flutter_map icon indicating copy to clipboard operation
flutter_map copied to clipboard

[SPEC] Overhaul event system

Open josxha opened this issue 2 years ago • 0 comments

Work in progress, feedback and additions are welcome, event names are not final

Motivation

  • Some event sources have their dedicated event class. Having both is redundant.
  • An overhaul of the event system simplifies integration in the gesture system.
  • https://github.com/fleaflet/flutter_map/pull/1733#discussion_r1428957493
  • https://github.com/fleaflet/flutter_map/issues/1732

Current state

  • Own event class for every event type
  • EventSource for the origin of the event
  • boolean hasGesture, false if gesture has been caused programmatically by the MapController

Needed additions

  • Possibility to distinguish between different kinds of rotate events (https://github.com/fleaflet/flutter_map/pull/1733)
  • A convenient method to group zoom/move/rotate events (https://github.com/fleaflet/flutter_map/issues/1732)
  • Less additional code to use it in the new gesture system
  • Option to merge MapController.move(), .zoom() and .rotate() into one function (https://github.com/fleaflet/flutter_map/pull/1733#discussion_r1429130169)

Class hierarchy

  • abstract MapEvent
    • MapEventTap, MapEventSecondaryTap, MapEventTertiaryTap, MapEventLongPress, MapEventSecondaryLongPress, MapEventTertiaryLongPress
    • MapEventMoveStart, MapEventMoveEnd
    • MapEventFlingAnimationNotStarted, MapEventFlingAnimationStart, MapEventFlingAnimationEnd
    • MapEventDoubleTapZoomStart, MapEventDoubleTapZoomEnd
    • MapEventDoubleTapDragZoomStart, MapEventDoubleTapDragZoomEnd
    • MapEventRotateStart, MapEventRotateEnd
    • abstract MapEventWithMove
      • MapEventMove
      • MapEventFlingAnimation
      • MapEventDoubleTapZoom
      • MapEventScrollWheelZoom
      • MapEventNonRotatedSizeChange

Usage in onMapEvent callback

build() {
  return FlutterMap(
    options: MapOptions(
      onMapEvent: (event) {
        switch (event) {
          case final MapEventDoubleTapZoom event:
            print('double tap zoom');
            break;
          case final MapEventFlingAnimationNotStarted event:
            print('fling animation not started');
            break;
        }
      },
    ),
  );
}

Proposals

Proposal 1: Minimal class approach

Class hierarchy

  • sealed MapEvent
    • MapCameraEvent(enum CameraEventType)
    • MapInteractionEvent(enum InteractionType)
    • MapStartEvent(enum CameraEventType)
    • MapEndEvent(enum CameraEventType)
    • MapEventFlingAnimationNotStarted()

Usage in onMapEvent callback

build() {
  return FlutterMap(
    options: MapOptions(
      onMapEvent: (event) {
        switch (event) {
          case MapCameraEvent():
            switch (event) {
              case CameraEventType.doubleTapZoom:
                print('double tap zoom');
                break;
            }
            break;
          case MapEventFlingAnimationNotStarted():
            print('fling animation not started');
            break;
        }
      },
    ),
  );
}
Proposal 2: Further embrace class subtyping

Class hierarchy

  • sealed MapEvent
    • sealed MapInteractionEvent
      • MapEventTap, MapEventSecondaryTap, MapEventTertiaryTap, MapEventLongPress, MapEventSecondaryLongPress, MapEventTertiaryLongPress
    • MapEventFlingAnimationNotStarted
    • sealed MapStartEvent
      • MapMoveEventStart, MapFlingAnimationEventStart, MapDoubleTapZoomEventStart, MapDoubleTapDragZoomEventStart, MapEventRotateStart
    • sealed MapEndEvent
      • MapMoveEventEnd, MapEventFlingAnimationEnd, MapDoubleTapZoomEventEnd, MapDoubleTapDragZoomEventEnd, MapRotateEventEnd
    • sealed MapCameraEvent
      • MapMoveEvent
      • MapFlingEvent
      • MapDoubleTapZoomEvent
      • MapScrollWheelZoomEvent
      • MapWidgetSizeChangedEvent

Usage in onMapEvent callback

build() {
  return FlutterMap(
    options: MapOptions(
      onMapEvent: (event) {
        switch (event) {
          case MapDoubleTapZoomEvent():
            print('fling animation not started');
            break;
          case MapEventFlingAnimationNotStarted():
            print('fling animation not started');
            break;
          default:
            break;
        }
      },
    ),
  );
}

TODO: add more proposals

Challenges

  • It could be that there is a feature conflict between https://github.com/fleaflet/flutter_map/pull/1733#discussion_r1429130169 and https://github.com/fleaflet/flutter_map/issues/1732

josxha avatar Dec 19 '23 10:12 josxha