Skip to content

Commit

Permalink
[google_maps_flutter_platform_interface] Convert PatternItem and `C…
Browse files Browse the repository at this point in the history
…ap` to typesafe structures. (#7703)

Convert `PatternItem` and `Cap` from JSON wrappers to typesafe classes.

flutter/flutter#155121

## 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
  • Loading branch information
yaakovschectman authored Oct 4, 2024
1 parent 05bf1d4 commit 6ec1b43
Show file tree
Hide file tree
Showing 6 changed files with 190 additions and 14 deletions.
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 2.9.4

* Converts `PatternItem` to typesafe structure.
* Converts `Cap` to typesafe structure.

## 2.9.3

* Corrects an incorrect comment in polyline.dart file.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,56 @@ import 'package:flutter/foundation.dart' show immutable;

import 'types.dart';

/// Enumeration of possible types of caps.
enum CapType {
/// Cap that is squared off exactly at the start or end vertex of a [Polyline]
/// with solid stroke pattern, equivalent to having no additional cap beyond
/// the start or end vertex.
butt,

/// Cap that is a semicircle with radius equal to half the stroke width,
/// centered at the start or end vertex of a [Polyline] with solid stroke
/// pattern.
round,

/// Cap that is squared off after extending half the stroke width beyond the
/// start or end vertex of a [Polyline] with solid stroke pattern.
square,

/// CustomCap with a bitmap overlay centered at the start or
/// end vertex of a [Polyline], orientated according to the direction of the line's
/// first or last edge and scaled with respect to the line's stroke width.
custom,
}

String _capTypeToJson(CapType capType) => switch (capType) {
CapType.butt => 'buttCap',
CapType.round => 'roundCap',
CapType.square => 'squareCap',
CapType.custom => 'customCap',
};

/// Cap that can be applied at the start or end vertex of a [Polyline].
@immutable
class Cap {
const Cap._(this._json);
const Cap._(this.type);

/// Cap that is squared off exactly at the start or end vertex of a [Polyline]
/// with solid stroke pattern, equivalent to having no additional cap beyond
/// the start or end vertex.
///
/// This is the default cap type at start and end vertices of Polylines with
/// solid stroke pattern.
static const Cap buttCap = Cap._(<Object>['buttCap']);
static const Cap buttCap = Cap._(CapType.butt);

/// Cap that is a semicircle with radius equal to half the stroke width,
/// centered at the start or end vertex of a [Polyline] with solid stroke
/// pattern.
static const Cap roundCap = Cap._(<Object>['roundCap']);
static const Cap roundCap = Cap._(CapType.round);

/// Cap that is squared off after extending half the stroke width beyond the
/// start or end vertex of a [Polyline] with solid stroke pattern.
static const Cap squareCap = Cap._(<Object>['squareCap']);
static const Cap squareCap = Cap._(CapType.square);

/// Constructs a new CustomCap with a bitmap overlay centered at the start or
/// end vertex of a [Polyline], orientated according to the direction of the line's
Expand All @@ -44,11 +73,37 @@ class Cap {
double refWidth = 10,
}) {
assert(refWidth > 0.0);
return Cap._(<Object>['customCap', bitmapDescriptor.toJson(), refWidth]);
return CustomCap(bitmapDescriptor, refWidth: refWidth);
}

final Object _json;
/// The type of rendering used for the cap at a start or end vertex of a
/// [Polyline].
final CapType type;

/// Converts this object to something serializable in JSON.
Object toJson() => _json;
Object toJson() => <Object>[_capTypeToJson(type)];
}

