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

[FEATURE] Provide a way to handle feature tap and drag events #151

Open
gabbopalma opened this issue Nov 25, 2024 · 1 comment · May be fixed by #162
Open

[FEATURE] Provide a way to handle feature tap and drag events #151

gabbopalma opened this issue Nov 25, 2024 · 1 comment · May be fixed by #162
Labels
feature New feature or request flutter_map parity A feature flutter_map has but maplibre does not maplibre_gl parity A feature maplibre_gl has but maplibre has not

Comments

@gabbopalma
Copy link
Contributor

gabbopalma commented Nov 25, 2024

Feature Description

Currently there is no good way to detect if an element has been dragged by the user, almost with Layer features.
I have not tried with the StyleLayer features, but previously on flutter-maplibre-gl with the draggable layer option set to true, dragging was possible.

Previously on flutter-maplibre-gl there was a way to handle drag events with: controller.onFeatureDrag. In my opinion, this was a complex way to handle them, but if this can be the only way we can reproduce, it will be fine.

Sample Use Case

  • Draggable geometries in the map, useful for editing them.

Existing Alternatives or Workarounds

Currently there is no way to handle drag events, but with the MapEventUserInput event you can see which QueriedLayer was tapped. Also, it would be nice if you could give this method a range nullable to query a feature in the range (in meters) of the pickup point.

Additional Context

maplibre-native

flutter-maplibre-gl

plugin-annotation

@gabbopalma gabbopalma added the feature New feature or request label Nov 25, 2024
@josxha josxha added flutter_map parity A feature flutter_map has but maplibre does not maplibre_gl parity A feature maplibre_gl has but maplibre has not labels Dec 2, 2024
@josxha
Copy link
Owner

josxha commented Dec 2, 2024

Thanks for this feature request @gabbopalma. This is indeed a missing feature.

The current design guidelines are:

  • keep things that are possible in a performant way in Dart for a better cross-plattform support (for example the user interface widgets)
  • Use native bindings for everything that needs requires the native SDKs (for example rendering)

There are two different options to handle the dragging:

Option 1: as much dart as possible

Keeping the dragging logic inside dart and listen to additional events like pointer-down, pointer-move and pointer-up. If this is possible and the end result looks alright, it could be the easiest solution. As far as I've seen this should be possible on web at least but I can't be 100% certain on Android yet.

Option 2: logic in kotlin and pass the results to dart

I think this option is somewhat more work. The feature dragging is handled by the Annotation plugin, isn't it? We don't use it
but rather have the LayerManager for a better integration into Flutter. Using this option, some basic logic would be needed in kotlin to handle the dragging for a faster response time.

Speaking of the public API, the user works with, the flutter-maplibre-gl way using a controller.onFeatureDrag callback makes a lot of sense. In our case, this would be an emitted MapEvent, e.g. MapEventFeatureDragged. However we could add an additional layer.onDragged() callback for convenience.
An important note: The LayerManager is stateless. This means that it can't change it's features itself. Instead if passes the updated values to the user and the user needs to update the values with setState().

I'd recommend to start like this:

Step 1

  • Add an pointer-down, pointer-move and pointer-up to pigeon to extend the method channel. JNI won't be useable as it lacks support to call dart from within kotlin.
  • Register callbacks for these kind of events in kotlin and send them via the pigeon method channel.
  • Create new MapEvent classes for the new event types
  • Emit the events for the new event types

Step 2

  • Create a new page for the example app for the dragging.
  • Add an nullable onDragged callback to the Layers that should be possible to drag.
  • Make the LayerManager listen to the new events.
  • Query the features of all Layers on-pointer-down if any Layer is targetted.
  • Find the specific feature that has been targetted and save this feature inside the LayerManager. This can be the indicator if a feature drag is happening at any time.
  • Call the onDragged callback, every time an on-pointer-move events happens. The user needs to update the location of the feature by using setState().
  • When a on-pointer-up is received, clear the saved feature form the LayerManager and the dragging is completed.

There are potential enhancements like move the map camera when the dragged marker is near an edge or only allow drag on long press. This could be part of Step 3. (:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature or request flutter_map parity A feature flutter_map has but maplibre does not maplibre_gl parity A feature maplibre_gl has but maplibre has not
Projects
Status: Todo
Development

Successfully merging a pull request may close this issue.

2 participants