blob: ecfc4d830c629ae1410e8f29aa9a0826d98c8438 [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
part of google_maps_flutter;
/// Controller for a single GoogleMap instance running on the host platform.
///
/// Change listeners are notified upon changes to any of
///
/// * the [options] property
/// * the [isCameraMoving] property
/// * the [cameraPosition] property
///
/// Listeners are notified after changes have been applied on the platform side.
class GoogleMapController extends ChangeNotifier {
GoogleMapController._(
MethodChannel channel,
CameraPosition initialCameraPosition,
this._googleMapState,
) : assert(channel != null),
_channel = channel {
_cameraPosition = initialCameraPosition;
_channel.setMethodCallHandler(_handleMethodCall);
}
static Future<GoogleMapController> init(
int id,
CameraPosition initialCameraPosition,
_GoogleMapState googleMapState,
) async {
assert(id != null);
final MethodChannel channel =
MethodChannel('plugins.flutter.io/google_maps_$id');
// TODO(amirh): remove this on when the invokeMethod update makes it to stable Flutter.
// https://github.com/flutter/flutter/issues/26431
// ignore: strong_mode_implicit_dynamic_method
await channel.invokeMethod('map#waitForMap');
return GoogleMapController._(
channel,
initialCameraPosition,
googleMapState,
);
}
final MethodChannel _channel;
/// True if the map camera is currently moving.
bool get isCameraMoving => _isCameraMoving;
bool _isCameraMoving = false;
final _GoogleMapState _googleMapState;
/// Returns the most recent camera position reported by the platform side.
/// Will be null, if [GoogleMap.trackCameraPosition] is false.
CameraPosition get cameraPosition => _cameraPosition;
CameraPosition _cameraPosition;
Future<dynamic> _handleMethodCall(MethodCall call) async {
switch (call.method) {
case 'camera#onMoveStarted':
_isCameraMoving = true;
notifyListeners();
break;
case 'camera#onMove':
_cameraPosition = CameraPosition.fromMap(call.arguments['position']);
notifyListeners();
break;
case 'camera#onIdle':
_isCameraMoving = false;
notifyListeners();
break;
case 'marker#onTap':
_googleMapState.onMarkerTap(call.arguments['markerId']);
break;
case 'infoWindow#onTap':
_googleMapState.onInfoWindowTap(call.arguments['markerId']);
break;
default:
throw MissingPluginException();
}
}
/// Updates configuration options of the map user interface.
///
/// Change listeners are notified once the update has been made on the
/// platform side.
///
/// The returned [Future] completes after listeners have been notified.
Future<void> _updateMapOptions(Map<String, dynamic> optionsUpdate) async {
assert(optionsUpdate != null);
// TODO(amirh): remove this on when the invokeMethod update makes it to stable Flutter.
// https://github.com/flutter/flutter/issues/26431
// ignore: strong_mode_implicit_dynamic_method
final dynamic json = await _channel.invokeMethod(
'map#update',
<String, dynamic>{
'options': optionsUpdate,
},
);
_cameraPosition = CameraPosition.fromMap(json);
notifyListeners();
}
/// Updates marker configuration.
///
/// Change listeners are notified once the update has been made on the
/// platform side.
///
/// The returned [Future] completes after listeners have been notified.
Future<void> _updateMarkers(_MarkerUpdates markerUpdates) async {
assert(markerUpdates != null);
// TODO(amirh): remove this on when the invokeMethod update makes it to stable Flutter.
// https://github.com/flutter/flutter/issues/26431
// ignore: strong_mode_implicit_dynamic_method
await _channel.invokeMethod(
'markers#update',
markerUpdates._toMap(),
);
notifyListeners();
}
/// Starts an animated change of the map camera position.
///
/// The returned [Future] completes after the change has been started on the
/// platform side.
Future<void> animateCamera(CameraUpdate cameraUpdate) async {
// TODO(amirh): remove this on when the invokeMethod update makes it to stable Flutter.
// https://github.com/flutter/flutter/issues/26431
// ignore: strong_mode_implicit_dynamic_method
await _channel.invokeMethod('camera#animate', <String, dynamic>{
'cameraUpdate': cameraUpdate._toJson(),
});
}
/// Changes the map camera position.
///
/// The returned [Future] completes after the change has been made on the
/// platform side.
Future<void> moveCamera(CameraUpdate cameraUpdate) async {
// TODO(amirh): remove this on when the invokeMethod update makes it to stable Flutter.
// https://github.com/flutter/flutter/issues/26431
// ignore: strong_mode_implicit_dynamic_method
await _channel.invokeMethod('camera#move', <String, dynamic>{
'cameraUpdate': cameraUpdate._toJson(),
});
}
}