From 1b6d31d772b02cde1cb9cebefab71bfafe74fea7 Mon Sep 17 00:00:00 2001 From: Peng Liu Date: Thu, 10 Feb 2022 17:35:33 +0200 Subject: [PATCH] [viewport] Refinements to public API documentation. (#1142) * [viewport] Refinements to public API documentation. * Address review comments. --- .../maps/plugin/viewport/ViewportExt.kt | 5 ++ .../transition/ImmediateViewportTransition.kt | 5 +- .../plugin/viewport/CompletionListener.kt | 5 +- .../maps/plugin/viewport/ViewportPlugin.kt | 81 +++++++++++++------ .../maps/plugin/viewport/ViewportStatus.kt | 5 +- .../plugin/viewport/ViewportStatusObserver.kt | 3 + .../data/DefaultViewportTransitionOptions.kt | 9 +-- .../data/FollowPuckViewportStateBearing.kt | 11 ++- .../data/FollowPuckViewportStateOptions.kt | 55 ++++++++++--- .../data/OverviewViewportStateOptions.kt | 41 +++++++--- .../plugin/viewport/data/ViewportOptions.kt | 15 ++-- .../viewport/state/FollowPuckViewportState.kt | 8 +- .../viewport/state/OverviewViewportState.kt | 10 ++- .../plugin/viewport/state/ViewportState.kt | 52 ++++++++++-- .../state/ViewportStateDataObserver.kt | 6 +- .../transition/DefaultViewportTransition.kt | 11 ++- .../viewport/transition/ViewportTransition.kt | 27 +++++-- 17 files changed, 263 insertions(+), 86 deletions(-) diff --git a/plugin-viewport/src/main/kotlin/com/mapbox/maps/plugin/viewport/ViewportExt.kt b/plugin-viewport/src/main/kotlin/com/mapbox/maps/plugin/viewport/ViewportExt.kt index e1fdfe7bac..e0a26f1e73 100644 --- a/plugin-viewport/src/main/kotlin/com/mapbox/maps/plugin/viewport/ViewportExt.kt +++ b/plugin-viewport/src/main/kotlin/com/mapbox/maps/plugin/viewport/ViewportExt.kt @@ -8,6 +8,11 @@ import com.mapbox.maps.plugin.delegates.MapPluginProviderDelegate /** * Extension val for MapView to get the [ViewportPlugin] instance. + * + * [ViewportPlugin] is a high-level and extensible API for driving the map camera. It + * provides built-in states for following the location puck and showing an overview of + * a GeoJSON geometry. Transitions between states can be animated with a built-in + * default transition and via custom transitions. */ @MapboxExperimental val MapPluginProviderDelegate.viewport: ViewportPlugin diff --git a/plugin-viewport/src/main/kotlin/com/mapbox/maps/plugin/viewport/transition/ImmediateViewportTransition.kt b/plugin-viewport/src/main/kotlin/com/mapbox/maps/plugin/viewport/transition/ImmediateViewportTransition.kt index ee88bf64cb..3ad4fc8f98 100644 --- a/plugin-viewport/src/main/kotlin/com/mapbox/maps/plugin/viewport/transition/ImmediateViewportTransition.kt +++ b/plugin-viewport/src/main/kotlin/com/mapbox/maps/plugin/viewport/transition/ImmediateViewportTransition.kt @@ -6,11 +6,14 @@ import com.mapbox.maps.plugin.animation.MapAnimationOptions.Companion.mapAnimati import com.mapbox.maps.plugin.animation.camera import com.mapbox.maps.plugin.delegates.MapDelegateProvider import com.mapbox.maps.plugin.viewport.CompletionListener +import com.mapbox.maps.plugin.viewport.ViewportPlugin import com.mapbox.maps.plugin.viewport.ViewportPluginImpl.Companion.VIEWPORT_CAMERA_OWNER import com.mapbox.maps.plugin.viewport.state.ViewportState /** - * [ViewportTransition] that transition to target [ViewportState] immediately. + * The [ViewportTransition] that transition to target [ViewportState] immediately without any animation. + * + * Use [ViewportPlugin.makeImmediateViewportTransition] to create instances of ImmediateViewportTransition. */ internal class ImmediateViewportTransition(delegateProvider: MapDelegateProvider) : ViewportTransition { diff --git a/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/CompletionListener.kt b/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/CompletionListener.kt index d5ea7c8e40..e80bf101d3 100644 --- a/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/CompletionListener.kt +++ b/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/CompletionListener.kt @@ -10,8 +10,11 @@ fun interface CompletionListener { /** * Notifies the action is completed. * + * Transition may end early if they fail or are interrupted(e.g. by another call to [ViewportPlugin.transitionTo] + * or [ViewportPlugin.idle]). + * * @param isFinished true if the transition ran to completion and false - * if it was canceled. + * if it was canceled or interrupted. */ fun onComplete(isFinished: Boolean) } \ No newline at end of file diff --git a/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/ViewportPlugin.kt b/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/ViewportPlugin.kt index 86f75b0362..dfca2e9bfc 100644 --- a/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/ViewportPlugin.kt +++ b/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/ViewportPlugin.kt @@ -13,14 +13,13 @@ import com.mapbox.maps.plugin.viewport.transition.DefaultViewportTransition import com.mapbox.maps.plugin.viewport.transition.ViewportTransition /** - * The Viewport plugin allows to track objects on a map. + * The [ViewportPlugin] provides a structured approach to organizing camera management logic into states + * and transitions between them. * - * It provides a structured approach to organizing camera management logic into states and transitions between them. - * - * at any given time, the viewport is either: + * At any given time, the viewport is either: * - idle (not updating the camera) - * - in a state (camera is being managed by a ViewportState) - * - transitioning (camera is being managed by a ViewportTransition) + * - in a state (camera is being managed by a [ViewportState]) + * - transitioning (camera is being managed by a [ViewportTransition]) */ @MapboxExperimental interface ViewportPlugin : MapPlugin { @@ -28,54 +27,85 @@ interface ViewportPlugin : MapPlugin { /** * Returns current [ViewportStatus]. * + * [ViewportStatus] can not be set directly, use [ViewportPlugin.transitionTo] and [ViewportPlugin.idle] + * to transition to a state or to idle. + * + * Defaults to [ViewportStatus.Idle] + * * @see addStatusObserver + * @see removeStatusObserver */ val status: ViewportStatus /** * Executes a transition to requested state. * - * When started, goes to [ViewportTransition] - * and to the final [ViewportState] when ended. + * When called, the [status] goes to [ViewportTransition] and to the final [ViewportState] when ended. + * + * Transitioning to state 'x' when the current [status] is 'ViewportStatus.State(x)' invokes [completionListener] + * synchronously with true and does not modify [ViewportPlugin.status]. * - * If transition is canceled, state goes to IDLE. + * Transitioning to state 'x' when the current [status] is 'ViewportStatus.Transition(_, x)' invokes + * [completionListener] synchronously with false and does not modify [ViewportPlugin.status]. + * + * If transition is failed or canceled, [status] goes to [ViewportStatus.Idle]. * * @param targetState The target [ViewportState] to transition to. - * @param transition The [ViewportTransition] that's used to transition to target state, if not specified, the [ViewportPlugin.defaultTransition] will be used. - * @param completionListener The listener to observe the completion state. + * @param transition The [ViewportTransition] that's used to transition to target state, if not specified, the [ViewportPlugin.defaultTransition] will be used. Defaults to null. + * @param completionListener The listener that's invoked when the transition ends, defaults to null. */ fun transitionTo(targetState: ViewportState, transition: ViewportTransition? = null, completionListener: CompletionListener? = null) /** - * Immediately goes to IDLE state canceling all ongoing transitions. + * Sets [ViewportPlugin.status] to [ViewportStatus.Idle] synchronously. + * + * This cancels any active [ViewportState] or [ViewportTransition]. */ fun idle() /** - * Options that impact the [ViewportPlugin]. + * Configuration options that impact the [ViewportPlugin]. */ var options: ViewportOptions // Transitions /** - * DefaultViewportTransition with default options. + * [ViewportPlugin.transitionTo] uses this transition unless some non-null value is passed to its + * transition argument. * - * This transition is used unless overridden by one of the registered transitions. + * Defaults to [DefaultViewportTransition] with default options. */ var defaultTransition: ViewportTransition // Observers /** - * Adds [ViewportStatusObserver] to observe the status change. + * Subscribes [ViewportStatusObserver] to observe the [ViewportStatus] change. + * + * [ViewportPlugin] keeps a strong reference to registered observers. Adding the same observer again + * while it is already subscribed has no effect. + * + * Note: Observers are notified of status changes asynchronously on the main queue. This means that + * by the time the notification is delivered, the status may have already changed again. This behaviour + * is necessary to allow observers to trigger further transitions while avoiding out-of-order delivery + * of status changed notifications. + * + * @param viewportStatusObserver the observer that will be notified when the [ViewportPlugin.status] changes. + * @see removeStatusObserver */ fun addStatusObserver( viewportStatusObserver: ViewportStatusObserver ) /** - * Removes [ViewportStatusObserver]. + * Unsubscribes [ViewportStatusObserver] from [ViewportPlugin.status] changes. + * + * This causes [ViewportPlugin] to release its strong reference to the observer. Removing an observer + * that is not subscribed has no effect. + * + * @param viewportStatusObserver the observer that should no longer be notified when the [ViewportPlugin.status] changes. + * @see addStatusObserver */ fun removeStatusObserver( viewportStatusObserver: ViewportStatusObserver @@ -84,32 +114,37 @@ interface ViewportPlugin : MapPlugin { // Convenient methods to create the in-stock [ViewportState] and [ViewportTransition]. /** - * Create a [FollowPuckViewportState] instance with provided [FollowPuckViewportStateOptions]. + * Create a new [FollowPuckViewportState] instance with provided [FollowPuckViewportStateOptions]. * - * @param options The desired [FollowPuckViewportStateOptions] + * @param options The desired [FollowPuckViewportStateOptions], defaults to [FollowPuckViewportStateOptions] that's initialised with default parameters. + * @return The newly-created [FollowPuckViewportState] instance. */ fun makeFollowPuckViewportState( options: FollowPuckViewportStateOptions = FollowPuckViewportStateOptions.Builder().build() ): FollowPuckViewportState /** - * Create an [OverviewViewportState] instance with provided [OverviewViewportStateOptions]. + * Create a new [OverviewViewportState] instance with provided [OverviewViewportStateOptions]. * * @param options The desired [OverviewViewportStateOptions] + * @return The newly-created [OverviewViewportState] instance. */ fun makeOverviewViewportState(options: OverviewViewportStateOptions): OverviewViewportState /** - * Create a default [ViewportTransition] instance with provided [DefaultViewportTransitionOptions]. + * Create a new [DefaultViewportTransition] instance with provided [DefaultViewportTransitionOptions]. * - * @param options The desired [DefaultViewportTransitionOptions] + * @param options The desired [DefaultViewportTransitionOptions], defaults to [DefaultViewportTransitionOptions] that's initialised with default parameters. + * @return The newly-created [DefaultViewportTransition] instance. */ fun makeDefaultViewportTransition( options: DefaultViewportTransitionOptions = DefaultViewportTransitionOptions.Builder().build() ): DefaultViewportTransition /** - * Create a [ViewportTransition] instance that transition to the target [ViewportState] immediately. + * Create a new [ViewportTransition] instance that transition to the target [ViewportState] immediately. + * + * @return The newly-created ImmediateViewportTransition instance. */ fun makeImmediateViewportTransition(): ViewportTransition } \ No newline at end of file diff --git a/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/ViewportStatus.kt b/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/ViewportStatus.kt index 7d0980dcbd..9d930610b3 100644 --- a/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/ViewportStatus.kt +++ b/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/ViewportStatus.kt @@ -8,7 +8,10 @@ import java.util.* /** * Represents the status of the viewport. * - * It could be either a [ViewportState] or [ViewportTransition]. + * It could be either a [ViewportStatus.State], [ViewportStatus.Transition] or [ViewportStatus.Idle]. + * + * The [ViewportStatus.State] amd [ViewportStatus.Transition] have associated values that are reference + * types, so equality and hash are implemented in terms of the identities of those objects. */ @MapboxExperimental sealed class ViewportStatus { diff --git a/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/ViewportStatusObserver.kt b/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/ViewportStatusObserver.kt index b96b0867dd..1023803e73 100644 --- a/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/ViewportStatusObserver.kt +++ b/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/ViewportStatusObserver.kt @@ -5,6 +5,9 @@ import com.mapbox.maps.plugin.viewport.data.ViewportStatusChangeReason /** * Observer that gets notified whenever [ViewportStatus] changes. + * + * @see [ViewportPlugin.addStatusObserver] + * @see [ViewportPlugin.removeStatusObserver] */ @MapboxExperimental fun interface ViewportStatusObserver { diff --git a/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/data/DefaultViewportTransitionOptions.kt b/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/data/DefaultViewportTransitionOptions.kt index 0da0b89b20..44a29ccac1 100644 --- a/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/data/DefaultViewportTransitionOptions.kt +++ b/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/data/DefaultViewportTransitionOptions.kt @@ -2,15 +2,15 @@ package com.mapbox.maps.plugin.viewport.data import com.mapbox.maps.MapboxExperimental import com.mapbox.maps.plugin.viewport.DEFAULT_TRANSITION_MAX_DURATION_MS +import com.mapbox.maps.plugin.viewport.transition.DefaultViewportTransition /** - * Options that impact the [DefaultViewportTransition]. + * Configuration options that impact the [DefaultViewportTransition]. */ @MapboxExperimental class DefaultViewportTransitionOptions private constructor( /** - * The maximum duration of the transitions in milliseconds, - * including delays between animators and their respective durations. + * The maximum duration of the transitions in milliseconds. * * Defaults to [DEFAULT_TRANSITION_MAX_DURATION_MS] milliseconds. */ @@ -45,8 +45,7 @@ class DefaultViewportTransitionOptions private constructor( private var maxDurationMs: Long = DEFAULT_TRANSITION_MAX_DURATION_MS /** - * Sets maximum duration of the generated transitions set in milliseconds, - * including delays between animators and their respective durations. + * Sets maximum duration of the generated transitions set in milliseconds. * * Defaults to [DEFAULT_TRANSITION_MAX_DURATION_MS] milliseconds. */ diff --git a/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/data/FollowPuckViewportStateBearing.kt b/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/data/FollowPuckViewportStateBearing.kt index d4faaec95c..be4304a265 100644 --- a/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/data/FollowPuckViewportStateBearing.kt +++ b/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/data/FollowPuckViewportStateBearing.kt @@ -1,15 +1,18 @@ package com.mapbox.maps.plugin.viewport.data +import com.mapbox.maps.CameraOptions import com.mapbox.maps.MapboxExperimental +import com.mapbox.maps.plugin.viewport.state.FollowPuckViewportState import java.util.Objects /** - * Describes the camera bearing options for the [FollowPuckViewportState]. + * Describes different ways that [FollowPuckViewportState] can obtain values to use when setting + * [CameraOptions.bearing]. */ @MapboxExperimental sealed class FollowPuckViewportStateBearing { /** - * The viewport's bearing is fixed to the given bearing. + * The [FollowPuckViewportState] sets the camera bearing to the constant value on every frame. * * @param bearing The bearing that the [FollowPuckViewportState] uses to generate camera updates. */ @@ -31,10 +34,10 @@ sealed class FollowPuckViewportStateBearing { } /** - * The viewport's bearing is set as the same as the location puck's bearing. + * The [FollowPuckViewportState] sets the camera bearing to the same as the location puck's bearing. * * When set to this mode, the viewport's bearing is driven by the location, thus guarantees - * synchronization. + * the synchronization of the location puck and camera position. */ object SyncWithLocationPuck : FollowPuckViewportStateBearing() { /** diff --git a/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/data/FollowPuckViewportStateOptions.kt b/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/data/FollowPuckViewportStateOptions.kt index 091f21d030..4727c17c36 100644 --- a/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/data/FollowPuckViewportStateOptions.kt +++ b/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/data/FollowPuckViewportStateOptions.kt @@ -1,41 +1,62 @@ package com.mapbox.maps.plugin.viewport.data +import com.mapbox.maps.CameraOptions import com.mapbox.maps.EdgeInsets import com.mapbox.maps.MapboxExperimental import com.mapbox.maps.plugin.viewport.DEFAULT_FOLLOW_PUCK_VIEWPORT_STATE_PITCH import com.mapbox.maps.plugin.viewport.DEFAULT_FOLLOW_PUCK_VIEWPORT_STATE_ZOOM import com.mapbox.maps.plugin.viewport.DEFAULT_STATE_ANIMATION_DURATION_MS +import com.mapbox.maps.plugin.viewport.state.FollowPuckViewportState +import com.mapbox.maps.plugin.viewport.transition.DefaultViewportTransition import java.util.Objects /** - * Options that impact the [FollowPuckViewportState]. + * Configuration options that impact the [FollowPuckViewportState]. + * + * Each of the [CameraOptions] related properties is optional, so that the state can be configured + * to only modify certain aspects of the camera if desired. This can be used, to achieve effects like + * allowing zoom gestures to work simultaneously with [FollowPuckViewportState]. + * + * @see [ViewportOptions.transitionsToIdleUponUserInteraction] */ @MapboxExperimental class FollowPuckViewportStateOptions private constructor( /** - * The edge padding of the map. + * The value to use for setting [CameraOptions.padding]. If null, padding will not be modified by + * the [FollowPuckViewportState]. + * + * Defaults to 0 padding. */ val padding: EdgeInsets?, /** - * The default zoom that will be generated for camera following frames. + * The value to use for setting [CameraOptions.zoom]. If null, zoom will not be modified by + * the [FollowPuckViewportState]. * * Defaults to [DEFAULT_FOLLOW_PUCK_VIEWPORT_STATE_ZOOM]. */ val zoom: Double?, /** - * The camera bearing configuration of the [FollowPuckViewportState]. + * Indicates how to obtain the value to use for [CameraOptions.bearing] when setting the camera. + * If set to null, bearing will not be modified by the [FollowPuckViewportState]. * * Defaults to [FollowPuckViewportStateBearing.SyncWithLocationPuck] */ val bearing: FollowPuckViewportStateBearing?, /** - * The default pitch that will be generated for following camera frames. + * The value to use for setting [CameraOptions.pitch]. If null, pitch will not be modified by + * the [FollowPuckViewportState]. * * Defaults to [DEFAULT_FOLLOW_PUCK_VIEWPORT_STATE_PITCH] degrees. */ val pitch: Double?, /** - * The maximum duration between frames in milliseconds. + * The duration of an animation that happens once when [FollowPuckViewportState.startUpdatingCamera] + * is invoked. + * + * Note: At the moment, [DefaultViewportTransition] calculates its animations based on the puck location + * at the beginning of the transition, so the farther the puck moves while the transition is in progress, + * the larger the jump when it completes and control is transferred to the target state. Tune this value + * for your use case to reduce the visibility of that jump. * * Defaults to [DEFAULT_STATE_ANIMATION_DURATION_MS] milliseconds */ @@ -81,14 +102,18 @@ class FollowPuckViewportStateOptions private constructor( private var animationDurationMs: Long = DEFAULT_STATE_ANIMATION_DURATION_MS /** - * The edge padding of the map. + * The value to use for setting [CameraOptions.padding]. If null, padding will not be modified by + * the [FollowPuckViewportState]. + * + * Defaults to 0 padding. */ fun padding(padding: EdgeInsets?) = apply { this.padding = padding } /** - * The default zoom that will be generated for camera following frames. + * The value to use for setting [CameraOptions.zoom]. If null, zoom will not be modified by + * the [FollowPuckViewportState]. * * Defaults to [DEFAULT_FOLLOW_PUCK_VIEWPORT_STATE_ZOOM]. */ @@ -97,7 +122,8 @@ class FollowPuckViewportStateOptions private constructor( } /** - * The camera bearing configuration of the [FollowPuckViewportState]. + * Indicates how to obtain the value to use for [CameraOptions.bearing] when setting the camera. + * If set to null, bearing will not be modified by the [FollowPuckViewportState]. * * Defaults to [FollowPuckViewportStateBearing.SyncWithLocationPuck] */ @@ -106,7 +132,8 @@ class FollowPuckViewportStateOptions private constructor( } /** - * The default pitch that will be generated for following camera frames. + * The value to use for setting [CameraOptions.pitch]. If null, pitch will not be modified by + * the [FollowPuckViewportState]. * * Defaults to [DEFAULT_FOLLOW_PUCK_VIEWPORT_STATE_PITCH] degrees. */ @@ -115,7 +142,13 @@ class FollowPuckViewportStateOptions private constructor( } /** - * The maximum duration between frames in milliseconds. + * The duration of an animation that happens once when [FollowPuckViewportState.startUpdatingCamera] + * is invoked. + * + * Note: At the moment, [DefaultViewportTransition] calculates its animations based on the puck location + * at the beginning of the transition, so the farther the puck moves while the transition is in progress, + * the larger the jump when it completes and control is transferred to the target state. Tune this value + * for your use case to reduce the visibility of that jump. * * Defaults to [DEFAULT_STATE_ANIMATION_DURATION_MS] milliseconds */ diff --git a/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/data/OverviewViewportStateOptions.kt b/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/data/OverviewViewportStateOptions.kt index 53ebcbd69d..e6d5bf93d8 100644 --- a/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/data/OverviewViewportStateOptions.kt +++ b/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/data/OverviewViewportStateOptions.kt @@ -4,32 +4,42 @@ import com.mapbox.geojson.Geometry import com.mapbox.maps.EdgeInsets import com.mapbox.maps.MapboxExperimental import com.mapbox.maps.plugin.viewport.DEFAULT_STATE_ANIMATION_DURATION_MS +import com.mapbox.maps.plugin.viewport.state.OverviewViewportState import java.lang.IllegalArgumentException import java.util.* /** - * Options that impact the [OverviewViewportState]. + * Configuration options that impact the [OverviewViewportState]. */ @MapboxExperimental class OverviewViewportStateOptions private constructor( /** - * The geometry that the OverviewState should cover. + * The geometry that the [OverviewViewportState] should use when calculating its camera. */ val geometry: Geometry, /** - * The edge padding of the map. + * The edge padding that [OverviewViewportState] should use when calculating its camera. + * + * Defaults to 0 padding. */ val padding: EdgeInsets, /** - * The bearing of the map. + * The bearing that [OverviewViewportState] should use when calculating its camera. + * + * Defaults to 0. */ val bearing: Double?, /** - * The pitch of the map. + * The pitch that [OverviewViewportState] should use when calculating its camera. + * + * Defaults to 0. */ val pitch: Double?, /** - * The duration between frames in milliseconds. + * The length of the animation performed in milliseconds by [OverviewViewportState] when it starts + * updating the camera and anytime [OverviewViewportState.options] is set. + * + * @see [OverviewViewportState.options] for details. * * Defaults to [DEFAULT_STATE_ANIMATION_DURATION_MS] milliseconds */ @@ -74,35 +84,44 @@ class OverviewViewportStateOptions private constructor( private var animationDurationMs: Long = DEFAULT_STATE_ANIMATION_DURATION_MS /** - * The geometry that the OverviewState should cover. + * The geometry that the [OverviewViewportState] should use when calculating its camera. */ fun geometry(geometry: Geometry) = apply { this.geometry = geometry } /** - * The edge padding of the map. + * The edge padding that [OverviewViewportState] should use when calculating its camera. + * + * Defaults to 0 padding. */ fun padding(padding: EdgeInsets) = apply { this.padding = padding } /** - * The bearing of the map. + * The bearing that [OverviewViewportState] should use when calculating its camera. + * + * Defaults to 0. */ fun bearing(bearing: Double?) = apply { this.bearing = bearing } /** - * The pitch of the map. + * The pitch that [OverviewViewportState] should use when calculating its camera. + * + * Defaults to 0. */ fun pitch(pitch: Double?) = apply { this.pitch = pitch } /** - * The duration between frames in milliseconds. + * The length of the animation performed by [OverviewViewportState] when it starts updating the + * camera and anytime [OverviewViewportState.options] is set. + * + * @see [OverviewViewportState.options] for details. * * Defaults to [DEFAULT_STATE_ANIMATION_DURATION_MS] milliseconds */ diff --git a/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/data/ViewportOptions.kt b/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/data/ViewportOptions.kt index 5073fcc944..ad052aea7f 100644 --- a/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/data/ViewportOptions.kt +++ b/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/data/ViewportOptions.kt @@ -1,16 +1,19 @@ package com.mapbox.maps.plugin.viewport.data import com.mapbox.maps.MapboxExperimental +import com.mapbox.maps.plugin.viewport.ViewportPlugin import com.mapbox.maps.plugin.viewport.state.ViewportState /** - * Options that impact the [ViewportPlugin]. + * Configuration options that impact the [ViewportPlugin]. */ @MapboxExperimental class ViewportOptions private constructor( /** - * Indicates whether to transition [ViewportState] to IDLE when user interact with the map - * using gestures. + * Indicates whether the [ViewportPlugin] should idle when user interact with the map using gestures. + * + * Set this property to false to enable building custom [ViewportState] that can work simultaneously + * with certain types of gestures. * * Defaults to true. */ @@ -45,8 +48,10 @@ class ViewportOptions private constructor( private var transitionsToIdleUponUserInteraction: Boolean = true /** - * Indicates whether to transition [ViewportState] to IDLE when user interact with the map - * using gestures. + * Indicates whether the [ViewportPlugin] should idle when user interact with the map using gestures. + * + * Set this property to false to enable building custom [ViewportState] that can work simultaneously + * with certain types of gestures. * * Defaults to true. */ diff --git a/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/state/FollowPuckViewportState.kt b/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/state/FollowPuckViewportState.kt index 0cc766e1a5..0568d943cd 100644 --- a/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/state/FollowPuckViewportState.kt +++ b/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/state/FollowPuckViewportState.kt @@ -2,14 +2,16 @@ package com.mapbox.maps.plugin.viewport.state import com.mapbox.maps.MapboxExperimental import com.mapbox.maps.plugin.locationcomponent.LocationComponentPlugin +import com.mapbox.maps.plugin.viewport.ViewportPlugin import com.mapbox.maps.plugin.viewport.data.FollowPuckViewportStateOptions /** - * The [ViewportState] that follows that follows the location component's puck position. + * The [ViewportState] that tracks the location puck's position. * - * Note: [LocationComponentPlugin] should be enabled to use this viewport state. + * Use [ViewportPlugin.makeFollowPuckViewportState] to create instances of [FollowPuckViewportState]. * - * Users are responsible to create the viewport states and keep a reference to these states for + * Note: [LocationComponentPlugin] should be enabled to use this viewport state, and Users are + * responsible to create the viewport states and keep a reference to these states for * future operations. */ @MapboxExperimental diff --git a/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/state/OverviewViewportState.kt b/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/state/OverviewViewportState.kt index 8f34c132bb..fc17023122 100644 --- a/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/state/OverviewViewportState.kt +++ b/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/state/OverviewViewportState.kt @@ -1,18 +1,24 @@ package com.mapbox.maps.plugin.viewport.state import com.mapbox.maps.MapboxExperimental +import com.mapbox.maps.plugin.viewport.ViewportPlugin import com.mapbox.maps.plugin.viewport.data.OverviewViewportStateOptions /** - * The [ViewportState] that shows the overview of a given geometry. + * The [ViewportState] that shows an overview of the geometry specified by its [OverviewViewportStateOptions.geometry]. * - * Users are responsible to create the viewport states and keep a reference to these states for + * Use [ViewportPlugin.makeOverviewViewportState] to create instances of [OverviewViewportState]. + * + * Note: Users are responsible to create the viewport states and keep a reference to these states for * future operations. */ @MapboxExperimental interface OverviewViewportState : ViewportState { /** * Describes the configuration options of the state. + * + * When set, the viewport reframes the geometry using the new options and update its camera with a + * linear camera animation and with duration specified by the new value's [OverviewViewportStateOptions.animationDurationMs]. */ var options: OverviewViewportStateOptions } \ No newline at end of file diff --git a/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/state/ViewportState.kt b/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/state/ViewportState.kt index 09f6ac73fe..a48e777232 100644 --- a/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/state/ViewportState.kt +++ b/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/state/ViewportState.kt @@ -3,21 +3,50 @@ package com.mapbox.maps.plugin.viewport.state import com.mapbox.maps.MapboxExperimental import com.mapbox.maps.plugin.animation.Cancelable import com.mapbox.maps.plugin.viewport.ViewportPlugin +import com.mapbox.maps.plugin.viewport.transition.ViewportTransition /** - * Definition of [ViewportPlugin] states. - * * [ViewportState] is used to observe the data source associated with the state and query the camera - * to keep updating according to current viewport data. + * to keep updating according to current viewport data. [ViewportState] is also used by [ViewportPlugin] + * to orchestrate transitions to and from different states. + * + * The [observeDataSource] allows [ViewportTransition] to consume a stream of camera + * updates from a target state while executing a transition. + * + * The [startUpdatingCamera] and [stopUpdatingCamera] are invoked to tell the state that it should + * assume or relinquish control of the map's camera. These are typically used by [ViewportPlugin] itself + * after a successful transition into a state and when exiting a state, respectively. * - * Users are responsible to create the viewport states and keep a reference to these states for + * Mapbox provides implementations of [ViewportState] that can be created and configured via methods + * on [ViewportPlugin]. Applications may also define their own implementations to handle advanced use + * cases not covered by the provided implementations. + * + * [ViewportState] should generally pre-warm their data sources as soon as they are created to minimise + * delays when they become current. For this reason, only states that are current(or soon-to-be) needed + * should be kept alive so that unneeded resources(e.g. location services) can be released. + * + * Note: Users are responsible to create the viewport states and keep a reference to these states for * future operations. + * + * @see [FollowPuckViewportState] + * @see [OverviewViewportState] */ @MapboxExperimental interface ViewportState { /** - * Observe the new camera options produced by the [ViewportState], it can be used to get the - * latest state [CameraOptions] for [ViewportTransition]. + * Registers an observer to receive the cameras being generated by this [ViewportState]. + * + * This method is commonly used by [ViewportTransition] implementations to obtain the target camera + * for transition animations. Transitions typically cannot start their animations until after the + * observer is invoked for the first time, so it's a good idea for [ViewportState] to invoke observer + * with the current camera if it's not too stale rather than waiting for the next camera change to + * occur. To increase the likelihood that a valid camera exists when an observer is registered, design + * [ViewportState] implementations so that they start updating their internal state prior to when they + * are passed to [ViewportPlugin.transitionTo]. + * + * The caller may either cancel on the returned [Cancelable] or return false from [ViewportStateDataObserver] + * to indicate that it wishes to stop receiving updates. Following either of these events, implementations + * must no longer invoke [ViewportStateDataObserver] and must release all strong references to it. * * @param viewportStateDataObserver observer that observe new viewport data. * @return a handle that cancels current observation. @@ -25,12 +54,19 @@ interface ViewportState { fun observeDataSource(viewportStateDataObserver: ViewportStateDataObserver): Cancelable /** - * Start updating the camera for the current [ViewportState]. + * Indicates the current [ViewportState] is now responsible for updating the camera. + * + * [ViewportPlugin] calls this method at the end of a successful transition into this state. */ fun startUpdatingCamera() /** - * Stop updating the camera for the current [ViewportState]. + * Indicates the current [ViewportState] is no longer responsible for updating the camera. + * + * [ViewportPlugin] calls this method at the beginning of the transition out of this sate. + * + * Implementations must stop updating the camera immediately and should typically cancel any ongoing + * animations that they started when this method is invoked. */ fun stopUpdatingCamera() } \ No newline at end of file diff --git a/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/state/ViewportStateDataObserver.kt b/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/state/ViewportStateDataObserver.kt index a889ed08ae..7bcd3b9c7c 100644 --- a/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/state/ViewportStateDataObserver.kt +++ b/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/state/ViewportStateDataObserver.kt @@ -4,15 +4,15 @@ import com.mapbox.maps.CameraOptions import com.mapbox.maps.MapboxExperimental /** - * Observer that gets notified whenever new data is available. + * Observer that gets notified whenever new viewport data is available. */ @MapboxExperimental fun interface ViewportStateDataObserver { /** * Notifies that new data is available. * - * @param cameraOptions The latest [CameraOptions] from the [ViewportState]. - * @return true if new data is needed. returning false will unsubscribe from further data updates. + * @param cameraOptions The most recent [CameraOptions] from the [ViewportState]. + * @return true if new data is needed and stay subscribed. returning false will unsubscribe from further data updates. */ fun onNewData(cameraOptions: CameraOptions): Boolean } \ No newline at end of file diff --git a/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/transition/DefaultViewportTransition.kt b/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/transition/DefaultViewportTransition.kt index b8c160d635..97df130137 100644 --- a/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/transition/DefaultViewportTransition.kt +++ b/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/transition/DefaultViewportTransition.kt @@ -1,15 +1,24 @@ package com.mapbox.maps.plugin.viewport.transition import com.mapbox.maps.MapboxExperimental +import com.mapbox.maps.plugin.viewport.ViewportPlugin import com.mapbox.maps.plugin.viewport.data.DefaultViewportTransitionOptions +import com.mapbox.maps.plugin.viewport.state.ViewportState /** - * The default [ViewportTransition] that transitions Viewport to the target [ViewportState]. + * The default [ViewportTransition] that transitions viewport to the target [ViewportState]. + * + * Use [ViewportPlugin.makeDefaultViewportTransition] to create instances of [DefaultViewportTransition]. + * + * Note: Users are responsible to create the viewport transitions and keep a reference to these transitions for + * future operations. */ @MapboxExperimental interface DefaultViewportTransition : ViewportTransition { /** * Describes the configuration options for the [DefaultViewportTransition]. + * + * New values will take effect the next time [ViewportTransition.run] is invoked. */ var options: DefaultViewportTransitionOptions } \ No newline at end of file diff --git a/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/transition/ViewportTransition.kt b/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/transition/ViewportTransition.kt index 643be5d223..343eec75d7 100644 --- a/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/transition/ViewportTransition.kt +++ b/sdk-base/src/main/java/com/mapbox/maps/plugin/viewport/transition/ViewportTransition.kt @@ -3,25 +3,38 @@ package com.mapbox.maps.plugin.viewport.transition import com.mapbox.maps.MapboxExperimental import com.mapbox.maps.plugin.animation.Cancelable import com.mapbox.maps.plugin.viewport.CompletionListener +import com.mapbox.maps.plugin.viewport.ViewportPlugin import com.mapbox.maps.plugin.viewport.state.ViewportState /** * Defines how to transition to another [ViewportState]. + * + * [ViewportTransition] is used by [ViewportPlugin] to orchestrate transitions to and from different + * [ViewportState]. + * + * Mapbox provides implementations of [ViewportTransition] that can be created and configured via methods + * on [ViewportPlugin]. Applications may also define their own implementations to handle advanced use + * cases not covered by the provided implementations. + * + * @see [ViewportPlugin.makeDefaultViewportTransition] + * @see [ViewportPlugin.makeImmediateViewportTransition] */ @MapboxExperimental fun interface ViewportTransition { /** * Run the [ViewportTransition] from current viewport to the target [ViewportState]. * - * The completion block contains a Bool that is true if the transition is cancelled and false - * if it ran to completion. Implementations must be sure to invoke the completion block with false if - * the returned Cancelable is invoked prior to completion. the completion block must be invoked - * on the main queue. Transitions must handle the possibility that the "to" state might fail to - * provide a target camera in a timely manner or might update the target camera multiple times - * during the transition (a "moving target"). + * The completion block must be invoked with true if the transition completes successfully. If the + * transition fails, invoke the completion block with false. + * + * If the returned [Cancelable] is canceled, it's not necessary to invoke the completion block(but + * safe to do so, as it will just be ignored. + * + * Transitions should handle the possibility that [to] state might fail to provide camera in a timely + * manner or might update the target camera multiple times during the transition(i.e. a 'moving target'). * * @param to The target [ViewportState] - * @param completionListener The listener to observe the completion state. + * @param completionListener The listener to observe the completion state, it must be invoked on the main queue. * @return a handle that can be used to cancel the current [ViewportTransition] */ fun run(