Skip to content

Commit d07c025

Browse files
[google_maps_flutter_platform_interface] Split CameraUpdate into derived classes to use structured data (flutter#7596)
Platform interface part of flutter/packages#7507 flutter#152928 ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] page, which explains my responsibilities. - [x] I read and followed the [relevant style guides] and ran the auto-formatter. (Unlike the flutter/flutter repo, the flutter/packages repo does use `dart format`.) - [ ] I signed the [CLA]. - [x] The title of the PR starts with the name of the package surrounded by square brackets, e.g. `[shared_preferences]` - [x] I [linked to at least one issue that this PR fixes] in the description above. - [x] I updated `pubspec.yaml` with an appropriate new version according to the [pub versioning philosophy], or this PR is [exempt from version changes]. - [x] I updated `CHANGELOG.md` to add a description of the change, [following repository CHANGELOG style], or this PR is [exempt from CHANGELOG changes]. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. <!-- Links --> [Contributor Guide]: https://github.com/flutter/packages/blob/main/CONTRIBUTING.md [Tree Hygiene]: https://github.com/flutter/flutter/blob/master/docs/contributing/Tree-hygiene.md [relevant style guides]: https://github.com/flutter/packages/blob/main/CONTRIBUTING.md#style [CLA]: https://cla.developers.google.com/ [Discord]: https://github.com/flutter/flutter/blob/master/docs/contributing/Chat.md [linked to at least one issue that this PR fixes]: https://github.com/flutter/flutter/blob/master/docs/contributing/Tree-hygiene.md#overview [pub versioning philosophy]: https://dart.dev/tools/pub/versioning [exempt from version changes]: https://github.com/flutter/flutter/blob/master/docs/ecosystem/contributing/README.md#version [following repository CHANGELOG style]: https://github.com/flutter/flutter/blob/master/docs/ecosystem/contributing/README.md#changelog-style [exempt from CHANGELOG changes]: https://github.com/flutter/flutter/blob/master/docs/ecosystem/contributing/README.md#changelog [test-exempt]: https://github.com/flutter/flutter/blob/master/docs/contributing/Tree-hygiene.md#tests
1 parent 8d1acdd commit d07c025

File tree

4 files changed

+243
-34
lines changed

4 files changed

+243
-34
lines changed

packages/google_maps_flutter/google_maps_flutter_platform_interface/CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
## NEXT
1+
## 2.9.1
22

3+
* Splits CameraUpdate into dervied classes for different update cases.
34
* Updates minimum supported SDK version to Flutter 3.19/Dart 3.3.
45

56
## 2.9.0

packages/google_maps_flutter/google_maps_flutter_platform_interface/lib/src/types/camera.dart

Lines changed: 162 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -110,42 +110,67 @@ class CameraPosition {
110110
'CameraPosition(bearing: $bearing, target: $target, tilt: $tilt, zoom: $zoom)';
111111
}
112112

113+
/// Indicates which type of camera update this instance represents.
114+
enum CameraUpdateType {
115+
/// New position for camera
116+
newCameraPosition,
117+
118+
/// New coordinates for camera
119+
newLatLng,
120+
121+
/// New coordinates bounding box
122+
newLatLngBounds,
123+
124+
/// New coordinate with zoom level
125+
newLatLngZoom,
126+
127+
/// Move by a scroll delta
128+
scrollBy,
129+
130+
/// Zoom by a relative change
131+
zoomBy,
132+
133+
/// Zoom to an absolute level
134+
zoomTo,
135+
136+
/// Zoom in
137+
zoomIn,
138+
139+
/// Zoom out
140+
zoomOut,
141+
}
142+
113143
/// Defines a camera move, supporting absolute moves as well as moves relative
114144
/// the current position.
115-
class CameraUpdate {
116-
const CameraUpdate._(this._json);
145+
abstract class CameraUpdate {
146+
const CameraUpdate._(this.updateType);
147+
148+
/// Indicates which type of camera update this instance represents.
149+
final CameraUpdateType updateType;
117150

118151
/// Returns a camera update that moves the camera to the specified position.
119152
static CameraUpdate newCameraPosition(CameraPosition cameraPosition) {
120-
return CameraUpdate._(
121-
<Object>['newCameraPosition', cameraPosition.toMap()],
122-
);
153+
return CameraUpdateNewCameraPosition(cameraPosition);
123154
}
124155

125156
/// Returns a camera update that moves the camera target to the specified
126157
/// geographical location.
127158
static CameraUpdate newLatLng(LatLng latLng) {
128-
return CameraUpdate._(<Object>['newLatLng', latLng.toJson()]);
159+
return CameraUpdateNewLatLng(latLng);
129160
}
130161

131162
/// Returns a camera update that transforms the camera so that the specified
132163
/// geographical bounding box is centered in the map view at the greatest
133164
/// possible zoom level. A non-zero [padding] insets the bounding box from the
134165
/// map view's edges. The camera's new tilt and bearing will both be 0.0.
135166
static CameraUpdate newLatLngBounds(LatLngBounds bounds, double padding) {
136-
return CameraUpdate._(<Object>[
137-
'newLatLngBounds',
138-
bounds.toJson(),
139-
padding,
140-
]);
167+
return CameraUpdateNewLatLngBounds(bounds, padding);
141168
}
142169

143170
/// Returns a camera update that moves the camera target to the specified
144171
/// geographical location and zoom level.
145172
static CameraUpdate newLatLngZoom(LatLng latLng, double zoom) {
146-
return CameraUpdate._(
147-
<Object>['newLatLngZoom', latLng.toJson(), zoom],
148-
);
173+
return CameraUpdateNewLatLngZoom(latLng, zoom);
149174
}
150175

151176
/// Returns a camera update that moves the camera target the specified screen
@@ -155,49 +180,154 @@ class CameraUpdate {
155180
/// the camera's target to a geographical location that is 50 to the east and
156181
/// 75 to the south of the current location, measured in screen coordinates.
157182
static CameraUpdate scrollBy(double dx, double dy) {
158-
return CameraUpdate._(
159-
<Object>['scrollBy', dx, dy],
160-
);
183+
return CameraUpdateScrollBy(dx, dy);
161184
}
162185

163186
/// Returns a camera update that modifies the camera zoom level by the
164187
/// specified amount. The optional [focus] is a screen point whose underlying
165188
/// geographical location should be invariant, if possible, by the movement.
166189
static CameraUpdate zoomBy(double amount, [Offset? focus]) {
167-
if (focus == null) {
168-
return CameraUpdate._(<Object>['zoomBy', amount]);
169-
} else {
170-
return CameraUpdate._(<Object>[
171-
'zoomBy',
172-
amount,
173-
<double>[focus.dx, focus.dy],
174-
]);
175-
}
190+
return CameraUpdateZoomBy(amount, focus);
176191
}
177192

178193
/// Returns a camera update that zooms the camera in, bringing the camera
179194
/// closer to the surface of the Earth.
180195
///
181196
/// Equivalent to the result of calling `zoomBy(1.0)`.
182197
static CameraUpdate zoomIn() {
183-
return const CameraUpdate._(<Object>['zoomIn']);
198+
return const CameraUpdateZoomIn();
184199
}
185200

186201
/// Returns a camera update that zooms the camera out, bringing the camera
187202
/// further away from the surface of the Earth.
188203
///
189204
/// Equivalent to the result of calling `zoomBy(-1.0)`.
190205
static CameraUpdate zoomOut() {
191-
return const CameraUpdate._(<Object>['zoomOut']);
206+
return const CameraUpdateZoomOut();
192207
}
193208

194209
/// Returns a camera update that sets the camera zoom level.
195210
static CameraUpdate zoomTo(double zoom) {
196-
return CameraUpdate._(<Object>['zoomTo', zoom]);
211+
return CameraUpdateZoomTo(zoom);
197212
}
198213

199-
final Object _json;
200-
201214
/// Converts this object to something serializable in JSON.
202-
Object toJson() => _json;
215+
Object toJson();
216+
}
217+
218+
/// Defines a camera move to a new position.
219+
class CameraUpdateNewCameraPosition extends CameraUpdate {
220+
/// Creates a camera move.
221+
const CameraUpdateNewCameraPosition(this.cameraPosition)
222+
: super._(CameraUpdateType.newCameraPosition);
223+
224+
/// The new camera position.
225+
final CameraPosition cameraPosition;
226+
@override
227+
Object toJson() => <Object>['newCameraPosition', cameraPosition.toMap()];
228+
}
229+
230+
/// Defines a camera move to a latitude and longitude.
231+
class CameraUpdateNewLatLng extends CameraUpdate {
232+
/// Creates a camera move to latitude and longitude.
233+
const CameraUpdateNewLatLng(this.latLng)
234+
: super._(CameraUpdateType.newLatLng);
235+
236+
/// New latitude and longitude of the camera..
237+
final LatLng latLng;
238+
@override
239+
Object toJson() => <Object>['newLatLng', latLng.toJson()];
240+
}
241+
242+
/// Defines a camera move to a new bounding latitude and longitude range.
243+
class CameraUpdateNewLatLngBounds extends CameraUpdate {
244+
/// Creates a camera move to a bounding range.
245+
const CameraUpdateNewLatLngBounds(this.bounds, this.padding)
246+
: super._(CameraUpdateType.newLatLngBounds);
247+
248+
/// The northeast and southwest bounding coordinates.
249+
final LatLngBounds bounds;
250+
251+
/// The amount of padding by which the view is inset.
252+
final double padding;
253+
@override
254+
Object toJson() => <Object>['newLatLngZoom', bounds.toJson(), padding];
255+
}
256+
257+
/// Defines a camera move to new coordinates with a zoom level.
258+
class CameraUpdateNewLatLngZoom extends CameraUpdate {
259+
/// Creates a camera move with coordinates and zoom level.
260+
const CameraUpdateNewLatLngZoom(this.latLng, this.zoom)
261+
: super._(CameraUpdateType.newLatLngZoom);
262+
263+
/// New coordinates of the camera.
264+
final LatLng latLng;
265+
266+
/// New zoom level of the camera.
267+
final double zoom;
268+
@override
269+
Object toJson() => <Object>['newLatLngZoom', latLng.toJson(), zoom];
270+
}
271+
272+
/// Defines a camera scroll by a certain delta.
273+
class CameraUpdateScrollBy extends CameraUpdate {
274+
/// Creates a camera scroll.
275+
const CameraUpdateScrollBy(this.dx, this.dy)
276+
: super._(CameraUpdateType.scrollBy);
277+
278+
/// Scroll delta x.
279+
final double dx;
280+
281+
/// Scroll delta y.
282+
final double dy;
283+
@override
284+
Object toJson() => <Object>['scrollBy', dx, dy];
285+
}
286+
287+
/// Defines a relative camera zoom.
288+
class CameraUpdateZoomBy extends CameraUpdate {
289+
/// Creates a relative camera zoom.
290+
const CameraUpdateZoomBy(this.amount, [this.focus])
291+
: super._(CameraUpdateType.zoomBy);
292+
293+
/// Change in camera zoom amount.
294+
final double amount;
295+
296+
/// Optional point around which the zoom is focused.
297+
final Offset? focus;
298+
@override
299+
Object toJson() => (focus == null)
300+
? <Object>['zoomBy', amount]
301+
: <Object>[
302+
'zoomBy',
303+
amount,
304+
<double>[focus!.dx, focus!.dy]
305+
];
306+
}
307+
308+
/// Defines a camera zoom in.
309+
class CameraUpdateZoomIn extends CameraUpdate {
310+
/// Zooms in the camera.
311+
const CameraUpdateZoomIn() : super._(CameraUpdateType.zoomIn);
312+
@override
313+
Object toJson() => <Object>['zoomIn'];
314+
}
315+
316+
/// Defines a camera zoom out.
317+
class CameraUpdateZoomOut extends CameraUpdate {
318+
/// Zooms out the camera.
319+
const CameraUpdateZoomOut() : super._(CameraUpdateType.zoomOut);
320+
@override
321+
Object toJson() => <Object>['zoomOut'];
322+
}
323+
324+
/// Defines a camera zoom to an absolute zoom.
325+
class CameraUpdateZoomTo extends CameraUpdate {
326+
/// Creates a zoom to an absolute zoom level.
327+
const CameraUpdateZoomTo(this.zoom) : super._(CameraUpdateType.zoomTo);
328+
329+
/// New zoom level of the camera.
330+
final double zoom;
331+
@override
332+
Object toJson() => <Object>['zoomTo', zoom];
203333
}

packages/google_maps_flutter/google_maps_flutter_platform_interface/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ repository: https://github.com/flutter/packages/tree/main/packages/google_maps_f
44
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+maps%22
55
# NOTE: We strongly prefer non-breaking changes, even at the expense of a
66
# less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes
7-
version: 2.9.0
7+
version: 2.9.1
88

99
environment:
1010
sdk: ^3.3.0

packages/google_maps_flutter/google_maps_flutter_platform_interface/test/types/camera_test.dart

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,82 @@ void main() {
2020

2121
expect(cameraPosition, cameraPositionFromJson);
2222
});
23+
24+
test('CameraUpdate.newCameraPosition', () {
25+
const CameraPosition cameraPosition = CameraPosition(
26+
target: LatLng(10.0, 15.0), bearing: 0.5, tilt: 30.0, zoom: 1.5);
27+
final CameraUpdate cameraUpdate =
28+
CameraUpdate.newCameraPosition(cameraPosition);
29+
expect(cameraUpdate.runtimeType, CameraUpdateNewCameraPosition);
30+
expect(cameraUpdate.updateType, CameraUpdateType.newCameraPosition);
31+
cameraUpdate as CameraUpdateNewCameraPosition;
32+
expect(cameraUpdate.cameraPosition, cameraPosition);
33+
});
34+
35+
test('CameraUpdate.newLatLng', () {
36+
const LatLng latLng = LatLng(1.0, 2.0);
37+
final CameraUpdate cameraUpdate = CameraUpdate.newLatLng(latLng);
38+
expect(cameraUpdate.runtimeType, CameraUpdateNewLatLng);
39+
expect(cameraUpdate.updateType, CameraUpdateType.newLatLng);
40+
cameraUpdate as CameraUpdateNewLatLng;
41+
expect(cameraUpdate.latLng, latLng);
42+
});
43+
44+
test('CameraUpdate.newLatLngBounds', () {
45+
final LatLngBounds latLngBounds = LatLngBounds(
46+
northeast: const LatLng(1.0, 2.0), southwest: const LatLng(-2.0, -3.0));
47+
const double padding = 1.0;
48+
final CameraUpdate cameraUpdate =
49+
CameraUpdate.newLatLngBounds(latLngBounds, padding);
50+
expect(cameraUpdate.runtimeType, CameraUpdateNewLatLngBounds);
51+
expect(cameraUpdate.updateType, CameraUpdateType.newLatLngBounds);
52+
cameraUpdate as CameraUpdateNewLatLngBounds;
53+
expect(cameraUpdate.bounds, latLngBounds);
54+
expect(cameraUpdate.padding, padding);
55+
});
56+
57+
test('CameraUpdate.newLatLngZoom', () {
58+
const LatLng latLng = LatLng(1.0, 2.0);
59+
const double zoom = 2.0;
60+
final CameraUpdate cameraUpdate = CameraUpdate.newLatLngZoom(latLng, zoom);
61+
expect(cameraUpdate.runtimeType, CameraUpdateNewLatLngZoom);
62+
expect(cameraUpdate.updateType, CameraUpdateType.newLatLngZoom);
63+
cameraUpdate as CameraUpdateNewLatLngZoom;
64+
expect(cameraUpdate.latLng, latLng);
65+
expect(cameraUpdate.zoom, zoom);
66+
});
67+
68+
test('CameraUpdate.scrollBy', () {
69+
const double dx = 2.0;
70+
const double dy = 5.0;
71+
final CameraUpdate cameraUpdate = CameraUpdate.scrollBy(dx, dy);
72+
expect(cameraUpdate.runtimeType, CameraUpdateScrollBy);
73+
expect(cameraUpdate.updateType, CameraUpdateType.scrollBy);
74+
cameraUpdate as CameraUpdateScrollBy;
75+
expect(cameraUpdate.dx, dx);
76+
expect(cameraUpdate.dy, dy);
77+
});
78+
79+
test('CameraUpdate.zoomBy', () {
80+
const double amount = 1.5;
81+
const Offset focus = Offset(-1.0, -2.0);
82+
final CameraUpdate cameraUpdate = CameraUpdate.zoomBy(amount, focus);
83+
expect(cameraUpdate.runtimeType, CameraUpdateZoomBy);
84+
expect(cameraUpdate.updateType, CameraUpdateType.zoomBy);
85+
cameraUpdate as CameraUpdateZoomBy;
86+
expect(cameraUpdate.amount, amount);
87+
expect(cameraUpdate.focus, focus);
88+
});
89+
90+
test('CameraUpdate.zoomIn', () {
91+
final CameraUpdate cameraUpdate = CameraUpdate.zoomIn();
92+
expect(cameraUpdate.runtimeType, CameraUpdateZoomIn);
93+
expect(cameraUpdate.updateType, CameraUpdateType.zoomIn);
94+
});
95+
96+
test('CameraUpdate.zoomOut', () {
97+
final CameraUpdate cameraUpdate = CameraUpdate.zoomOut();
98+
expect(cameraUpdate.runtimeType, CameraUpdateZoomOut);
99+
expect(cameraUpdate.updateType, CameraUpdateType.zoomOut);
100+
});
23101
}

0 commit comments

Comments
 (0)