/// CustomCap with a bitmap overlay centered at the start or
/// end vertex of a [Polyline], orientated according to the direction of the line's
/// first or last edge and scaled with respect to the line's stroke width.
class CustomCap extends Cap {
/// [bitmapDescriptor] must not be null.
///
/// [refWidth] is the reference stroke width (in pixels) - the stroke width for which
/// the cap bitmap at its native dimension is designed. Must be positive. Default value
/// is 10 pixels.
const CustomCap(this.bitmapDescriptor, {this.refWidth = 10})
: super._(CapType.custom);

/// Bitmap overlay centered at the start or end vertex of a [Polyline].
final BitmapDescriptor bitmapDescriptor;

/// Reference stroke width in screen pixels. See
/// https://developers.google.com/maps/documentation/android-sdk/reference/com/google/android/libraries/maps/model/CustomCap#refWidth
final double refWidth;

@override
Object toJson() =>
<Object>[_capTypeToJson(type), bitmapDescriptor.toJson(), refWidth];
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,73 @@

import 'package:flutter/foundation.dart' show immutable;

/// Enumeration of types of pattern items.
enum PatternItemType {
/// A dot used in the stroke pattern for a [Polyline].
dot,

/// A dash used in the stroke pattern for a [Polyline].
dash,

/// A gap used in the stroke pattern for a [Polyline].
gap,
}

String _patternItemTypeToJson(PatternItemType itemType) => switch (itemType) {
PatternItemType.dot => 'dot',
PatternItemType.dash => 'dash',
PatternItemType.gap => 'gap',
};

/// Item used in the stroke pattern for a Polyline.
@immutable
class PatternItem {
const PatternItem._(this._json);
const PatternItem._(this.type);

/// A dot used in the stroke pattern for a [Polyline].
static const PatternItem dot = PatternItem._(<Object>['dot']);
static const PatternItem dot = PatternItem._(PatternItemType.dot);

/// A dash used in the stroke pattern for a [Polyline].
///
/// [length] has to be non-negative.
static PatternItem dash(double length) {
assert(length >= 0.0);
return PatternItem._(<Object>['dash', length]);
return VariableLengthPatternItem._(
patternItemType: PatternItemType.dash, length: length);
}

/// A gap used in the stroke pattern for a [Polyline].
///
/// [length] has to be non-negative.
static PatternItem gap(double length) {
assert(length >= 0.0);
return PatternItem._(<Object>['gap', length]);
return VariableLengthPatternItem._(
patternItemType: PatternItemType.gap, length: length);
}

final Object _json;
/// The type of rendering used for an item in a pattern.
final PatternItemType type;

/// Converts this object to something serializable in JSON.
Object toJson() => <Object>[
_patternItemTypeToJson(type),
];
}

/// A pattern item with a length, i.e. a dash or gap.
@immutable
class VariableLengthPatternItem extends PatternItem {
const VariableLengthPatternItem._(
{required PatternItemType patternItemType, required this.length})
: super._(patternItemType);

/// The length in pixels of a dash or gap.
final double length;

/// Converts this object to something serializable in JSON.
Object toJson() => _json;
@override
Object toJson() => <Object>[
_patternItemTypeToJson(type),
length,
];
}
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.9.3
version: 2.9.4

environment:
sdk: ^3.3.0
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// 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.

import 'package:flutter_test/flutter_test.dart';
import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart';

void main() {
TestWidgetsFlutterBinding.ensureInitialized();

test('buttCap', () {
const Cap cap = Cap.buttCap;
expect(cap.toJson(), equals(<Object>['buttCap']));
});

test('roundCap', () {
const Cap cap = Cap.roundCap;
expect(cap.toJson(), equals(<Object>['roundCap']));
});

test('squareCap', () {
const Cap cap = Cap.squareCap;
expect(cap.toJson(), equals(<Object>['squareCap']));
});

test('customCap', () {
final Cap cap = Cap.customCapFromBitmap(BitmapDescriptor.defaultMarker);
expect(
cap.toJson(),
equals(<Object>[
'customCap',
<Object>['defaultMarker'],
10.0
]));
});

test('customCapWithWidth', () {
final Cap cap =
Cap.customCapFromBitmap(BitmapDescriptor.defaultMarker, refWidth: 100);
expect(
cap.toJson(),
equals(<Object>[
'customCap',
<Object>['defaultMarker'],
100.0
]));
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// 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.

import 'package:flutter_test/flutter_test.dart';
import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart';

void main() {
TestWidgetsFlutterBinding.ensureInitialized();

test('dot', () {
const PatternItem item = PatternItem.dot;
expect(item.toJson(), equals(<Object>['dot']));
});

test('dash', () {
final PatternItem item = PatternItem.dash(10.0);
expect(item, isA<VariableLengthPatternItem>());
expect(item.toJson(), equals(<Object>['dash', 10.0]));
});

test('gap', () {
final PatternItem item = PatternItem.gap(20.0);
expect(item, isA<VariableLengthPatternItem>());
expect(item.toJson(), equals(<Object>['gap', 20.0]));
});
}

0 comments on commit 6ec1b43

Please sign in to comment.