From 050ca133e968d5cdd671bfd8590bc92576e58dcc Mon Sep 17 00:00:00 2001 From: Arthur Monteiro Date: Thu, 28 Aug 2025 16:08:39 -0300 Subject: [PATCH 1/4] feat: add camera control --- .../google_maps_flutter_web/CHANGELOG.md | 4 ++ .../google_maps_controller_test.dart | 51 ++++++++++++++ .../example/pubspec.yaml | 2 +- .../lib/src/convert.dart | 66 +++++++++++++++++++ .../google_maps_flutter_web/pubspec.yaml | 4 +- 5 files changed, 124 insertions(+), 3 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md index f2e6fcd7affc..1522575be0fc 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter_web/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.5.14 + +* Adds support for disabling or moving the camera control button on web. + ## 0.5.13 * Updates minimum supported SDK version to Flutter 3.29/Dart 3.7. diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart index 32ebfdc5b93f..09b847d2cf22 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart @@ -524,6 +524,57 @@ void main() { expect(capturedOptions!.gestureHandling, 'greedy'); }); + testWidgets('translates webCameraControlEnabled option', ( + WidgetTester tester, + ) async { + gmaps.MapOptions? capturedOptions; + controller = createController( + mapConfiguration: const MapConfiguration( + zoomGesturesEnabled: false, + webCameraControlEnabled: true, + ), + ); + controller.debugSetOverrides( + createMap: (_, gmaps.MapOptions options) { + capturedOptions = options; + return map; + }, + ); + + controller.init(); + + expect(capturedOptions, isNotNull); + expect(capturedOptions!.cameraControl, isTrue); + }); + + testWidgets('translates webCameraControlEnabled option', ( + WidgetTester tester, + ) async { + gmaps.MapOptions? capturedOptions; + controller = createController( + mapConfiguration: const MapConfiguration( + zoomGesturesEnabled: false, + webCameraControlEnabled: true, + webCameraControlPosition: WebCameraControlPosition.bottomLeft, + ), + ); + controller.debugSetOverrides( + createMap: (_, gmaps.MapOptions options) { + capturedOptions = options; + return map; + }, + ); + + controller.init(); + + expect(capturedOptions, isNotNull); + expect(capturedOptions!.cameraControl, isTrue); + expect( + capturedOptions!.cameraControlOptions?.position, + gmaps.ControlPosition.BOTTOM_LEFT, + ); + }); + testWidgets('translates cameraTargetBounds option', ( WidgetTester tester, ) async { diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml index b87b2a4cc482..3b48e3dbecb5 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml @@ -8,7 +8,7 @@ environment: dependencies: flutter: sdk: flutter - google_maps_flutter_platform_interface: ^2.12.1 + google_maps_flutter_platform_interface: ^2.14.0 google_maps_flutter_web: path: ../ web: ^1.0.0 diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart index 3787a8cca951..db25752ade1a 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart @@ -95,6 +95,16 @@ gmaps.MapOptions _configurationAndStyleToGmapsOptions( options.gestureHandling = WebGestureHandling.auto.name; } + if (configuration.webCameraControlEnabled != null) { + options.cameraControl = configuration.webCameraControlEnabled; + } + + if (configuration.webCameraControlPosition != null) { + options.cameraControlOptions = gmaps.CameraControlOptions( + position: _toControlPosition(configuration.webCameraControlPosition!), + ); + } + if (configuration.fortyFiveDegreeImageryEnabled != null) { options.rotateControl = configuration.fortyFiveDegreeImageryEnabled; } @@ -787,3 +797,59 @@ gmaps.LatLng _pixelToLatLng(gmaps.Map map, int x, int y) { return projection.fromPointToLatLng(point)!; } + +/// Converts a [WebCameraControlPosition] to [gmaps.ControlPosition]. +gmaps.ControlPosition _toControlPosition( + WebCameraControlPosition webCameraControlPosition, +) { + switch (webCameraControlPosition) { + case WebCameraControlPosition.blockEndInlineCenter: + return gmaps.ControlPosition.BLOCK_END_INLINE_CENTER; + case WebCameraControlPosition.blockEndInlineEnd: + return gmaps.ControlPosition.BLOCK_END_INLINE_END; + case WebCameraControlPosition.blockEndInlineStart: + return gmaps.ControlPosition.BLOCK_END_INLINE_START; + case WebCameraControlPosition.blockStartInlineCenter: + return gmaps.ControlPosition.BLOCK_START_INLINE_CENTER; + case WebCameraControlPosition.blockStartInlineEnd: + return gmaps.ControlPosition.BLOCK_START_INLINE_END; + case WebCameraControlPosition.blockStartInlineStart: + return gmaps.ControlPosition.BLOCK_START_INLINE_START; + case WebCameraControlPosition.bottomCenter: + return gmaps.ControlPosition.BOTTOM_CENTER; + case WebCameraControlPosition.bottomLeft: + return gmaps.ControlPosition.BOTTOM_LEFT; + case WebCameraControlPosition.bottomRight: + return gmaps.ControlPosition.BOTTOM_RIGHT; + case WebCameraControlPosition.inlineEndBlockCenter: + return gmaps.ControlPosition.INLINE_END_BLOCK_CENTER; + case WebCameraControlPosition.inlineEndBlockEnd: + return gmaps.ControlPosition.INLINE_END_BLOCK_END; + case WebCameraControlPosition.inlineEndBlockStart: + return gmaps.ControlPosition.INLINE_END_BLOCK_START; + case WebCameraControlPosition.inlineStartBlockCenter: + return gmaps.ControlPosition.INLINE_START_BLOCK_CENTER; + case WebCameraControlPosition.inlineStartBlockEnd: + return gmaps.ControlPosition.INLINE_START_BLOCK_END; + case WebCameraControlPosition.inlineStartBlockStart: + return gmaps.ControlPosition.INLINE_START_BLOCK_START; + case WebCameraControlPosition.leftBottom: + return gmaps.ControlPosition.LEFT_BOTTOM; + case WebCameraControlPosition.leftCenter: + return gmaps.ControlPosition.LEFT_CENTER; + case WebCameraControlPosition.leftTop: + return gmaps.ControlPosition.LEFT_TOP; + case WebCameraControlPosition.rightBottom: + return gmaps.ControlPosition.RIGHT_BOTTOM; + case WebCameraControlPosition.rightCenter: + return gmaps.ControlPosition.RIGHT_CENTER; + case WebCameraControlPosition.rightTop: + return gmaps.ControlPosition.RIGHT_TOP; + case WebCameraControlPosition.topCenter: + return gmaps.ControlPosition.TOP_CENTER; + case WebCameraControlPosition.topLeft: + return gmaps.ControlPosition.TOP_LEFT; + case WebCameraControlPosition.topRight: + return gmaps.ControlPosition.TOP_RIGHT; + } +} diff --git a/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml index 2a81e0f247c8..2677176c86dc 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml @@ -2,7 +2,7 @@ name: google_maps_flutter_web description: Web platform implementation of google_maps_flutter repository: https://github.com/flutter/packages/tree/main/packages/google_maps_flutter/google_maps_flutter_web issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+maps%22 -version: 0.5.13 +version: 0.5.14 environment: sdk: ^3.7.0 @@ -23,7 +23,7 @@ dependencies: flutter_web_plugins: sdk: flutter google_maps: ^8.0.0 - google_maps_flutter_platform_interface: ^2.12.1 + google_maps_flutter_platform_interface: ^2.14.0 sanitize_html: ^2.0.0 stream_transform: ^2.0.0 web: ">=0.5.1 <2.0.0" From 4d26fb7d8e50788286c2d042ccc096ada934e8a7 Mon Sep 17 00:00:00 2001 From: Arthur Monteiro Date: Thu, 28 Aug 2025 16:14:31 -0300 Subject: [PATCH 2/4] chore: update test name --- .../example/integration_test/google_maps_controller_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart index 09b847d2cf22..e3e206c86dd6 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/integration_test/google_maps_controller_test.dart @@ -547,7 +547,7 @@ void main() { expect(capturedOptions!.cameraControl, isTrue); }); - testWidgets('translates webCameraControlEnabled option', ( + testWidgets('translates webCameraControlPosition option', ( WidgetTester tester, ) async { gmaps.MapOptions? capturedOptions; From 9894d37171babece81d3fbbab18cc08578022e8e Mon Sep 17 00:00:00 2001 From: Arthur Monteiro Date: Thu, 28 Aug 2025 18:13:37 -0300 Subject: [PATCH 3/4] chore: upgrade google_maps to 8.1.0 --- .../google_maps_flutter_web/example/pubspec.yaml | 2 +- .../google_maps_flutter/google_maps_flutter_web/pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml index 3b48e3dbecb5..96e889984d0b 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_web/example/pubspec.yaml @@ -17,7 +17,7 @@ dev_dependencies: build_runner: ^2.1.1 flutter_test: sdk: flutter - google_maps: ^8.0.0 + google_maps: ^8.1.0 google_maps_flutter: ^2.2.0 # Needed for projection_test.dart http: ^1.2.2 integration_test: diff --git a/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml index 2677176c86dc..bbf91f2d3694 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_web/pubspec.yaml @@ -22,7 +22,7 @@ dependencies: sdk: flutter flutter_web_plugins: sdk: flutter - google_maps: ^8.0.0 + google_maps: ^8.1.0 google_maps_flutter_platform_interface: ^2.14.0 sanitize_html: ^2.0.0 stream_transform: ^2.0.0 From 8fa8c4c63659d8a7779e92deaef5c43235ca0049 Mon Sep 17 00:00:00 2001 From: Arthur Monteiro Date: Thu, 28 Aug 2025 18:20:31 -0300 Subject: [PATCH 4/4] enhancement: handle the case of an enum value being added --- .../google_maps_flutter_web/lib/src/convert.dart | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart index db25752ade1a..2515636170e7 100644 --- a/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart +++ b/packages/google_maps_flutter/google_maps_flutter_web/lib/src/convert.dart @@ -100,9 +100,15 @@ gmaps.MapOptions _configurationAndStyleToGmapsOptions( } if (configuration.webCameraControlPosition != null) { - options.cameraControlOptions = gmaps.CameraControlOptions( - position: _toControlPosition(configuration.webCameraControlPosition!), + final gmaps.ControlPosition? controlPosition = _toControlPosition( + configuration.webCameraControlPosition!, ); + + if (controlPosition != null) { + options.cameraControlOptions = gmaps.CameraControlOptions( + position: controlPosition, + ); + } } if (configuration.fortyFiveDegreeImageryEnabled != null) { @@ -799,7 +805,7 @@ gmaps.LatLng _pixelToLatLng(gmaps.Map map, int x, int y) { } /// Converts a [WebCameraControlPosition] to [gmaps.ControlPosition]. -gmaps.ControlPosition _toControlPosition( +gmaps.ControlPosition? _toControlPosition( WebCameraControlPosition webCameraControlPosition, ) { switch (webCameraControlPosition) {