Skip to content

Commit

Permalink
feat: implement gesturesSettings on MapView & remove default from pro…
Browse files Browse the repository at this point in the history
…jection
  • Loading branch information
mfazekas committed Oct 19, 2023
1 parent 8fc47c6 commit 33a7708
Show file tree
Hide file tree
Showing 12 changed files with 367 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import com.rnmapbox.rnmbx.utils.ConvertUtils
import com.rnmapbox.rnmbx.utils.ExpressionParser
import com.rnmapbox.rnmbx.utils.Logger
import com.rnmapbox.rnmbx.utils.ViewTagResolver
import com.rnmapbox.rnmbx.utils.extensions.getAndLogIfNotBoolean
import com.rnmapbox.rnmbx.utils.extensions.getAndLogIfNotDouble
import com.rnmapbox.rnmbx.utils.extensions.toCoordinate
import com.rnmapbox.rnmbx.utils.extensions.toRectF
import com.rnmapbox.rnmbx.utils.extensions.toScreenCoordinate
Expand Down Expand Up @@ -139,6 +141,55 @@ open class RNMBXMapViewManager(context: ReactApplicationContext, val viewTagReso
mapView.setReactLocalizeLabels(locale, layerIds)
}

@ReactProp(name = "gestureSettings")
override fun setGestureSettings(mapView: RNMBXMapView, settings: Dynamic) {
mapView.getMapboxMap().gesturesPlugin {
val map = settings.asMap()
this.updateSettings {
map.getAndLogIfNotBoolean("doubleTapToZoomInEnabled", LOG_TAG)?.let {
this.doubleTapToZoomInEnabled = it
}
map.getAndLogIfNotBoolean("doubleTouchToZoomOutEnabled", LOG_TAG)?.let {
this.doubleTouchToZoomOutEnabled = it
}
map.getAndLogIfNotBoolean("pinchPanEnabled", LOG_TAG)?.let {
this.pinchScrollEnabled = it
}
map.getAndLogIfNotBoolean("pinchZoomEnabled", LOG_TAG)?.let {
this.pinchToZoomEnabled = it
}
map.getAndLogIfNotBoolean("pinchZoomDecelerationEnabled", LOG_TAG)?.let {
this.pinchToZoomDecelerationEnabled = it
}
map.getAndLogIfNotBoolean("pitchEnabled", LOG_TAG)?.let {
this.pitchEnabled = it
}
map.getAndLogIfNotBoolean("quickZoomEnabled", LOG_TAG)?.let {
this.quickZoomEnabled = it
}
map.getAndLogIfNotBoolean("rotateEnabled", LOG_TAG)?.let {
this.rotateEnabled = it
}
map.getAndLogIfNotBoolean("rotateDecelerationEnabled", LOG_TAG)?.let {
this.rotateDecelerationEnabled = it
}
map.getAndLogIfNotBoolean("panEnabled", LOG_TAG)?.let {
this.scrollEnabled = it
}
map.getAndLogIfNotDouble("panDecelerationFactor", LOG_TAG)?.let {
this.scrollDecelerationEnabled = it > 0.0
}
map.getAndLogIfNotBoolean("simultaneousRotateAndPinchToZoomEnabled", LOG_TAG)?.let {
this.simultaneousRotateAndPinchToZoomEnabled = it
}
map.getAndLogIfNotDouble("zoomAnimationAmount", LOG_TAG)?.let {
this.zoomAnimationAmount = it.toFloat()
}
}
}

}

