Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
## NEXT
## 2.16.0

* Adds `editable` property and `onEdited` callback to `Polyline` and `Polygon`.
* Adds `PolylineEditEvent` and `PolygonEditEvent` event types.
* Adds `onPolylineEdited` and `onPolygonEdited` streams to platform interface.
* Updates minimum supported SDK version to Flutter 3.38/Dart 3.10.

## 2.15.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,18 @@ class PolylineTapEvent extends MapEvent<PolylineId> {
PolylineTapEvent(super.mapId, super.polylineId);
}

/// An event fired when a [Polyline] path is edited by the user.
class PolylineEditEvent extends MapEvent<PolylineId> {
/// Build a PolylineEdit Event triggered from the map represented by `mapId`.
///
/// The `value` of this event is a [PolylineId] object that represents the edited Polyline.
/// [points] contains the updated path after the edit.
PolylineEditEvent(super.mapId, super.polylineId, this.points);

/// The updated list of points after the edit.
final List<LatLng> points;
}

/// An event fired when a [Polygon] is tapped.
class PolygonTapEvent extends MapEvent<PolygonId> {
/// Build an PolygonTap Event triggered from the map represented by `mapId`.
Expand All @@ -144,6 +156,22 @@ class PolygonTapEvent extends MapEvent<PolygonId> {
PolygonTapEvent(super.mapId, super.polygonId);
}

/// An event fired when a [Polygon] path is edited by the user.
class PolygonEditEvent extends MapEvent<PolygonId> {
/// Build a PolygonEdit Event triggered from the map represented by `mapId`.
///
/// The `value` of this event is a [PolygonId] object that represents the edited Polygon.
/// [points] contains the updated outer boundary after the edit.
/// [holes] contains the updated holes after the edit.
PolygonEditEvent(super.mapId, super.polygonId, this.points, this.holes);

/// The updated outer boundary points after the edit.
final List<LatLng> points;

/// The updated list of holes after the edit.
final List<List<LatLng>> holes;
}

/// An event fired when a [Circle] is tapped.
class CircleTapEvent extends MapEvent<CircleId> {
/// Build an CircleTap Event triggered from the map represented by `mapId`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -327,11 +327,21 @@ abstract class GoogleMapsFlutterPlatform extends PlatformInterface {
throw UnimplementedError('onPolylineTap() has not been implemented.');
}

/// A [Polyline] path has been edited by the user. Currently only supported on web.
Stream<PolylineEditEvent> onPolylineEdited({required int mapId}) {
throw UnimplementedError('onPolylineEdited() has not been implemented.');
}

/// A [Polygon] has been tapped.
Stream<PolygonTapEvent> onPolygonTap({required int mapId}) {
throw UnimplementedError('onPolygonTap() has not been implemented.');
}

/// A [Polygon] path has been edited by the user. Currently only supported on web.
Stream<PolygonEditEvent> onPolygonEdited({required int mapId}) {
throw UnimplementedError('onPolygonEdited() has not been implemented.');
}

/// A [Circle] has been tapped.
Stream<CircleTapEvent> onCircleTap({required int mapId}) {
throw UnimplementedError('onCircleTap() has not been implemented.');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ class Polygon implements MapsObject<Polygon> {
this.visible = true,
this.zIndex = 0,
this.onTap,
this.editable = false,
this.onEdited,
});

/// Uniquely identifies a [Polygon].
Expand Down Expand Up @@ -92,6 +94,19 @@ class Polygon implements MapsObject<Polygon> {
/// Callbacks to receive tap events for polygon placed on this map.
final VoidCallback? onTap;

/// True if the user can edit this polygon by dragging its vertices.
///
/// When true, the polygon renders with draggable vertex handles.
/// Currently only supported on web.
final bool editable;

/// Called when the user edits the polygon path by dragging vertices.
///
/// The callback receives the updated outer boundary [points] and the
/// updated list of [holes]. Only fires when [editable] is true.
/// Currently only supported on web.
final void Function(List<LatLng> points, List<List<LatLng>> holes)? onEdited;

/// Creates a new [Polygon] object whose values are the same as this instance,
/// unless overwritten by the specified parameters.
Polygon copyWith({
Expand All @@ -105,6 +120,8 @@ class Polygon implements MapsObject<Polygon> {
bool? visibleParam,
int? zIndexParam,
VoidCallback? onTapParam,
bool? editableParam,
void Function(List<LatLng> points, List<List<LatLng>> holes)? onEditedParam,
}) {
return Polygon(
polygonId: polygonId,
Expand All @@ -118,6 +135,8 @@ class Polygon implements MapsObject<Polygon> {
visible: visibleParam ?? visible,
onTap: onTapParam ?? onTap,
zIndex: zIndexParam ?? zIndex,
editable: editableParam ?? editable,
onEdited: onEditedParam ?? onEdited,
);
}

Expand Down Expand Up @@ -146,6 +165,7 @@ class Polygon implements MapsObject<Polygon> {
addIfPresent('strokeWidth', strokeWidth);
addIfPresent('visible', visible);
addIfPresent('zIndex', zIndex);
addIfPresent('editable', editable);

json['points'] = _pointsToJson();

Expand All @@ -172,7 +192,8 @@ class Polygon implements MapsObject<Polygon> {
visible == other.visible &&
strokeColor == other.strokeColor &&
strokeWidth == other.strokeWidth &&
zIndex == other.zIndex;
zIndex == other.zIndex &&
editable == other.editable;
}

@override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ class Polyline implements MapsObject<Polyline> {
this.width = 10,
this.zIndex = 0,
this.onTap,
this.editable = false,
this.onEdited,
});

/// Uniquely identifies a [Polyline].
Expand Down Expand Up @@ -114,6 +116,18 @@ class Polyline implements MapsObject<Polyline> {
/// Callbacks to receive tap events for polyline placed on this map.
final VoidCallback? onTap;

/// True if the user can edit this polyline by dragging its vertices.
///
/// When true, the polyline renders with draggable vertex handles.
/// Currently only supported on web.
final bool editable;

/// Called when the user edits the polyline path by dragging vertices.
///
/// The callback receives the updated list of [LatLng] points.
/// Only fires when [editable] is true. Currently only supported on web.
final void Function(List<LatLng> points)? onEdited;

/// Creates a new [Polyline] object whose values are the same as this instance,
/// unless overwritten by the specified parameters.
Polyline copyWith({
Expand All @@ -129,6 +143,8 @@ class Polyline implements MapsObject<Polyline> {
int? widthParam,
int? zIndexParam,
VoidCallback? onTapParam,
bool? editableParam,
void Function(List<LatLng> points)? onEditedParam,
}) {
return Polyline(
polylineId: polylineId,
Expand All @@ -144,6 +160,8 @@ class Polyline implements MapsObject<Polyline> {
width: widthParam ?? width,
onTap: onTapParam ?? onTap,
zIndex: zIndexParam ?? zIndex,
editable: editableParam ?? editable,
onEdited: onEditedParam ?? onEdited,
);
}

Expand Down Expand Up @@ -178,6 +196,7 @@ class Polyline implements MapsObject<Polyline> {
addIfPresent('visible', visible);
addIfPresent('width', width);
addIfPresent('zIndex', zIndex);
addIfPresent('editable', editable);

json['points'] = _pointsToJson();

Expand Down Expand Up @@ -206,7 +225,8 @@ class Polyline implements MapsObject<Polyline> {
endCap == other.endCap &&
visible == other.visible &&
width == other.width &&
zIndex == other.zIndex;
zIndex == other.zIndex &&
editable == other.editable;
}

@override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.15.0
version: 2.16.0

environment:
sdk: ^3.10.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,20 @@ void main() {
);
});

test('onPolylineEdited() throws UnimplementedError', () {
expect(
() => BuildViewGoogleMapsFlutterPlatform().onPolylineEdited(mapId: 0),
throwsUnimplementedError,
);
});

test('onPolygonEdited() throws UnimplementedError', () {
expect(
() => BuildViewGoogleMapsFlutterPlatform().onPolygonEdited(mapId: 0),
throwsUnimplementedError,
);
});

test('default implementation of `getStyleError` returns null', () async {
final GoogleMapsFlutterPlatform platform = BuildViewGoogleMapsFlutterPlatform();
expect(await platform.getStyleError(mapId: 0), null);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
// Copyright 2013 The Flutter Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:flutter/material.dart' show Colors;
import 'package:flutter_test/flutter_test.dart';
import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart';

void main() {
TestWidgetsFlutterBinding.ensureInitialized();

group('$Polygon', () {
test('constructor defaults', () {
const polygon = Polygon(polygonId: PolygonId('ABC123'));

expect(polygon.consumeTapEvents, equals(false));
expect(polygon.fillColor, equals(Colors.black));
expect(polygon.geodesic, equals(false));
expect(polygon.visible, equals(true));
expect(polygon.strokeWidth, equals(10));
expect(polygon.zIndex, equals(0));
expect(polygon.points, equals(const <LatLng>[]));
expect(polygon.holes, equals(const <List<LatLng>>[]));
expect(polygon.onTap, isNull);
expect(polygon.editable, equals(false));
expect(polygon.onEdited, isNull);
});

test('construct with editable', () {
const polygon = Polygon(polygonId: PolygonId('ABC123'), editable: true);

expect(polygon.editable, equals(true));
});

test('toJson includes editable', () {
const polygon = Polygon(polygonId: PolygonId('ABC123'), editable: true);

final json = polygon.toJson() as Map<String, Object>;
expect(json['editable'], equals(true));
});

test('clone', () {
const polygon = Polygon(polygonId: PolygonId('ABC123'), editable: true);
final Polygon clone = polygon.clone();

expect(identical(clone, polygon), isFalse);
expect(clone, equals(polygon));
expect(clone.editable, equals(true));
});

test('copyWith editable', () {
const polygon = Polygon(polygonId: PolygonId('ABC123'));
final Polygon copy = polygon.copyWith(editableParam: true);

expect(copy.polygonId, equals(const PolygonId('ABC123')));
expect(copy.editable, equals(true));
});

test('copyWith onEdited', () {
const polygon = Polygon(polygonId: PolygonId('ABC123'));
final log = <String>[];
final Polygon copy = polygon.copyWith(
onEditedParam: (List<LatLng> points, List<List<LatLng>> holes) {
log.add('onEdited');
},
);

copy.onEdited!(<LatLng>[const LatLng(1.0, 2.0)], <List<LatLng>>[]);
expect(log, contains('onEdited'));
});

test('onEdited callback receives holes', () {
List<LatLng>? receivedPoints;
List<List<LatLng>>? receivedHoles;
final polygon = Polygon(
polygonId: const PolygonId('ABC123'),
editable: true,
onEdited: (List<LatLng> points, List<List<LatLng>> holes) {
receivedPoints = points;
receivedHoles = holes;
},
);

final testPoints = <LatLng>[const LatLng(0, 0), const LatLng(1, 1), const LatLng(0, 1)];
final testHoles = <List<LatLng>>[
<LatLng>[const LatLng(0.2, 0.2), const LatLng(0.4, 0.4), const LatLng(0.2, 0.4)],
];

polygon.onEdited!(testPoints, testHoles);

expect(receivedPoints, equals(testPoints));
expect(receivedHoles, equals(testHoles));
});

test('equality includes editable', () {
const p1 = Polygon(polygonId: PolygonId('ABC123'));
const p2 = Polygon(polygonId: PolygonId('ABC123'), editable: true);

expect(p1, isNot(equals(p2)));
});

test('equality ignores onEdited', () {
final p1 = Polygon(
polygonId: const PolygonId('ABC123'),
editable: true,
onEdited: (List<LatLng> points, List<List<LatLng>> holes) {},
);
final p2 = Polygon(
polygonId: const PolygonId('ABC123'),
editable: true,
onEdited: (List<LatLng> points, List<List<LatLng>> holes) {},
);

expect(p1, equals(p2));
});
});
}
Loading