From 8251ab01c10f45d3feb1d41a21b37b4641f363c4 Mon Sep 17 00:00:00 2001 From: Arthur Monteiro Date: Wed, 27 Aug 2025 12:19:04 -0300 Subject: [PATCH 1/4] feat: add cameraControl enablse/disable --- .../CHANGELOG.md | 5 +- .../lib/src/types/map_configuration.dart | 32 +++++++ .../lib/src/types/types.dart | 1 + .../types/web_camera_control_position.dart | 93 +++++++++++++++++++ .../pubspec.yaml | 2 +- .../test/types/map_configuration_test.dart | 51 ++++++++++ 6 files changed, 181 insertions(+), 3 deletions(-) create mode 100644 packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/web_camera_control_position.dart diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md b/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md index 20585d0257d..3641925e578 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md @@ -1,5 +1,6 @@ -## NEXT +## 2.14.0 +* Adds support for disabling or moving the camera control button on web. * Updates minimum supported SDK version to Flutter 3.29/Dart 3.7. ## 2.13.0 @@ -247,4 +248,4 @@ ## 1.0.0 ... 1.0.0+5 -* Development. +* Development. \ No newline at end of file diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/map_configuration.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/map_configuration.dart index 960a4c425b1..5bf2a67a907 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/map_configuration.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/map_configuration.dart @@ -15,6 +15,8 @@ class MapConfiguration { /// as either a full configuration selection, or an update to an existing /// configuration where only non-null values are updated. const MapConfiguration({ + this.webCameraControlPosition, + this.webCameraControlEnabled, this.webGestureHandling, this.compassEnabled, this.mapToolbarEnabled, @@ -47,6 +49,18 @@ class MapConfiguration { /// See [WebGestureHandling] for more details. final WebGestureHandling? webGestureHandling; + /// This setting controls how the API handles cameraControl button position on the map. Web only. + /// + /// If null, the Google Maps API will use its default camera control position. + /// + /// See [WebCameraControlPosition] for more details. + final WebCameraControlPosition? webCameraControlPosition; + + /// This setting controls how the API handles cameraControl button on the map. Web only. + /// + /// See https://developers.google.com/maps/documentation/javascript/controls for more details. + final bool? webCameraControlEnabled; + /// True if the compass UI should be shown. final bool? compassEnabled; @@ -142,6 +156,14 @@ class MapConfiguration { /// that are different from [other]. MapConfiguration diffFrom(MapConfiguration other) { return MapConfiguration( + webCameraControlPosition: + webCameraControlPosition != other.webCameraControlPosition + ? webCameraControlPosition + : null, + webCameraControlEnabled: + webCameraControlEnabled != other.webCameraControlEnabled + ? webCameraControlEnabled + : null, webGestureHandling: webGestureHandling != other.webGestureHandling ? webGestureHandling @@ -218,6 +240,10 @@ class MapConfiguration { /// replacing the previous values. MapConfiguration applyDiff(MapConfiguration diff) { return MapConfiguration( + webCameraControlPosition: + diff.webCameraControlPosition ?? webCameraControlPosition, + webCameraControlEnabled: + diff.webCameraControlEnabled ?? webCameraControlEnabled, webGestureHandling: diff.webGestureHandling ?? webGestureHandling, compassEnabled: diff.compassEnabled ?? compassEnabled, mapToolbarEnabled: diff.mapToolbarEnabled ?? mapToolbarEnabled, @@ -250,6 +276,8 @@ class MapConfiguration { /// True if no options are set. bool get isEmpty => + webCameraControlPosition == null && + webCameraControlEnabled == null && webGestureHandling == null && compassEnabled == null && mapToolbarEnabled == null && @@ -283,6 +311,8 @@ class MapConfiguration { return false; } return other is MapConfiguration && + webCameraControlPosition == other.webCameraControlPosition && + webCameraControlEnabled == other.webCameraControlEnabled && webGestureHandling == other.webGestureHandling && compassEnabled == other.compassEnabled && mapToolbarEnabled == other.mapToolbarEnabled && @@ -311,6 +341,8 @@ class MapConfiguration { @override int get hashCode => Object.hashAll([ webGestureHandling, + webCameraControlPosition, + webCameraControlEnabled, compassEnabled, mapToolbarEnabled, cameraTargetBounds, diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/types.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/types.dart index 08c34d29ea7..85a7096a404 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/types.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/types.dart @@ -45,4 +45,5 @@ export 'utils/marker.dart'; export 'utils/polygon.dart'; export 'utils/polyline.dart'; export 'utils/tile_overlay.dart'; +export 'web_camera_control_position.dart'; export 'web_gesture_handling.dart'; diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/web_camera_control_position.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/web_camera_control_position.dart new file mode 100644 index 00000000000..d3d417557ba --- /dev/null +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/web_camera_control_position.dart @@ -0,0 +1,93 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/// This setting controls how the API handles camera control button on the map +/// See https://developers.google.com/maps/documentation/javascript/reference/control#ControlPosition for more details. +enum WebCameraControlPosition { + /// Equivalent to BOTTOM_CENTER in both LTR and RTL. + blockEndInlineCenter, + + /// Equivalent to BOTTOM_LEFT in LTR, or BOTTOM_RIGHT in RTL. + blockEndInlineStart, + + /// Equivalent to TOP_RIGHT in LTR, or TOP_LEFT in RTL. + blockEndInlineEnd, + + /// Equivalent to TOP_CENTER in both LTR and RTL. + blockStartInlineCenter, + + /// Equivalent to TOP_LEFT in LTR, or TOP_RIGHT in RTL. + blockStartInlineStart, + + /// Equivalent to TOP_RIGHT in LTR, or TOP_LEFT in RTL. + blockStartInlineEnd, + + /// Elements are positioned in the center of the bottom row. + /// Consider using BLOCK_END_INLINE_CENTER instead. + bottomCenter, + + /// Elements are positioned in the bottom left and flow towards the middle. + /// Elements are positioned to the right of the Google logo. + /// Consider using BLOCK_END_INLINE_START instead. + bottomLeft, + + /// Elements are positioned in the bottom right and flow towards the middle. + /// Elements are positioned to the left of the copyrights. + /// Consider using BLOCK_END_INLINE_END instead. + bottomRight, + + /// Equivalent to RIGHT_CENTER in LTR, or LEFT_CENTER in RTL. + inlineEndBlockCenter, + + /// Equivalent to RIGHT_BOTTOM in LTR, or LEFT_BOTTOM in RTL. + inlineEndBlockEnd, + + /// Equivalent to RIGHT_TOP in LTR, or LEFT_TOP in RTL. + inlineEndBlockStart, + + /// Equivalent to LEFT_CENTER in LTR, or RIGHT_CENTER in RTL. + inlineStartBlockCenter, + + /// Equivalent to LEFT_BOTTOM in LTR, or RIGHT_BOTTOM in RTL. + inlineStartBlockEnd, + + /// Equivalent to LEFT_TOP in LTR, or RIGHT_TOP in RTL. + inlineStartBlockStart, + + /// Elements are positioned on the left, above bottom-left elements, + /// and flow upwards. Consider using INLINE_START_BLOCK_END instead. + leftBottom, + + /// Elements are positioned in the center of the left side. + /// Consider using INLINE_START_BLOCK_CENTER instead. + leftCenter, + + /// Elements are positioned on the left, below top-left elements, + /// and flow downwards. Consider using INLINE_START_BLOCK_START instead. + leftTop, + + /// Elements are positioned on the right, above bottom-right elements, + /// and flow upwards. Consider using INLINE_END_BLOCK_END instead. + rightBottom, + + /// Elements are positioned in the center of the right side. + /// Consider using INLINE_END_BLOCK_CENTER instead. + rightCenter, + + /// Elements are positioned on the right, below top-right elements, + /// and flow downwards. Consider using INLINE_END_BLOCK_START instead. + rightTop, + + /// Elements are positioned in the center of the top row. + /// Consider using BLOCK_START_INLINE_CENTER instead. + topCenter, + + /// Elements are positioned in the top left and flow towards the middle. + /// Consider using BLOCK_START_INLINE_START instead. + topLeft, + + /// Elements are positioned in the top right and flow towards the middle. + /// Consider using BLOCK_START_INLINE_END instead. + topRight, +} diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml b/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml index 643165f130e..7a8fdc763c6 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml @@ -4,7 +4,7 @@ repository: https://github.com/flutter/packages/tree/main/packages/google_maps_f issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+maps%22 # NOTE: We strongly prefer non-breaking changes, even at the expense of a # less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes -version: 2.13.0 +version: 2.14.0 environment: sdk: ^3.7.0 diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/map_configuration_test.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/map_configuration_test.dart index 5ce807556df..00c9e61c4c0 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/map_configuration_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/map_configuration_test.dart @@ -12,6 +12,8 @@ void main() { group('diffs', () { // A options instance with every field set, to test diffs against. final MapConfiguration diffBase = MapConfiguration( + webCameraControlPosition: WebCameraControlPosition.topRight, + webCameraControlEnabled: false, webGestureHandling: WebGestureHandling.auto, compassEnabled: false, mapToolbarEnabled: false, @@ -62,6 +64,8 @@ void main() { expect(updated.liteModeEnabled, isNot(null)); expect(updated.padding, isNot(null)); expect(updated.trafficEnabled, isNot(null)); + expect(updated.cloudMapId, null); + expect(updated.webCameraControlPosition, isNot(null)); expect(updated.mapId, null); }); @@ -83,6 +87,45 @@ void main() { expect(empty.hashCode, isNot(diff.hashCode)); }); + test('handle webCameraControlPosition', () async { + const MapConfiguration diff = MapConfiguration( + webCameraControlPosition: WebCameraControlPosition.blockEndInlineEnd, + ); + + const MapConfiguration empty = MapConfiguration(); + final MapConfiguration updated = diffBase.applyDiff(diff); + + // A diff applied to empty options should be the diff itself. + expect(empty.applyDiff(diff), diff); + // The diff from empty options should be the diff itself. + expect(diff.diffFrom(empty), diff); + // A diff applied to non-empty options should update that field. + expect( + updated.webCameraControlPosition, + WebCameraControlPosition.blockEndInlineEnd, + ); + // The hash code should change. + expect(empty.hashCode, isNot(diff.hashCode)); + }); + + test('handle webCameraControlEnabled', () async { + const MapConfiguration diff = MapConfiguration( + webCameraControlEnabled: true, + ); + + const MapConfiguration empty = MapConfiguration(); + final MapConfiguration updated = diffBase.applyDiff(diff); + + // A diff applied to empty options should be the diff itself. + expect(empty.applyDiff(diff), diff); + // The diff from empty options should be the diff itself. + expect(diff.diffFrom(empty), diff); + // A diff applied to non-empty options should update that field. + expect(updated.webCameraControlEnabled, true); + // The hash code should change. + expect(empty.hashCode, isNot(diff.hashCode)); + }); + test('handle compassEnabled', () async { const MapConfiguration diff = MapConfiguration(compassEnabled: true); @@ -470,6 +513,14 @@ void main() { expect(nullOptions.isEmpty, true); }); + test('is false with webCameraControlEnabled', () async { + const MapConfiguration diff = MapConfiguration( + webCameraControlEnabled: true, + ); + + expect(diff.isEmpty, false); + }); + test('is false with compassEnabled', () async { const MapConfiguration diff = MapConfiguration(compassEnabled: true); From e919f3d3a1f2e8f407dffd39129b9b9c759815a0 Mon Sep 17 00:00:00 2001 From: Arthur Monteiro Alves Melo Date: Wed, 27 Aug 2025 12:23:41 -0300 Subject: [PATCH 2/4] Update packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/web_camera_control_position.dart Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- .../lib/src/types/web_camera_control_position.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/web_camera_control_position.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/web_camera_control_position.dart index d3d417557ba..dd7489d6ec1 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/web_camera_control_position.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/web_camera_control_position.dart @@ -11,7 +11,7 @@ enum WebCameraControlPosition { /// Equivalent to BOTTOM_LEFT in LTR, or BOTTOM_RIGHT in RTL. blockEndInlineStart, - /// Equivalent to TOP_RIGHT in LTR, or TOP_LEFT in RTL. + /// Equivalent to BOTTOM_RIGHT in LTR, or BOTTOM_LEFT in RTL. blockEndInlineEnd, /// Equivalent to TOP_CENTER in both LTR and RTL. From a53dea06d76d84ab63b2b9b87eed7239860eecd6 Mon Sep 17 00:00:00 2001 From: Arthur Monteiro Date: Wed, 27 Aug 2025 16:28:20 -0300 Subject: [PATCH 3/4] chore: update docs --- .../types/web_camera_control_position.dart | 31 +++++++++++++++---- 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/web_camera_control_position.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/web_camera_control_position.dart index dd7489d6ec1..84b64cb282e 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/web_camera_control_position.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/web_camera_control_position.dart @@ -2,8 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -/// This setting controls how the API handles camera control button on the map -/// See https://developers.google.com/maps/documentation/javascript/reference/control#ControlPosition for more details. +/// This setting controls how the API handles camera control button on the map. +/// +/// See https://developers.google.com/maps/documentation/javascript/reference/control#ControlPosition +/// for more details. enum WebCameraControlPosition { /// Equivalent to BOTTOM_CENTER in both LTR and RTL. blockEndInlineCenter, @@ -24,16 +26,21 @@ enum WebCameraControlPosition { blockStartInlineEnd, /// Elements are positioned in the center of the bottom row. + /// /// Consider using BLOCK_END_INLINE_CENTER instead. bottomCenter, /// Elements are positioned in the bottom left and flow towards the middle. + /// /// Elements are positioned to the right of the Google logo. + /// /// Consider using BLOCK_END_INLINE_START instead. bottomLeft, /// Elements are positioned in the bottom right and flow towards the middle. + /// /// Elements are positioned to the left of the copyrights. + /// /// Consider using BLOCK_END_INLINE_END instead. bottomRight, @@ -56,7 +63,9 @@ enum WebCameraControlPosition { inlineStartBlockStart, /// Elements are positioned on the left, above bottom-left elements, - /// and flow upwards. Consider using INLINE_START_BLOCK_END instead. + /// and flow upwards. + /// + /// Consider using INLINE_START_BLOCK_END instead. leftBottom, /// Elements are positioned in the center of the left side. @@ -64,30 +73,40 @@ enum WebCameraControlPosition { leftCenter, /// Elements are positioned on the left, below top-left elements, - /// and flow downwards. Consider using INLINE_START_BLOCK_START instead. + /// and flow downwards. + /// + /// Consider using INLINE_START_BLOCK_START instead. leftTop, /// Elements are positioned on the right, above bottom-right elements, - /// and flow upwards. Consider using INLINE_END_BLOCK_END instead. + /// and flow upwards. + /// + /// Consider using INLINE_END_BLOCK_END instead. rightBottom, /// Elements are positioned in the center of the right side. + /// /// Consider using INLINE_END_BLOCK_CENTER instead. rightCenter, /// Elements are positioned on the right, below top-right elements, - /// and flow downwards. Consider using INLINE_END_BLOCK_START instead. + /// and flow downwards. + /// + /// Consider using INLINE_END_BLOCK_START instead. rightTop, /// Elements are positioned in the center of the top row. + /// /// Consider using BLOCK_START_INLINE_CENTER instead. topCenter, /// Elements are positioned in the top left and flow towards the middle. + /// /// Consider using BLOCK_START_INLINE_START instead. topLeft, /// Elements are positioned in the top right and flow towards the middle. + /// /// Consider using BLOCK_START_INLINE_END instead. topRight, } From 2a11b3ae0c4b428350f053951d1315943aec5006 Mon Sep 17 00:00:00 2001 From: Arthur Monteiro Date: Wed, 27 Aug 2025 17:48:40 -0300 Subject: [PATCH 4/4] chore: add webCameraControlPosition test --- .../test/types/map_configuration_test.dart | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/map_configuration_test.dart b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/map_configuration_test.dart index 00c9e61c4c0..d60dbe58772 100644 --- a/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/map_configuration_test.dart +++ b/packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/map_configuration_test.dart @@ -521,6 +521,14 @@ void main() { expect(diff.isEmpty, false); }); + test('is false with webCameraControlPosition', () async { + const MapConfiguration diff = MapConfiguration( + webCameraControlPosition: WebCameraControlPosition.blockEndInlineCenter, + ); + + expect(diff.isEmpty, false); + }); + test('is false with compassEnabled', () async { const MapConfiguration diff = MapConfiguration(compassEnabled: true);