@ReactProp(name = "styleURL")
override fun setStyleURL(mapView: RNMBXMapView, styleURL:Dynamic) {
mapView.setReactStyleURL(styleURL.asString())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.rnmapbox.rnmbx.utils.extensions

import com.facebook.react.bridge.ReadableMap
import com.facebook.react.bridge.ReadableType
import com.rnmapbox.rnmbx.utils.Logger

fun ReadableMap.forEach(action: (String, Any) -> Unit) {
val iterator = this.entryIterator
Expand All @@ -17,3 +18,37 @@ fun ReadableMap.getIfDouble(key: String): Double? {
null
}
}

fun ReadableMap.getIfBoolean(key: String): Boolean? {
return if (hasKey(key) && (getType(key) == ReadableType.Boolean)) {
getBoolean(key)
} else {
null
}
}

fun ReadableMap.getAndLogIfNotBoolean(key: String, tag:String = "RNMBXReadableMap"): Boolean? {
return if (hasKey(key)) {
if (getType(key) == ReadableType.Boolean) {
getBoolean(key)
} else {
Logger.e("RNMBXReadableMap", "$key is expected to be a boolean but was: ${getType(key)}")
null
}
} else {
null
}
}

fun ReadableMap.getAndLogIfNotDouble(key: String, tag: String = "RNMBXReadableMap"): Double? {
return if (hasKey(key)) {
if (getType(key) == ReadableType.Number) {
getDouble(key)
} else {
Logger.e("RNMBXReadableMap", "$key is expected to be a double but was: ${getType(key)}")
null
}
} else {
null
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ public void setProperty(T view, String propName, @Nullable Object value) {
case "styleURL":
mViewManager.setStyleURL(view, new DynamicFromObject(value));
break;
case "gestureSettings":
mViewManager.setGestureSettings(view, new DynamicFromObject(value));
break;
case "scaleBarViewMargins":
mViewManager.setScaleBarViewMargins(view, new DynamicFromObject(value));
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public interface RNMBXMapViewManagerInterface<T extends View> {
void setProjection(T view, Dynamic value);
void setLocalizeLabels(T view, Dynamic value);
void setStyleURL(T view, Dynamic value);
void setGestureSettings(T view, Dynamic value);
void setScaleBarViewMargins(T view, Dynamic value);
void setAttributionViewMargins(T view, Dynamic value);
void setAttributionViewPosition(T view, Dynamic value);
Expand Down
30 changes: 29 additions & 1 deletion docs/MapView.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ The distance from the edges of the map view’s frame to the edges of the map vi
```
The projection used when rendering the map

_defaults to:_ `'mercator'`


### styleURL
Expand Down Expand Up @@ -275,6 +274,35 @@ Set map's label locale, e.g. { "locale": "es" } will localize labels to Spanish,
### gestureSettings
```tsx
type GestureSettings = {
doubleTapToZoomInEnabled: boolean; /* Whether double tapping the map with one touch results in a zoom-in animation. */
doubleTouchToZoomOutEnabled: boolean; /* Whether single tapping the map with two touches results in a zoom-out animation. */
pinchPanEnabled: boolean; /* Whether pan/scroll is enabled for the pinch gesture. */
pinchZoomEnabled: boolean; /* Whether zoom is enabled for the pinch gesture. */
pinchZoomDecelerationEnabled: boolean; /* Whether a deceleration animation following a pinch-zoom gesture is enabled. True by default.
(Android only) */
pitchEnabled: boolean; /* Whether the pitch gesture is enabled. */
quickZoomEnabled: boolean; /* Whether the quick zoom gesture is enabled. */
rotateEnabled: boolean; /* Whether the rotate gesture is enabled. */
rotateDecelerationEnabled: boolean; /* Whether a deceleration animation following a rotate gesture is enabled. True by default.
(Android only) */
panEnabled: boolean; /* Whether the single-touch pan/scroll gesture is enabled. */
panDecelerationFactor: number; /* A constant factor that determines how quickly pan deceleration animations happen. Multiplied with the velocity vector once per millisecond during deceleration animations.
On iOS Defaults to UIScrollView.DecelerationRate.normal.rawValue
On android set to 0 to disable deceleration, and non zero to enabled it. */
simultaneousRotateAndPinchZoomEnabled: boolean; /* Whether rotation is enabled for the pinch zoom gesture. */
zoomAnimationAmount: number; /* The amount by which the zoom level increases or decreases during a double-tap-to-zoom-in or double-touch-to-zoom-out gesture. 1.0 by default. Must be positive.
(Android only) */
}
```
Gesture configuration allows to control the user touch interaction.
### onPress
```tsx
Expand Down
104 changes: 103 additions & 1 deletion docs/docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -3543,7 +3543,7 @@
"name": "projection",
"required": false,
"type": "'mercator' \\| 'globe'",
"default": "'mercator'",
"default": "none",
"description": "The projection used when rendering the map"
},
{
Expand Down Expand Up @@ -3725,6 +3725,108 @@
"default": "none",
"description": "[`mapbox` (v10) implementation only]\nSet map's label locale, e.g. { \"locale\": \"es\" } will localize labels to Spanish, { \"locale\": \"current\" } will localize labels to system locale."
},
{
"name": "gestureSettings",
"required": false,
"type": {
"name": "shape",
"value": [
{
"name": "doubleTapToZoomInEnabled",
"required": false,
"type": "boolean",
"default": "none",
"description": "Whether double tapping the map with one touch results in a zoom-in animation."
},
{
"name": "doubleTouchToZoomOutEnabled",
"required": false,
"type": "boolean",
"default": "none",
"description": "Whether single tapping the map with two touches results in a zoom-out animation."
},
{
"name": "pinchPanEnabled",
"required": false,
"type": "boolean",
"default": "none",
"description": "Whether pan/scroll is enabled for the pinch gesture."
},
{
"name": "pinchZoomEnabled",
"required": false,
"type": "boolean",
"default": "none",
"description": "Whether zoom is enabled for the pinch gesture."
},
{
"name": "pinchZoomDecelerationEnabled",
"required": false,
"type": "boolean",
"default": "none",
"description": "Whether a deceleration animation following a pinch-zoom gesture is enabled. True by default.\n(Android only)"
},
{
"name": "pitchEnabled",
"required": false,
"type": "boolean",
"default": "none",
"description": "Whether the pitch gesture is enabled."
},
{
"name": "quickZoomEnabled",
"required": false,
"type": "boolean",
"default": "none",
"description": "Whether the quick zoom gesture is enabled."
},
{
"name": "rotateEnabled",
"required": false,
"type": "boolean",
"default": "none",
"description": "Whether the rotate gesture is enabled."
},
{
"name": "rotateDecelerationEnabled",
"required": false,
"type": "boolean",
"default": "none",
"description": "Whether a deceleration animation following a rotate gesture is enabled. True by default.\n(Android only)"
},
{
"name": "panEnabled",
"required": false,
"type": "boolean",
"default": "none",
"description": "Whether the single-touch pan/scroll gesture is enabled."
},
{
"name": "panDecelerationFactor",
"required": false,
"type": "number",
"default": "none",
"description": "A constant factor that determines how quickly pan deceleration animations happen. Multiplied with the velocity vector once per millisecond during deceleration animations.\n\nOn iOS Defaults to UIScrollView.DecelerationRate.normal.rawValue\nOn android set to 0 to disable deceleration, and non zero to enabled it."
},
{
"name": "simultaneousRotateAndPinchZoomEnabled",
"required": false,
"type": "boolean",
"default": "none",
"description": "Whether rotation is enabled for the pinch zoom gesture."
},
{
"name": "zoomAnimationAmount",
"required": false,
"type": "number",
"default": "none",
"description": "The amount by which the zoom level increases or decreases during a double-tap-to-zoom-in or double-touch-to-zoom-out gesture. 1.0 by default. Must be positive.\n(Android only)"
}
]
},
"default": "none",
"description": "Gesture configuration allows to control the user touch interaction."
},
{
"name": "onPress",
"required": false,
Expand Down
2 changes: 1 addition & 1 deletion example/ios/Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ prepare_react_native_project!
$RNMapboxMapsImpl = 'mapbox'
if ENV['RNMBX11']
$RNMapboxMapsUseV11 = true # use 11 version
$RNMapboxMapsVersion = '= 11.0.0-beta.4'
$RNMapboxMapsVersion = '= 11.0.0-beta.5'
end


Expand Down
11 changes: 11 additions & 0 deletions ios/RNMBX/CustomHttpHeaders.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
import MapboxMaps

class CustomHttpHeaders : HttpServiceInterceptorInterface {
#if RNMBX_11
func onRequest(for request: HttpRequest, continuation: @escaping HttpServiceInterceptorRequestContinuation) {

Check failure on line 5 in ios/RNMBX/CustomHttpHeaders.swift

View workflow job for this annotation

GitHub Actions / iOS/Mapbox11 / build

cannot find type 'HttpServiceInterceptorRequestContinuation' in scope
let request = onRequest(for: request)
continuation(HttpRequestOrResponse.fromHttpRequest(request))
}

func onResponse(for response: HttpResponse, continuation: @escaping HttpServiceInterceptorResponseContinuation) {

Check failure on line 10 in ios/RNMBX/CustomHttpHeaders.swift

View workflow job for this annotation

GitHub Actions / iOS/Mapbox11 / build

cannot find type 'HttpServiceInterceptorResponseContinuation' in scope
continuation(response)
}
#endif

static var shared : CustomHttpHeaders = {
let headers = CustomHttpHeaders()
headers.install()
Expand Down
57 changes: 56 additions & 1 deletion ios/RNMBX/RNMBXMapView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,9 @@ open class RNMBXMapView : MapView {
@objc public func setReactProjection(_ value: String?) {
if let value = value {
let projection = StyleProjection(name: value == "globe" ? .globe : .mercator)
try! self.mapboxMap.style.setProjection(projection)
logged("RNMBXMapView.setReactProjection") {
try self.mapboxMap.style.setProjection(projection)
}
}
}

Expand All @@ -272,6 +274,59 @@ open class RNMBXMapView : MapView {
}
}

@objc public func setReactGestureSettings(_ value: NSDictionary?) {
if let value = value, let gestures = self.mapView.gestures {
var options = gestures.options
if let doubleTapToZoomInEnabled = value["doubleTapToZoomInEnabled"] as? NSNumber {
options.doubleTapToZoomInEnabled = doubleTapToZoomInEnabled.boolValue
}
if let doubleTouchToZoomOutEnabled = value["doubleTouchToZoomOutEnabled"] as? NSNumber {
options.doubleTouchToZoomOutEnabled = doubleTouchToZoomOutEnabled.boolValue
}
if let pinchScrollEnabled = value["pinchPanEnabled"] as? NSNumber {
options.pinchPanEnabled = pinchScrollEnabled.boolValue
}
if let pinchZoomEnabled = value["pinchZoomEnabled"] as? NSNumber {
options.pinchZoomEnabled = pinchZoomEnabled.boolValue
}
/* android only
if let pinchZoomDecelerationEnabled = value["pinchZoomDecelerationEnabled"] as? NSNumber {
options.pinchZoomDecelerationEnabled = pinchZoomDecelerationEnabled.boolValue
}
*/
if let pitchEnabled = value["pitchEnabled"] as? NSNumber {
options.pitchEnabled = pitchEnabled.boolValue
}
if let quickZoomEnabled = value["quickZoomEnabled"] as? NSNumber {
options.quickZoomEnabled = quickZoomEnabled.boolValue
}
if let rotateEnabled = value["rotateEnabled"] as? NSNumber {
options.rotateEnabled = rotateEnabled.boolValue
}
/* android only
if let rotateDecelerationEnabled = value["rotateDecelerationEnabled"] as? NSNumber {
options.rotateDecelerationEnabled = rotateDecelerationEnabled.boolValue
}*/
if let panEnabled = value["panEnabled"] as? NSNumber {
options.panEnabled = panEnabled.boolValue
}
if let panDecelerationFactor = value["panDecelerationFactor"] as? NSNumber {
options.panDecelerationFactor = panDecelerationFactor.CGFloat
}
#if RNMBX_11
if let simultaneousRotateAndPinchZoomEnabled = value["simultaneousRotateAndPinchZoomEnabled"] as? NSNumber {
options.simultaneousRotateAndPinchZoomEnabled = simultaneousRotateAndPinchZoomEnabled.boolValue
}
#endif
/* android only
if let zoomAnimationAmount = value["zoomAnimationAmount"] as? NSNumber {
options.zoomAnimationAmount = zoomAnimationAmount.CGFloat
}*/
if options != gestures.options {
gestures.options = options
}
}
}

@objc public func setReactAttributionEnabled(_ value: Bool) {
mapView.ornaments.options.attributionButton.visibility = value ? .visible : .hidden
Expand Down
2 changes: 2 additions & 0 deletions ios/RNMBX/RNMBXMapViewManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ @interface RCT_EXTERN_REMAP_MODULE(RNMBXMapView, RNMBXMapViewManager, RCTViewMan
RCT_REMAP_VIEW_PROPERTY(projection, reactProjection, NSString)
RCT_REMAP_VIEW_PROPERTY(localizeLabels, reactLocalizeLabels, NSDictionary)

RCT_REMAP_VIEW_PROPERTY(gestureSettings, reactGestureSettings, NSDictionary)

RCT_REMAP_VIEW_PROPERTY(styleURL, reactStyleURL, NSString)
RCT_REMAP_VIEW_PROPERTY(onPress, reactOnPress, RCTBubblingEventBlock)
RCT_REMAP_VIEW_PROPERTY(onLongPress, reactOnLongPress, RCTBubblingEventBlock)
Expand Down
Loading

0 comments on commit 33a7708

Please sign in to comment.