Skip to content

Commit

Permalink
Drag event types support added (#987)
Browse files Browse the repository at this point in the history
* Android implementation

* ios & web implementation

* _onFeatureDrag example

* swift format

* ios & android code formatting

* prints removed

* typo fixed

Co-authored-by: Tolga Guler <[email protected]>
  • Loading branch information
GULERTOLGA and Tolga Guler authored Apr 26, 2022
1 parent b1f2392 commit 62650dd
Show file tree
Hide file tree
Showing 8 changed files with 156 additions and 80 deletions.
106 changes: 55 additions & 51 deletions android/src/main/java/com/mapbox/mapboxgl/MapboxMapController.java
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ final class MapboxMapController
private final int id;
private final MethodChannel methodChannel;
private final MapboxMapsPlugin.LifecycleProvider lifecycleProvider;
private final float density;
private final Context context;
private final String styleStringInitial;
private MapView mapView;
private MapboxMap mapboxMap;
private boolean trackCameraPosition = false;
Expand All @@ -113,10 +116,7 @@ final class MapboxMapController
private int myLocationRenderMode = 0;
private boolean disposed = false;
private boolean dragEnabled = true;
private final float density;
private MethodChannel.Result mapReadyResult;
private final Context context;
private final String styleStringInitial;
private LocationComponent locationComponent = null;
private LocationEngine locationEngine = null;
private LocationEngineCallback<LocationEngineResult> locationEngineCallback = null;
Expand All @@ -132,6 +132,25 @@ final class MapboxMapController
private Map<String, FeatureCollection> addedFeaturesByLayer;

private LatLngBounds bounds = null;
Style.OnStyleLoaded onStyleLoadedCallback =
new Style.OnStyleLoaded() {
@Override
public void onStyleLoaded(@NonNull Style style) {
MapboxMapController.this.style = style;

updateMyLocationEnabled();

if (null != bounds) {
mapboxMap.setLatLngBoundsForCameraTarget(bounds);
}

mapboxMap.addOnMapClickListener(MapboxMapController.this);
mapboxMap.addOnMapLongClickListener(MapboxMapController.this);
localizationPlugin = new LocalizationPlugin(mapView, mapboxMap, style);

methodChannel.invokeMethod("map#onStyleLoaded", null);
}
};

MapboxMapController(
int id,
Expand Down Expand Up @@ -245,26 +264,6 @@ public void setStyleString(String styleString) {
}
}

Style.OnStyleLoaded onStyleLoadedCallback =
new Style.OnStyleLoaded() {
@Override
public void onStyleLoaded(@NonNull Style style) {
MapboxMapController.this.style = style;

updateMyLocationEnabled();

if (null != bounds) {
mapboxMap.setLatLngBoundsForCameraTarget(bounds);
}

mapboxMap.addOnMapClickListener(MapboxMapController.this);
mapboxMap.addOnMapLongClickListener(MapboxMapController.this);
localizationPlugin = new LocalizationPlugin(mapView, mapboxMap, style);

methodChannel.invokeMethod("map#onStyleLoaded", null);
}
};

@SuppressWarnings({"MissingPermission"})
private void enableLocationComponent(@NonNull Style style) {
if (hasLocationPermission()) {
Expand Down Expand Up @@ -1657,15 +1656,6 @@ private Bitmap getScaledImage(String imageId, float density) {
return bitmap;
}

/** Simple Listener to listen for the status of camera movements. */
public class OnCameraMoveFinishedListener implements MapboxMap.CancelableCallback {
@Override
public void onFinish() {}

@Override
public void onCancel() {}
}

boolean onMoveBegin(MoveGestureDetector detector) {
// onMoveBegin gets called even during a move - move end is also not called unless this function
// returns
Expand All @@ -1678,42 +1668,47 @@ boolean onMoveBegin(MoveGestureDetector detector) {
RectF rectF = new RectF(pointf.x - 10, pointf.y - 10, pointf.x + 10, pointf.y + 10);
Feature feature = firstFeatureOnLayers(rectF);
if (feature != null && startDragging(feature, origin)) {
invokeFeatureDrag(pointf, "start");
return true;
}
}
return false;
}

private void invokeFeatureDrag(PointF pointf, String eventType) {
LatLng current = mapboxMap.getProjection().fromScreenLocation(pointf);

final Map<String, Object> arguments = new HashMap<>(9);
arguments.put("id", draggedFeature.id());
arguments.put("x", pointf.x);
arguments.put("y", pointf.y);
arguments.put("originLng", dragOrigin.getLongitude());
arguments.put("originLat", dragOrigin.getLatitude());
arguments.put("currentLng", current.getLongitude());
arguments.put("currentLat", current.getLatitude());
arguments.put("eventType", eventType);
arguments.put("deltaLng", current.getLongitude() - dragPrevious.getLongitude());
arguments.put("deltaLat", current.getLatitude() - dragPrevious.getLatitude());
dragPrevious = current;
methodChannel.invokeMethod("feature#onDrag", arguments);
}

boolean onMove(MoveGestureDetector detector) {
if (draggedFeature != null) {
if (detector.getPointersCount() > 1) {
stopDragging();
return true;
}

PointF pointf = detector.getFocalPoint();
LatLng current = mapboxMap.getProjection().fromScreenLocation(pointf);

final Map<String, Object> arguments = new HashMap<>(9);
arguments.put("id", draggedFeature.id());
arguments.put("x", pointf.x);
arguments.put("y", pointf.y);

arguments.put("originLng", dragOrigin.getLongitude());
arguments.put("originLat", dragOrigin.getLatitude());
arguments.put("currentLng", current.getLongitude());
arguments.put("currentLat", current.getLatitude());
arguments.put("deltaLng", current.getLongitude() - dragPrevious.getLongitude());
arguments.put("deltaLat", current.getLatitude() - dragPrevious.getLatitude());

methodChannel.invokeMethod("feature#onDrag", arguments);
dragPrevious = current;
invokeFeatureDrag(pointf, "drag");
return false;
}
return true;
}

void onMoveEnd() {
void onMoveEnd(MoveGestureDetector detector) {
PointF pointf = detector.getFocalPoint();
invokeFeatureDrag(pointf, "end");
stopDragging();
}

Expand All @@ -1737,6 +1732,15 @@ void stopDragging() {
dragPrevious = null;
}

/** Simple Listener to listen for the status of camera movements. */
public class OnCameraMoveFinishedListener implements MapboxMap.CancelableCallback {
@Override
public void onFinish() {}

@Override
public void onCancel() {}
}

private class MoveGestureListener implements MoveGestureDetector.OnMoveGestureListener {

@Override
Expand All @@ -1751,7 +1755,7 @@ public boolean onMove(MoveGestureDetector detector, float distanceX, float dista

@Override
public void onMoveEnd(MoveGestureDetector detector, float velocityX, float velocityY) {
MapboxMapController.this.onMoveEnd();
MapboxMapController.this.onMoveEnd(detector);
}
}
}
21 changes: 21 additions & 0 deletions example/lib/place_fill.dart
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,27 @@ class PlaceFillBodyState extends State<PlaceFillBody> {
void _onMapCreated(MapboxMapController controller) {
this.controller = controller;
controller.onFillTapped.add(_onFillTapped);
this.controller!.onFeatureDrag.add(_onFeatureDrag);
}

void _onFeatureDrag(id,
{required current,
required delta,
required origin,
required point,
required eventType}) {
DragEventType type = eventType;
switch (type) {
case DragEventType.start:
// TODO: Handle this case.
break;
case DragEventType.drag:
// TODO: Handle this case.
break;
case DragEventType.end:
// TODO: Handle this case.
break;
}
}

void _onStyleLoaded() {
Expand Down
67 changes: 41 additions & 26 deletions ios/Classes/MapboxMapController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -869,53 +869,68 @@ class MapboxMapController: NSObject, FlutterPlatformView, MGLMapViewDelegate, Ma
}
}

/*
* UITapGestureRecognizer
* On pan might invoke the feature#onDrag callback.
*/
fileprivate func invokeFeatureDrag(
_ point: CGPoint,
_ coordinate: CLLocationCoordinate2D,
_ eventType: String
) {
if let feature = dragFeature,
let id = feature.identifier,
let previous = previousDragCoordinate,
let origin = originDragCoordinate
{
channel?.invokeMethod("feature#onDrag", arguments: [
"id": id,
"x": point.x,
"y": point.y,
"originLng": origin.longitude,
"originLat": origin.latitude,
"currentLng": coordinate.longitude,
"currentLat": coordinate.latitude,
"eventType": eventType,
"deltaLng": coordinate.longitude - previous.longitude,
"deltaLat": coordinate.latitude - previous.latitude,
])
}
}

@IBAction func handleMapPan(sender: UIPanGestureRecognizer) {
let began = sender.state == UIGestureRecognizer.State.began
let end = sender.state == UIGestureRecognizer.State.ended
let point = sender.location(in: mapView)
let coordinate = mapView.convert(point, toCoordinateFrom: mapView)

if sender.state == UIGestureRecognizer.State.began,
sender.numberOfTouches == 1,
if dragFeature == nil, began, sender.numberOfTouches == 1,
let feature = firstFeatureOnLayers(at: point),
let draggable = feature.attribute(forKey: "draggable") as? Bool,
draggable
{
sender.state = UIGestureRecognizer.State.began
dragFeature = feature
originDragCoordinate = coordinate
previousDragCoordinate = coordinate
mapView.allowsScrolling = false
let eventType = "start"
invokeFeatureDrag(point, coordinate, eventType)
for gestureRecognizer in mapView.gestureRecognizers! {
if let _ = gestureRecognizer as? UIPanGestureRecognizer {
gestureRecognizer.addTarget(self, action: #selector(handleMapPan))
break
}
}
} else if sender.state == UIGestureRecognizer.State.ended || sender.numberOfTouches != 1 {
sender.state = UIGestureRecognizer.State.ended
mapView.allowsScrolling = scrollingEnabled
}
if end, dragFeature != nil {
mapView.allowsScrolling = true
let eventType = "end"
invokeFeatureDrag(point, coordinate, eventType)
dragFeature = nil
originDragCoordinate = nil
previousDragCoordinate = nil
} else if let feature = dragFeature,
let id = feature.identifier,
let previous = previousDragCoordinate,
let origin = originDragCoordinate
{
print("in drag")
channel?.invokeMethod("feature#onDrag", arguments: [
"id": id,
"x": point.x,
"y": point.y,
"originLng": origin.longitude,
"originLat": origin.latitude,
"currentLng": coordinate.longitude,
"currentLat": coordinate.latitude,
"deltaLng": coordinate.longitude - previous.longitude,
"deltaLat": coordinate.latitude - previous.latitude,
])
}

if !began, !end, dragFeature != nil {
let eventType = "drag"
invokeFeatureDrag(point, coordinate, eventType)
previousDragCoordinate = coordinate
}
}
Expand Down
3 changes: 2 additions & 1 deletion lib/src/annotation_manager.dart
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,8 @@ abstract class AnnotationManager<T extends Annotation> {
{required Point<double> point,
required LatLng origin,
required LatLng current,
required LatLng delta}) {
required LatLng delta,
required DragEventType eventType}) {
final annotation = byId(id);
if (annotation != null) {
annotation.translate(delta);
Expand Down
8 changes: 6 additions & 2 deletions lib/src/controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ typedef void OnFeatureDragnCallback(dynamic id,
{required Point<double> point,
required LatLng origin,
required LatLng current,
required LatLng delta});
required LatLng delta,
required DragEventType eventType});

typedef void OnMapLongClickCallback(Point<double> point, LatLng coordinates);

Expand Down Expand Up @@ -72,11 +73,14 @@ class MapboxMapController extends ChangeNotifier {

_mapboxGlPlatform.onFeatureDraggedPlatform.add((payload) {
for (final fun in List<OnFeatureDragnCallback>.from(onFeatureDrag)) {
final DragEventType enmDragEventType = DragEventType.values
.firstWhere((element) => element.name == payload["eventType"]);
fun(payload["id"],
point: payload["point"],
origin: payload["origin"],
current: payload["current"],
delta: payload["delta"]);
delta: payload["delta"],
eventType: enmDragEventType);
}
});

Expand Down
2 changes: 2 additions & 0 deletions lib/src/global.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ Future<void> installOfflineMapTiles(String tilesDb) async {
);
}

enum DragEventType { start, drag, end }

Future<dynamic> setOffline(
bool offline, {
String? accessToken,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,15 @@ class MethodChannelMapboxGl extends MapboxGlPlatform {

final double deltaLat = call.arguments['deltaLat'];
final double deltaLng = call.arguments['deltaLng'];
final String eventType = call.arguments['eventType'];

onFeatureDraggedPlatform({
'id': id,
'point': Point<double>(x, y),
'origin': LatLng(originLat, originLng),
'current': LatLng(currentLat, currentLng),
'delta': LatLng(deltaLat, deltaLng),
'eventType': eventType,
});
break;

Expand Down
Loading

0 comments on commit 62650dd

Please sign in to comment.