From 639fc1de412da3e6de59672c3357b136fa51dfbf Mon Sep 17 00:00:00 2001 From: Andrea Valenzano Date: Tue, 11 Feb 2020 16:59:44 +0100 Subject: [PATCH] refactoring --- README.md | 2 + example/data_driven_circle_colors/index.dart | 10 +- example/drag_a_marker/index.dart | 3 +- example/popup_on_click/index.dart | 21 +- example/popup_on_click/index.html | 5 + example/popup_on_hover/index.dart | 253 ++-- example/popup_on_hover/index.html | 5 + lib/mapbox_gl_dart.dart | 4 +- lib/src/geo/geojson.dart | 64 + lib/src/geo/lng_lat.dart | 33 +- lib/src/geo/lng_lat_bounds.dart | 60 +- lib/src/interop/geo/geojson_interop.dart | 42 + .../interop/geo/lng_lat_bounds_interop.dart | 140 ++ lib/src/interop/geo/lng_lat_interop.dart | 79 + lib/src/interop/geojson_interop.dart | 36 - lib/src/interop/interop.dart | 27 + lib/src/interop/js.dart | 17 + .../style/evaluation_parameters_interop.dart | 21 + .../style/layers/circle_layer_interop.dart | 36 + .../style/layers/line_layer_interop.dart | 71 + .../style/layers/symbol_layer_interop.dart | 154 ++ .../style/sources/geojson_source_interop.dart | 15 + .../style/sources/vector_source_interop.dart | 16 + .../interop/style/style_image_interop.dart | 27 + lib/src/interop/style/style_interop.dart | 146 ++ lib/src/interop/ui/camera_interop.dart | 480 +++++++ lib/src/interop/ui/events_interop.dart | 77 + .../interop/ui/handler/box_zoom_interop.dart | 34 + .../ui/handler/dblclick_zoom_interop.dart | 35 + .../interop/ui/handler/drag_pan_interop.dart | 36 + .../ui/handler/drag_rotate_interop.dart | 34 + .../interop/ui/handler/keyboard_interop.dart | 25 + .../ui/handler/scroll_zoom_interop.dart | 49 + .../ui/handler/touch_zoom_rotate_interop.dart | 48 + lib/src/interop/ui/map_interop.dart | 1279 +++++++++++++++++ lib/src/interop/ui/marker_interop.dart | 131 ++ lib/src/interop/ui/popup_interop.dart | 195 +++ lib/src/interop/util/evented_interop.dart | 73 + lib/src/style/evaluation_parameters.dart | 30 +- lib/src/style/layers/circle_layer.dart | 43 +- lib/src/style/layers/layer.dart | 9 + lib/src/style/layers/layout.dart | 18 - lib/src/style/layers/line_layer.dart | 65 +- lib/src/style/layers/symbol_layer.dart | 116 +- lib/src/style/sources/geojson_source.dart | 93 +- lib/src/style/sources/source.dart | 11 +- lib/src/style/sources/vector_source.dart | 41 +- lib/src/style/style.dart | 134 +- lib/src/style/style_image.dart | 46 +- lib/src/ui/camera.dart | 187 ++- lib/src/ui/events.dart | 52 +- lib/src/ui/handler/box_zoom.dart | 21 +- lib/src/ui/handler/dblclick_zoom.dart | 24 +- lib/src/ui/handler/drag_pan.dart | 23 +- lib/src/ui/handler/drag_rotate.dart | 21 +- lib/src/ui/handler/keyboard.dart | 17 +- lib/src/ui/handler/scroll_zoom.dart | 28 +- lib/src/ui/handler/touch_zoom_rotate.dart | 24 +- lib/src/ui/map.dart | 416 ++++-- lib/src/ui/marker.dart | 88 +- lib/src/ui/popup.dart | 410 +++--- lib/src/util/evented.dart | 96 +- lib/src/utils.dart | 35 + 63 files changed, 4652 insertions(+), 1179 deletions(-) create mode 100644 lib/src/geo/geojson.dart create mode 100644 lib/src/interop/geo/geojson_interop.dart create mode 100644 lib/src/interop/geo/lng_lat_bounds_interop.dart create mode 100644 lib/src/interop/geo/lng_lat_interop.dart delete mode 100644 lib/src/interop/geojson_interop.dart create mode 100644 lib/src/interop/interop.dart create mode 100644 lib/src/interop/js.dart create mode 100644 lib/src/interop/style/evaluation_parameters_interop.dart create mode 100644 lib/src/interop/style/layers/circle_layer_interop.dart create mode 100644 lib/src/interop/style/layers/line_layer_interop.dart create mode 100644 lib/src/interop/style/layers/symbol_layer_interop.dart create mode 100644 lib/src/interop/style/sources/geojson_source_interop.dart create mode 100644 lib/src/interop/style/sources/vector_source_interop.dart create mode 100644 lib/src/interop/style/style_image_interop.dart create mode 100644 lib/src/interop/style/style_interop.dart create mode 100644 lib/src/interop/ui/camera_interop.dart create mode 100644 lib/src/interop/ui/events_interop.dart create mode 100644 lib/src/interop/ui/handler/box_zoom_interop.dart create mode 100644 lib/src/interop/ui/handler/dblclick_zoom_interop.dart create mode 100644 lib/src/interop/ui/handler/drag_pan_interop.dart create mode 100644 lib/src/interop/ui/handler/drag_rotate_interop.dart create mode 100644 lib/src/interop/ui/handler/keyboard_interop.dart create mode 100644 lib/src/interop/ui/handler/scroll_zoom_interop.dart create mode 100644 lib/src/interop/ui/handler/touch_zoom_rotate_interop.dart create mode 100644 lib/src/interop/ui/map_interop.dart create mode 100644 lib/src/interop/ui/marker_interop.dart create mode 100644 lib/src/interop/ui/popup_interop.dart create mode 100644 lib/src/interop/util/evented_interop.dart create mode 100644 lib/src/style/layers/layer.dart delete mode 100644 lib/src/style/layers/layout.dart create mode 100644 lib/src/utils.dart diff --git a/README.md b/README.md index 3e861cc..8cf49fc 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # Mapbox-gl wrapper for Dart +Library to use Mapbox GL JS from Dart. Working examples here: https://andrea689.github.io/mapbox-gl-dart/ + ## Using this package You must include [Mapbox GL JS](https://github.com/mapbox/mapbox-gl-js) into your `.html` file diff --git a/example/data_driven_circle_colors/index.dart b/example/data_driven_circle_colors/index.dart index 6143f96..21a6354 100644 --- a/example/data_driven_circle_colors/index.dart +++ b/example/data_driven_circle_colors/index.dart @@ -1,6 +1,3 @@ -import 'dart:js'; - -import 'package:js/js.dart'; import 'package:mapbox_gl_dart/mapbox_gl_dart.dart'; void main() { @@ -16,7 +13,7 @@ void main() { ), ); - map.on('load', allowInterop((_) { + map.on('load', (_) { /* Sample feature from the `examples.8fgz4egr` tileset: { "type": "Feature", @@ -61,7 +58,6 @@ void main() { ], ), ); - - map.addLayer(layer.toJs()); - })); + map.addLayer(layer); + }); } diff --git a/example/drag_a_marker/index.dart b/example/drag_a_marker/index.dart index 2207a4f..3c34e42 100644 --- a/example/drag_a_marker/index.dart +++ b/example/drag_a_marker/index.dart @@ -1,6 +1,5 @@ import 'dart:html'; -import 'package:js/js.dart'; import 'package:mapbox_gl_dart/mapbox_gl_dart.dart'; Marker marker; @@ -26,7 +25,7 @@ void main() { ), ).setLngLat(LngLat(0, 0)).addTo(map); - marker.on('dragend', allowInterop(onDragEnd)); + marker.on('dragend', onDragEnd); } void onDragEnd(_) { diff --git a/example/popup_on_click/index.dart b/example/popup_on_click/index.dart index e889152..78f60ce 100644 --- a/example/popup_on_click/index.dart +++ b/example/popup_on_click/index.dart @@ -1,4 +1,3 @@ -import 'package:js/js.dart'; import 'package:mapbox_gl_dart/mapbox_gl_dart.dart'; void main() { @@ -14,7 +13,7 @@ void main() { ), ); - map.on('load', allowInterop((_) { + map.on('load', (_) { // Add a layer showing the places. var layer = SymbolLayer( id: 'places', @@ -128,27 +127,27 @@ void main() { iconAllowOverlap: true, ), ); - map.addLayer(layer.toJs()); + map.addLayer(layer); // When a click event occurs on a feature in the places layer, open a popup at the // location of the feature, with description HTML from its properties. - map.on('click', 'places', allowInterop((e) { + map.on('click', 'places', (e) { var coordinates = e.features[0].geometry.coordinates; - var description = e.features[0].properties.description; + var description = e.features[0].properties['description']; Popup() .setLngLat(LngLat(coordinates[0], coordinates[1])) .setHTML(description) .addTo(map); - })); + }); // Change the cursor to a pointer when the mouse is over the places layer. - map.on('mouseenter', 'places', allowInterop((_) { + map.on('mouseenter', 'places', (_) { map.getCanvas().style.cursor = 'pointer'; - })); + }); // Change it back to a pointer when it leaves. - map.on('mouseleave', 'places', allowInterop((_) { + map.on('mouseleave', 'places', (_) { map.getCanvas().style.cursor = ''; - })); - })); + }); + }); } diff --git a/example/popup_on_click/index.html b/example/popup_on_click/index.html index c83a924..7457e92 100644 --- a/example/popup_on_click/index.html +++ b/example/popup_on_click/index.html @@ -21,6 +21,11 @@ text-align: center; font-style: italic; } + + .mapboxgl-popup { + max-width: 400px; + font: 12px/20px 'Helvetica Neue', Arial, Helvetica, sans-serif; + } diff --git a/example/popup_on_hover/index.dart b/example/popup_on_hover/index.dart index e2ee5b3..2e08edb 100644 --- a/example/popup_on_hover/index.dart +++ b/example/popup_on_hover/index.dart @@ -1,6 +1,3 @@ -import 'dart:js'; - -import 'package:js/js.dart'; import 'package:mapbox_gl_dart/mapbox_gl_dart.dart'; void main() { @@ -16,121 +13,131 @@ void main() { ), ); - map.on('load', allowInterop((_) { + map.on('load', (_) { + map.addSource('places', { + 'type': 'geojson', + 'data': { + 'type': 'FeatureCollection', + 'features': [ + { + 'type': 'Feature', + 'properties': { + 'description': + 'Make it Mount Pleasant

Make it Mount Pleasant is a handmade and vintage market and afternoon of live entertainment and kids activities. 12:00-6:00 p.m.

', + 'icon': 'theatre' + }, + 'geometry': { + 'type': 'Point', + 'coordinates': [-77.038659, 38.931567] + } + }, + { + 'type': 'Feature', + 'properties': { + 'description': + 'Mad Men Season Five Finale Watch Party

Head to Lounge 201 (201 Massachusetts Avenue NE) Sunday for a Mad Men Season Five Finale Watch Party, complete with 60s costume contest, Mad Men trivia, and retro food and drink. 8:00-11:00 p.m. \$10 general admission, \$20 admission and two hour open bar.

', + 'icon': 'theatre' + }, + 'geometry': { + 'type': 'Point', + 'coordinates': [-77.003168, 38.894651] + } + }, + { + 'type': 'Feature', + 'properties': { + 'description': + 'Big Backyard Beach Bash and Wine Fest

EatBar (2761 Washington Boulevard Arlington VA) is throwing a Big Backyard Beach Bash and Wine Fest on Saturday, serving up conch fritters, fish tacos and crab sliders, and Red Apron hot dogs. 12:00-3:00 p.m. \$25.grill hot dogs.

', + 'icon': 'bar' + }, + 'geometry': { + 'type': 'Point', + 'coordinates': [-77.090372, 38.881189] + } + }, + { + 'type': 'Feature', + 'properties': { + 'description': + 'Ballston Arts & Crafts Market

The Ballston Arts & Crafts Market sets up shop next to the Ballston metro this Saturday for the first of five dates this summer. Nearly 35 artists and crafters will be on hand selling their wares. 10:00-4:00 p.m.

', + 'icon': 'art-gallery' + }, + 'geometry': { + 'type': 'Point', + 'coordinates': [-77.111561, 38.882342] + } + }, + { + 'type': 'Feature', + 'properties': { + 'description': + "Seersucker Bike Ride and Social

Feeling dandy? Get fancy, grab your bike, and take part in this year's Seersucker Social bike ride from Dandies and Quaintrelles. After the ride enjoy a lawn party at Hillwood with jazz, cocktails, paper hat-making, and more. 11:00-7:00 p.m.

", + 'icon': 'bicycle' + }, + 'geometry': { + 'type': 'Point', + 'coordinates': [-77.052477, 38.943951] + } + }, + { + 'type': 'Feature', + 'properties': { + 'description': + 'Capital Pride Parade

The annual Capital Pride Parade makes its way through Dupont this Saturday. 4:30 p.m. Free.

', + 'icon': 'star' + }, + 'geometry': { + 'type': 'Point', + 'coordinates': [-77.043444, 38.909664] + } + }, + { + 'type': 'Feature', + 'properties': { + 'description': + 'Muhsinah

Jazz-influenced hip hop artist Muhsinah plays the Black Cat (1811 14th Street NW) tonight with Exit Clov and Gods’illa. 9:00 p.m. \$12.

', + 'icon': 'music' + }, + 'geometry': { + 'type': 'Point', + 'coordinates': [-77.031706, 38.914581] + } + }, + { + 'type': 'Feature', + 'properties': { + 'description': + "A Little Night Music

The Arlington Players' production of Stephen Sondheim's A Little Night Music comes to the Kogod Cradle at The Mead Center for American Theater (1101 6th Street SW) this weekend and next. 8:00 p.m.

", + 'icon': 'music' + }, + 'geometry': { + 'type': 'Point', + 'coordinates': [-77.020945, 38.878241] + } + }, + { + 'type': 'Feature', + 'properties': { + 'description': + 'Truckeroo

Truckeroo brings dozens of food trucks, live music, and games to half and M Street SE (across from Navy Yard Metro Station) today from 11:00 a.m. to 11:00 p.m.

', + 'icon': 'music' + }, + 'geometry': { + 'type': 'Point', + 'coordinates': [-77.007481, 38.876516] + } + } + ] + } + }); + // Add a layer showing the places. - var layer = SymbolLayer( - id: 'places', - source: GeoJsonSource( - data: FeatureCollection( - features: [ - Feature( - properties: { - 'description': - 'Make it Mount Pleasant

Make it Mount Pleasant is a handmade and vintage market and afternoon of live entertainment and kids activities. 12:00-6:00 p.m.

', - 'icon': 'theatre', - }, - geometry: Geometry( - type: 'Point', - coordinates: [-77.038659, 38.931567], - ), - ), - Feature( - properties: { - 'description': - 'Mad Men Season Five Finale Watch Party

Head to Lounge 201 (201 Massachusetts Avenue NE) Sunday for a Mad Men Season Five Finale Watch Party, complete with 60s costume contest, Mad Men trivia, and retro food and drink. 8:00-11:00 p.m. \$10 general admission, \$20 admission and two hour open bar.

', - 'icon': 'theatre', - }, - geometry: Geometry( - type: 'Point', - coordinates: [-77.003168, 38.894651], - ), - ), - Feature( - properties: { - 'description': - 'Big Backyard Beach Bash and Wine Fest

EatBar (2761 Washington Boulevard Arlington VA) is throwing a Big Backyard Beach Bash and Wine Fest on Saturday, serving up conch fritters, fish tacos and crab sliders, and Red Apron hot dogs. 12:00-3:00 p.m. \$25.grill hot dogs.

', - 'icon': 'bar', - }, - geometry: Geometry( - type: 'Point', - coordinates: [-77.090372, 38.881189], - ), - ), - Feature( - properties: { - 'description': - 'Ballston Arts & Crafts Market

The Ballston Arts & Crafts Market sets up shop next to the Ballston metro this Saturday for the first of five dates this summer. Nearly 35 artists and crafters will be on hand selling their wares. 10:00-4:00 p.m.

', - 'icon': 'art-gallery', - }, - geometry: Geometry( - type: 'Point', - coordinates: [-77.111561, 38.882342], - ), - ), - Feature( - properties: { - 'description': - 'Seersucker Bike Ride and Social

Feeling dandy? Get fancy, grab your bike, and take part in this year\'s Seersucker Social bike ride from Dandies and Quaintrelles. After the ride enjoy a lawn party at Hillwood with jazz, cocktails, paper hat-making, and more. 11:00-7:00 p.m.

', - 'icon': 'bicycle', - }, - geometry: Geometry( - type: 'Point', - coordinates: [-77.052477, 38.943951], - ), - ), - Feature( - properties: { - 'description': - 'Capital Pride Parade

The annual Capital Pride Parade makes its way through Dupont this Saturday. 4:30 p.m. Free.

', - 'icon': 'rocket', - }, - geometry: Geometry( - type: 'Point', - coordinates: [-77.043444, 38.909664], - ), - ), - Feature( - properties: { - 'description': - 'Muhsinah

Jazz-influenced hip hop artist Muhsinah plays the Black Cat (1811 14th Street NW) tonight with Exit Clov and Gods’illa. 9:00 p.m. \$12.

', - 'icon': 'music', - }, - geometry: Geometry( - type: 'Point', - coordinates: [-77.031706, 38.914581], - ), - ), - Feature( - properties: { - 'description': - 'A Little Night Music

The Arlington Players\' production of Stephen Sondheim\'s A Little Night Music comes to the Kogod Cradle at The Mead Center for American Theater (1101 6th Street SW) this weekend and next. 8:00 p.m.

', - 'icon': 'music', - }, - geometry: Geometry( - type: 'Point', - coordinates: [-77.020945, 38.878241], - ), - ), - Feature( - properties: { - 'description': - 'Truckeroo

Truckeroo brings dozens of food trucks, live music, and games to half and M Street SE (across from Navy Yard Metro Station) today from 11:00 a.m. to 11:00 p.m.

', - 'icon': 'music', - }, - geometry: Geometry( - type: 'Point', - coordinates: [-77.007481, 38.876516], - ), - ) - ], - ), - ), - layout: SymbolLayout( - iconImage: '{icon}-15', - iconAllowOverlap: true, - ), - ); - map.addLayer(layer.toJs()); + map.addLayer({ + 'id': 'places', + 'type': 'symbol', + 'source': 'places', + 'layout': {'icon-image': '{icon}-15', 'icon-allow-overlap': true} + }); // Create a popup, but don't add it to the map yet. var popup = Popup( @@ -139,12 +146,12 @@ void main() { closeOnClick: false, ), ); - map.on('mouseenter', 'places', allowInterop((e) { + map.on('mouseenter', 'places', (e) { // Change the cursor style as a UI indicator. map.getCanvas().style.cursor = 'pointer'; var coordinates = e.features[0].geometry.coordinates; - var description = e.features[0].properties.description; + var description = e.features[0].properties['description']; // Ensure that if the map is zoomed out such that multiple // copies of the feature are visible, the popup appears @@ -159,11 +166,11 @@ void main() { .setLngLat(LngLat(coordinates[0], coordinates[1])) .setHTML(description) .addTo(map); - })); + }); - map.on('mouseleave', 'places', allowInterop((_) { + map.on('mouseleave', 'places', (_) { map.getCanvas().style.cursor = ''; popup.remove(); - })); - })); + }); + }); } diff --git a/example/popup_on_hover/index.html b/example/popup_on_hover/index.html index 299081d..6e0e485 100644 --- a/example/popup_on_hover/index.html +++ b/example/popup_on_hover/index.html @@ -21,6 +21,11 @@ text-align: center; font-style: italic; } + + .mapboxgl-popup { + max-width: 400px; + font: 12px/20px 'Helvetica Neue', Arial, Helvetica, sans-serif; + } diff --git a/lib/mapbox_gl_dart.dart b/lib/mapbox_gl_dart.dart index fdf8251..799d30c 100644 --- a/lib/mapbox_gl_dart.dart +++ b/lib/mapbox_gl_dart.dart @@ -3,13 +3,13 @@ /// Project: https://github.com/mapbox/mapbox-gl-js library mapboxgl; +export 'src/geo/geojson.dart'; export 'src/geo/lng_lat.dart'; export 'src/geo/lng_lat_bounds.dart'; export 'src/index.dart'; -export 'src/interop/geojson_interop.dart'; export 'src/style/evaluation_parameters.dart'; export 'src/style/layers/circle_layer.dart'; -export 'src/style/layers/layout.dart'; +export 'src/style/layers/layer.dart'; export 'src/style/layers/line_layer.dart'; export 'src/style/layers/symbol_layer.dart'; export 'src/style/sources/geojson_source.dart'; diff --git a/lib/src/geo/geojson.dart b/lib/src/geo/geojson.dart new file mode 100644 index 0000000..52d7a1c --- /dev/null +++ b/lib/src/geo/geojson.dart @@ -0,0 +1,64 @@ +library mapboxgl.geo.geojson; + +import 'package:js/js_util.dart'; +import 'package:mapbox_gl_dart/src/interop/interop.dart'; +import 'package:mapbox_gl_dart/src/utils.dart'; + +class FeatureCollection extends JsObjectWrapper { + String get type => jsObject.type; + List get features => + jsObject.features.map((dynamic f) => Feature.fromJsObject(f)); + + factory FeatureCollection({ + List features, + }) { + return FeatureCollection.fromJsObject(FeatureCollectionJsImpl( + type: 'FeatureCollection', + features: features.map((dynamic f) => f.jsObject).toList(), + )); + } + + /// Creates a new FeatureCollection from a [jsObject]. + FeatureCollection.fromJsObject(FeatureCollectionJsImpl jsObject) + : super.fromJsObject(jsObject); +} + +class Feature extends JsObjectWrapper { + num get id => jsObject.id; + String get type => jsObject.type; + Geometry get geometry => Geometry.fromJsObject(jsObject.geometry); + Map get properties => dartifyMap(jsObject.properties); + String get source => jsObject.source; + + factory Feature({ + Geometry geometry, + Map properties, + String source, + }) => + Feature.fromJsObject(FeatureJsImpl( + type: 'Feature', + geometry: geometry.jsObject, + properties: jsify(properties), + source: source, + )); + + /// Creates a new Feature from a [jsObject]. + Feature.fromJsObject(FeatureJsImpl jsObject) : super.fromJsObject(jsObject); +} + +class Geometry extends JsObjectWrapper { + String get type => jsObject.type; + dynamic get coordinates => jsObject.coordinates; + + factory Geometry({ + String type, + dynamic coordinates, + }) => + Geometry.fromJsObject(GeometryJsImpl( + type: type, + coordinates: coordinates, + )); + + /// Creates a new Geometry from a [jsObject]. + Geometry.fromJsObject(GeometryJsImpl jsObject) : super.fromJsObject(jsObject); +} diff --git a/lib/src/geo/lng_lat.dart b/lib/src/geo/lng_lat.dart index 917fd56..a4d6d2f 100644 --- a/lib/src/geo/lng_lat.dart +++ b/lib/src/geo/lng_lat.dart @@ -1,8 +1,7 @@ -@JS('mapboxgl') library mapboxgl.geo.lng_lat; -import 'package:js/js.dart'; import 'package:mapbox_gl_dart/mapbox_gl_dart.dart'; +import 'package:mapbox_gl_dart/src/interop/interop.dart'; /// A `LngLat` object represents a given longitude and latitude coordinate, measured in degrees. /// @@ -20,15 +19,18 @@ import 'package:mapbox_gl_dart/mapbox_gl_dart.dart'; /// @see [Display a popup](https://www.mapbox.com/mapbox-gl-js/example/popup/) /// @see [Highlight features within a bounding box](https://www.mapbox.com/mapbox-gl-js/example/using-box-queryrenderedfeatures/) /// @see [Create a timeline animation](https://www.mapbox.com/mapbox-gl-js/example/timeline-animation/) -@JS() -class LngLat { - external num get lng; - external num get lat; +class LngLat extends JsObjectWrapper { + num get lng => jsObject.lng; + num get lat => jsObject.lat; - external factory LngLat( + factory LngLat( num lng, num lat, - ); + ) => + LngLat.fromJsObject(LngLatJsImpl( + lng, + lat, + )); /// Returns a new `LngLat` object whose longitude is wrapped to the range (-180, 180). /// @@ -37,7 +39,7 @@ class LngLat { /// var ll = new mapboxgl.LngLat(286.0251, 40.7736); /// var wrapped = ll.wrap(); /// wrapped.lng; // = -73.9749 - external LngLat wrap(); + LngLat wrap() => LngLat.fromJsObject(jsObject.wrap()); /// Returns the coordinates represented as an array of two numbers. /// @@ -45,7 +47,7 @@ class LngLat { /// @example /// var ll = new mapboxgl.LngLat(-73.9749, 40.7736); /// ll.toArray(); // = [-73.9749, 40.7736] - external List toArray(); + List toArray() => jsObject.toArray(); /// Returns the coordinates represent as a string. /// @@ -53,7 +55,7 @@ class LngLat { /// @example /// var ll = new mapboxgl.LngLat(-73.9749, 40.7736); /// ll.toString(); // = "LngLat(-73.9749, 40.7736)" - external String toString(); + String toString() => jsObject.toString(); /// Returns a `LngLatBounds` from the coordinates extended by a given `radius`. The returned `LngLatBounds` completely contains the `radius`. /// @@ -62,7 +64,8 @@ class LngLat { /// @example /// var ll = new mapboxgl.LngLat(-73.9749, 40.7736); /// ll.toBounds(100).toArray(); // = [[-73.97501862141328, 40.77351016847229], [-73.97478137858673, 40.77368983152771]] - external LngLatBounds toBounds(num radius); + LngLatBounds toBounds(num radius) => + LngLatBounds.fromJsObject(jsObject.toBounds(radius)); /// Converts an array of two numbers or an object with `lng` and `lat` or `lon` and `lat` properties /// to a `LngLat` object. @@ -75,5 +78,9 @@ class LngLat { /// var arr = [-73.9749, 40.7736]; /// var ll = mapboxgl.LngLat.convert(arr); /// ll; // = LngLat {lng: -73.9749, lat: 40.7736} - external static LngLat convert(dynamic input); + static LngLat convert(dynamic input) => + LngLat.fromJsObject(LngLatJsImpl.convert(input)); + + /// Creates a new LngLat from a [jsObject]. + LngLat.fromJsObject(LngLatJsImpl jsObject) : super.fromJsObject(jsObject); } diff --git a/lib/src/geo/lng_lat_bounds.dart b/lib/src/geo/lng_lat_bounds.dart index b050824..7b5919e 100644 --- a/lib/src/geo/lng_lat_bounds.dart +++ b/lib/src/geo/lng_lat_bounds.dart @@ -1,8 +1,7 @@ -@JS('mapboxgl') library mapboxgl.geo.lng_lat_bounds; -import 'package:js/js.dart'; import 'package:mapbox_gl_dart/mapbox_gl_dart.dart'; +import 'package:mapbox_gl_dart/src/interop/interop.dart'; /// A `LngLatBounds` object represents a geographical bounding box, /// defined by its southwest and northeast points in longitude and latitude. @@ -19,33 +18,39 @@ import 'package:mapbox_gl_dart/mapbox_gl_dart.dart'; /// var sw = new mapboxgl.LngLat(-73.9876, 40.7661); /// var ne = new mapboxgl.LngLat(-73.9397, 40.8002); /// var llb = new mapboxgl.LngLatBounds(sw, ne); -@JS() -class LngLatBounds { - external LngLat get sw; - external LngLat get ne; +class LngLatBounds extends JsObjectWrapper { + LngLat get sw => LngLat.fromJsObject(jsObject.sw); + LngLat get ne => LngLat.fromJsObject(jsObject.ne); - external factory LngLatBounds( + factory LngLatBounds( LngLat sw, LngLat ne, - ); + ) => + LngLatBounds.fromJsObject(LngLatBoundsJsImpl( + sw.jsObject, + ne.jsObject, + )); /// Set the northeast corner of the bounding box /// /// @param {LngLatLike} ne /// @returns {LngLatBounds} `this` - external LngLatBounds setNorthEast(LngLat ne); + LngLatBounds setNorthEast(LngLat ne) => + LngLatBounds.fromJsObject(jsObject.setNorthEast(ne.jsObject)); /// Set the southwest corner of the bounding box /// /// @param {LngLatLike} sw /// @returns {LngLatBounds} `this` - external LngLatBounds setSouthWest(LngLat sw); + LngLatBounds setSouthWest(LngLat sw) => + LngLatBounds.fromJsObject(jsObject.setSouthWest(sw.jsObject)); /// Extend the bounds to include a given LngLat or LngLatBounds. /// /// @param {LngLat|LngLatBounds} obj object to extend to /// @returns {LngLatBounds} `this` - external LngLatBounds extend(dynamic obj); + LngLatBounds extend(dynamic obj) => + LngLatBounds.fromJsObject(jsObject.extend(obj.jsObject)); /// Returns the geographical coordinate equidistant from the bounding box's corners. /// @@ -53,47 +58,47 @@ class LngLatBounds { /// @example /// var llb = new mapboxgl.LngLatBounds([-73.9876, 40.7661], [-73.9397, 40.8002]); /// llb.getCenter(); // = LngLat {lng: -73.96365, lat: 40.78315} - external LngLat getCenter(); + LngLat getCenter() => LngLat.fromJsObject(jsObject.getCenter()); /// Returns the southwest corner of the bounding box. /// /// @returns {LngLat} The southwest corner of the bounding box. - external LngLat getSouthWest(); + LngLat getSouthWest() => LngLat.fromJsObject(jsObject.getSouthWest()); /// Returns the northeast corner of the bounding box. /// /// @returns {LngLat} The northeast corner of the bounding box. - external LngLat getNorthEast(); + LngLat getNorthEast() => LngLat.fromJsObject(jsObject.getNorthEast()); /// Returns the northwest corner of the bounding box. /// /// @returns {LngLat} The northwest corner of the bounding box. - external LngLat getNorthWest(); + LngLat getNorthWest() => LngLat.fromJsObject(jsObject.getNorthWest()); /// Returns the southeast corner of the bounding box. /// /// @returns {LngLat} The southeast corner of the bounding box. - external LngLat getSouthEast(); + LngLat getSouthEast() => LngLat.fromJsObject(jsObject.getSouthEast()); /// Returns the west edge of the bounding box. /// /// @returns {number} The west edge of the bounding box. - external num getWest(); + num getWest() => jsObject.getWest(); /// Returns the south edge of the bounding box. /// /// @returns {number} The south edge of the bounding box. - external num getSouth(); + num getSouth() => jsObject.getSouth(); /// Returns the east edge of the bounding box. /// /// @returns {number} The east edge of the bounding box. - external num getEast(); + num getEast() => jsObject.getEast(); /// Returns the north edge of the bounding box. /// /// @returns {number} The north edge of the bounding box. - external num getNorth(); + num getNorth() => jsObject.getNorth(); /// Returns the bounding box represented as an array. /// @@ -102,7 +107,7 @@ class LngLatBounds { /// @example /// var llb = new mapboxgl.LngLatBounds([-73.9876, 40.7661], [-73.9397, 40.8002]); /// llb.toArray(); // = [[-73.9876, 40.7661], [-73.9397, 40.8002]] - external List> toArray(); + List> toArray() => jsObject.toArray(); /// Return the bounding box represented as a string. /// @@ -111,18 +116,18 @@ class LngLatBounds { /// @example /// var llb = new mapboxgl.LngLatBounds([-73.9876, 40.7661], [-73.9397, 40.8002]); /// llb.toString(); // = "LngLatBounds(LngLat(-73.9876, 40.7661), LngLat(-73.9397, 40.8002))" - external String toString(); + String toString() => jsObject.toString(); /// Check if the bounding box is an empty/`null`-type box. /// /// @returns {boolean} True if bounds have been defined, otherwise false. - external bool isEmpty(); + bool isEmpty() => jsObject.isEmpty(); /// Check if the point is within the bounding box. /// /// @param {LngLatLike} lnglat geographic point to check against. /// @returns {boolean} True if the point is within the bounding box. - external bool contains(LngLat lnglat); + bool contains(LngLat lnglat) => jsObject.contains(lnglat.jsObject); /// Converts an array to a `LngLatBounds` object. /// @@ -136,5 +141,10 @@ class LngLatBounds { /// var arr = [[-73.9876, 40.7661], [-73.9397, 40.8002]]; /// var llb = mapboxgl.LngLatBounds.convert(arr); /// llb; // = LngLatBounds {_sw: LngLat {lng: -73.9876, lat: 40.7661}, _ne: LngLat {lng: -73.9397, lat: 40.8002}} - external static LngLatBounds convert(dynamic input); + static LngLatBounds convert(dynamic input) => + LngLatBounds.fromJsObject(LngLatBoundsJsImpl.convert(input)); + + /// Creates a new LngLatBounds from a [jsObject]. + LngLatBounds.fromJsObject(LngLatBoundsJsImpl jsObject) + : super.fromJsObject(jsObject); } diff --git a/lib/src/interop/geo/geojson_interop.dart b/lib/src/interop/geo/geojson_interop.dart new file mode 100644 index 0000000..0db575f --- /dev/null +++ b/lib/src/interop/geo/geojson_interop.dart @@ -0,0 +1,42 @@ +@JS('mapboxgl') +library mapboxgl.interop.geo.geojson; + +import 'package:js/js.dart'; + +@JS() +@anonymous +class FeatureCollectionJsImpl { + external String get type; + external List get features; + external factory FeatureCollectionJsImpl({ + String type, + List features, + }); +} + +@JS() +@anonymous +class FeatureJsImpl { + external num get id; + external String get type; + external GeometryJsImpl get geometry; + external dynamic get properties; + external String get source; + external factory FeatureJsImpl({ + String type, + GeometryJsImpl geometry, + dynamic properties, + String source, + }); +} + +@JS() +@anonymous +class GeometryJsImpl { + external String get type; + external dynamic get coordinates; + external factory GeometryJsImpl({ + String type, + dynamic coordinates, + }); +} diff --git a/lib/src/interop/geo/lng_lat_bounds_interop.dart b/lib/src/interop/geo/lng_lat_bounds_interop.dart new file mode 100644 index 0000000..e86afd0 --- /dev/null +++ b/lib/src/interop/geo/lng_lat_bounds_interop.dart @@ -0,0 +1,140 @@ +@JS('mapboxgl') +library mapboxgl.interop.geo.lng_lat_bounds; + +import 'package:js/js.dart'; +import 'package:mapbox_gl_dart/src/interop/interop.dart'; + +/// A `LngLatBounds` object represents a geographical bounding box, +/// defined by its southwest and northeast points in longitude and latitude. +/// +/// If no arguments are provided to the constructor, a `null` bounding box is created. +/// +/// Note that any Mapbox GL method that accepts a `LngLatBounds` object as an argument or option +/// can also accept an `Array` of two {@link LngLatLike} constructs and will perform an implicit conversion. +/// This flexible type is documented as {@link LngLatBoundsLike}. +/// +/// @param {LngLatLike} [sw] The southwest corner of the bounding box. +/// @param {LngLatLike} [ne] The northeast corner of the bounding box. +/// @example +/// var sw = new mapboxgl.LngLat(-73.9876, 40.7661); +/// var ne = new mapboxgl.LngLat(-73.9397, 40.8002); +/// var llb = new mapboxgl.LngLatBounds(sw, ne); +@JS('LngLatBounds') +class LngLatBoundsJsImpl { + external LngLatJsImpl get sw; + external LngLatJsImpl get ne; + + external factory LngLatBoundsJsImpl( + LngLatJsImpl sw, + LngLatJsImpl ne, + ); + + /// Set the northeast corner of the bounding box + /// + /// @param {LngLatLike} ne + /// @returns {LngLatBounds} `this` + external LngLatBoundsJsImpl setNorthEast(LngLatJsImpl ne); + + /// Set the southwest corner of the bounding box + /// + /// @param {LngLatLike} sw + /// @returns {LngLatBounds} `this` + external LngLatBoundsJsImpl setSouthWest(LngLatJsImpl sw); + + /// Extend the bounds to include a given LngLat or LngLatBounds. + /// + /// @param {LngLat|LngLatBounds} obj object to extend to + /// @returns {LngLatBounds} `this` + external LngLatBoundsJsImpl extend(dynamic obj); + + /// Returns the geographical coordinate equidistant from the bounding box's corners. + /// + /// @returns {LngLat} The bounding box's center. + /// @example + /// var llb = new mapboxgl.LngLatBounds([-73.9876, 40.7661], [-73.9397, 40.8002]); + /// llb.getCenter(); // = LngLat {lng: -73.96365, lat: 40.78315} + external LngLatJsImpl getCenter(); + + /// Returns the southwest corner of the bounding box. + /// + /// @returns {LngLat} The southwest corner of the bounding box. + external LngLatJsImpl getSouthWest(); + + /// Returns the northeast corner of the bounding box. + /// + /// @returns {LngLat} The northeast corner of the bounding box. + external LngLatJsImpl getNorthEast(); + + /// Returns the northwest corner of the bounding box. + /// + /// @returns {LngLat} The northwest corner of the bounding box. + external LngLatJsImpl getNorthWest(); + + /// Returns the southeast corner of the bounding box. + /// + /// @returns {LngLat} The southeast corner of the bounding box. + external LngLatJsImpl getSouthEast(); + + /// Returns the west edge of the bounding box. + /// + /// @returns {number} The west edge of the bounding box. + external num getWest(); + + /// Returns the south edge of the bounding box. + /// + /// @returns {number} The south edge of the bounding box. + external num getSouth(); + + /// Returns the east edge of the bounding box. + /// + /// @returns {number} The east edge of the bounding box. + external num getEast(); + + /// Returns the north edge of the bounding box. + /// + /// @returns {number} The north edge of the bounding box. + external num getNorth(); + + /// Returns the bounding box represented as an array. + /// + /// @returns {Array>} The bounding box represented as an array, consisting of the + /// southwest and northeast coordinates of the bounding represented as arrays of numbers. + /// @example + /// var llb = new mapboxgl.LngLatBounds([-73.9876, 40.7661], [-73.9397, 40.8002]); + /// llb.toArray(); // = [[-73.9876, 40.7661], [-73.9397, 40.8002]] + external List> toArray(); + + /// Return the bounding box represented as a string. + /// + /// @returns {string} The bounding box represents as a string of the format + /// `'LngLatBounds(LngLat(lng, lat), LngLat(lng, lat))'`. + /// @example + /// var llb = new mapboxgl.LngLatBounds([-73.9876, 40.7661], [-73.9397, 40.8002]); + /// llb.toString(); // = "LngLatBounds(LngLat(-73.9876, 40.7661), LngLat(-73.9397, 40.8002))" + external String toString(); + + /// Check if the bounding box is an empty/`null`-type box. + /// + /// @returns {boolean} True if bounds have been defined, otherwise false. + external bool isEmpty(); + + /// Check if the point is within the bounding box. + /// + /// @param {LngLatLike} lnglat geographic point to check against. + /// @returns {boolean} True if the point is within the bounding box. + external bool contains(LngLatJsImpl lnglat); + + /// Converts an array to a `LngLatBounds` object. + /// + /// If a `LngLatBounds` object is passed in, the function returns it unchanged. + /// + /// Internally, the function calls `LngLat#convert` to convert arrays to `LngLat` values. + /// + /// @param {LngLatBoundsLike} input An array of two coordinates to convert, or a `LngLatBounds` object to return. + /// @returns {LngLatBounds} A new `LngLatBounds` object, if a conversion occurred, or the original `LngLatBounds` object. + /// @example + /// var arr = [[-73.9876, 40.7661], [-73.9397, 40.8002]]; + /// var llb = mapboxgl.LngLatBounds.convert(arr); + /// llb; // = LngLatBounds {_sw: LngLat {lng: -73.9876, lat: 40.7661}, _ne: LngLat {lng: -73.9397, lat: 40.8002}} + external static LngLatBoundsJsImpl convert(dynamic input); +} diff --git a/lib/src/interop/geo/lng_lat_interop.dart b/lib/src/interop/geo/lng_lat_interop.dart new file mode 100644 index 0000000..0be6999 --- /dev/null +++ b/lib/src/interop/geo/lng_lat_interop.dart @@ -0,0 +1,79 @@ +@JS('mapboxgl') +library mapboxgl.interop.geo.lng_lat; + +import 'package:js/js.dart'; +import 'package:mapbox_gl_dart/src/interop/interop.dart'; + +/// A `LngLat` object represents a given longitude and latitude coordinate, measured in degrees. +/// +/// Mapbox GL uses longitude, latitude coordinate order (as opposed to latitude, longitude) to match GeoJSON. +/// +/// Note that any Mapbox GL method that accepts a `LngLat` object as an argument or option +/// can also accept an `Array` of two numbers and will perform an implicit conversion. +/// This flexible type is documented as {@link LngLatLike}. +/// +/// @param {number} lng Longitude, measured in degrees. +/// @param {number} lat Latitude, measured in degrees. +/// @example +/// var ll = new mapboxgl.LngLat(-73.9749, 40.7736); +/// @see [Get coordinates of the mouse pointer](https://www.mapbox.com/mapbox-gl-js/example/mouse-position/) +/// @see [Display a popup](https://www.mapbox.com/mapbox-gl-js/example/popup/) +/// @see [Highlight features within a bounding box](https://www.mapbox.com/mapbox-gl-js/example/using-box-queryrenderedfeatures/) +/// @see [Create a timeline animation](https://www.mapbox.com/mapbox-gl-js/example/timeline-animation/) +@JS('LngLat') +class LngLatJsImpl { + external num get lng; + external num get lat; + + external factory LngLatJsImpl( + num lng, + num lat, + ); + + /// Returns a new `LngLat` object whose longitude is wrapped to the range (-180, 180). + /// + /// @returns {LngLat} The wrapped `LngLat` object. + /// @example + /// var ll = new mapboxgl.LngLat(286.0251, 40.7736); + /// var wrapped = ll.wrap(); + /// wrapped.lng; // = -73.9749 + external LngLatJsImpl wrap(); + + /// Returns the coordinates represented as an array of two numbers. + /// + /// @returns {Array} The coordinates represeted as an array of longitude and latitude. + /// @example + /// var ll = new mapboxgl.LngLat(-73.9749, 40.7736); + /// ll.toArray(); // = [-73.9749, 40.7736] + external List toArray(); + + /// Returns the coordinates represent as a string. + /// + /// @returns {string} The coordinates represented as a string of the format `'LngLat(lng, lat)'`. + /// @example + /// var ll = new mapboxgl.LngLat(-73.9749, 40.7736); + /// ll.toString(); // = "LngLat(-73.9749, 40.7736)" + external String toString(); + + /// Returns a `LngLatBounds` from the coordinates extended by a given `radius`. The returned `LngLatBounds` completely contains the `radius`. + /// + /// @param {number} [radius]=0 Distance in meters from the coordinates to extend the bounds. + /// @returns {LngLatBounds} A new `LngLatBounds` object representing the coordinates extended by the `radius`. + /// @example + /// var ll = new mapboxgl.LngLat(-73.9749, 40.7736); + /// ll.toBounds(100).toArray(); // = [[-73.97501862141328, 40.77351016847229], [-73.97478137858673, 40.77368983152771]] + external LngLatBoundsJsImpl toBounds(num radius); + + /// Converts an array of two numbers or an object with `lng` and `lat` or `lon` and `lat` properties + /// to a `LngLat` object. + /// + /// If a `LngLat` object is passed in, the function returns it unchanged. + /// + /// @param {LngLatLike} input An array of two numbers or object to convert, or a `LngLat` object to return. + /// @returns {LngLat} A new `LngLat` object, if a conversion occurred, or the original `LngLat` object. + /// @example + /// var arr = [-73.9749, 40.7736]; + /// var ll = mapboxgl.LngLat.convert(arr); + /// ll; // = LngLat {lng: -73.9749, lat: 40.7736} + external static LngLatJsImpl convert(dynamic input); +} diff --git a/lib/src/interop/geojson_interop.dart b/lib/src/interop/geojson_interop.dart deleted file mode 100644 index bf163b6..0000000 --- a/lib/src/interop/geojson_interop.dart +++ /dev/null @@ -1,36 +0,0 @@ -@JS('mapboxgl') -library mapboxgl.interop.geojson_interop; - -import 'package:js/js.dart'; - -@JS() -@anonymous -class FeatureJsImpl { - String type; - GeometryJsImpl geometry; - PropertiesJsImpl properties; - String source; - external factory FeatureJsImpl({String source}); -} - -@JS() -@anonymous -class GeometryJsImpl { - String type; - List coordinates; - external factory GeometryJsImpl({ - String type, - List coordinates, - }); -} - -@JS() -@anonymous -class PropertiesJsImpl { - String description; - String icon; - external factory PropertiesJsImpl({ - String description, - String icon, - }); -} diff --git a/lib/src/interop/interop.dart b/lib/src/interop/interop.dart new file mode 100644 index 0000000..ed088b3 --- /dev/null +++ b/lib/src/interop/interop.dart @@ -0,0 +1,27 @@ +library mapboxgl.interop; + +export 'geo/geojson_interop.dart'; +export 'geo/lng_lat_bounds_interop.dart'; +export 'geo/lng_lat_interop.dart'; +export 'js.dart'; +export 'style/evaluation_parameters_interop.dart'; +export 'style/layers/circle_layer_interop.dart'; +export 'style/layers/line_layer_interop.dart'; +export 'style/layers/symbol_layer_interop.dart'; +export 'style/sources/geojson_source_interop.dart'; +export 'style/sources/vector_source_interop.dart'; +export 'style/style_image_interop.dart'; +export 'style/style_interop.dart'; +export 'ui/camera_interop.dart'; +export 'ui/events_interop.dart'; +export 'ui/handler/box_zoom_interop.dart'; +export 'ui/handler/dblclick_zoom_interop.dart'; +export 'ui/handler/drag_pan_interop.dart'; +export 'ui/handler/drag_rotate_interop.dart'; +export 'ui/handler/keyboard_interop.dart'; +export 'ui/handler/scroll_zoom_interop.dart'; +export 'ui/handler/touch_zoom_rotate_interop.dart'; +export 'ui/map_interop.dart'; +export 'ui/marker_interop.dart'; +export 'ui/popup_interop.dart'; +export 'util/evented_interop.dart'; diff --git a/lib/src/interop/js.dart b/lib/src/interop/js.dart new file mode 100644 index 0000000..3f046fe --- /dev/null +++ b/lib/src/interop/js.dart @@ -0,0 +1,17 @@ +@JS() +library mapboxgl.interop.js; + +import 'package:js/js.dart'; + +/// This class is a wrapper for the jsObject. All the specific JsObject +/// wrappers extend from it. +abstract class JsObjectWrapper { + /// JS object. + final T jsObject; + + /// Creates a new JsObjectWrapper type from a [jsObject]. + JsObjectWrapper.fromJsObject(this.jsObject); +} + +@JS('Object.keys') +external List objectKeys(Object obj); diff --git a/lib/src/interop/style/evaluation_parameters_interop.dart b/lib/src/interop/style/evaluation_parameters_interop.dart new file mode 100644 index 0000000..def2143 --- /dev/null +++ b/lib/src/interop/style/evaluation_parameters_interop.dart @@ -0,0 +1,21 @@ +@JS('mapboxgl') +library mapboxgl.interop.style.evaluation_parameters; + +import 'package:js/js.dart'; + +@JS('EvaluationParameters') +class EvaluationParametersJsImpl { + external num get zoom; + external num get now; + external num get fadeDuration; + external dynamic get zoomHistory; + external dynamic get transition; + + external factory EvaluationParametersJsImpl(num zoom, [dynamic options]); + + external bool isSupportedScript(String str); + + external crossFadingFactor(); + + external dynamic getCrossfadeParameters(); +} diff --git a/lib/src/interop/style/layers/circle_layer_interop.dart b/lib/src/interop/style/layers/circle_layer_interop.dart new file mode 100644 index 0000000..cc69189 --- /dev/null +++ b/lib/src/interop/style/layers/circle_layer_interop.dart @@ -0,0 +1,36 @@ +library mapboxgl.interop.style.layers.circle_layer; + +import 'package:js/js_util.dart'; +import 'package:mapbox_gl_dart/mapbox_gl_dart.dart'; + +class CircleLayerJsImpl { + static toJs(CircleLayer circleLayer) => jsify(toDict(circleLayer)); + + static toDict(CircleLayer circleLayer) { + Map dict = { + 'id': circleLayer.id, + 'type': 'circle', + }; + if (circleLayer.source != null) + dict['source'] = circleLayer.source is String + ? circleLayer.source + : circleLayer.source.dict; + if (circleLayer.sourceLayer != null) + dict['source-layer'] = circleLayer.sourceLayer; + if (circleLayer.paint != null) dict['paint'] = circleLayer.paint.dict; + return dict; + } +} + +class CirclePaintJsImpl { + static toJs(CirclePaint circlePaint) => jsify(toDict(circlePaint)); + + static toDict(CirclePaint circlePaint) { + Map dict = {}; + if (circlePaint.circleRadius != null) + dict['circle-radius'] = circlePaint.circleRadius; + if (circlePaint.circleColor != null) + dict['circle-color'] = circlePaint.circleColor; + return dict; + } +} diff --git a/lib/src/interop/style/layers/line_layer_interop.dart b/lib/src/interop/style/layers/line_layer_interop.dart new file mode 100644 index 0000000..c605095 --- /dev/null +++ b/lib/src/interop/style/layers/line_layer_interop.dart @@ -0,0 +1,71 @@ +library mapboxgl.interop.style.layers.line_layer; + +import 'package:js/js_util.dart'; +import 'package:mapbox_gl_dart/mapbox_gl_dart.dart'; + +class LineLayerJsImpl { + static toJs(LineLayer lineLayer) => jsify(toDict(lineLayer)); + + static toDict(LineLayer lineLayer) { + Map dict = { + 'id': lineLayer.id, + 'type': 'line', + }; + if (lineLayer.source != null) + dict['source'] = + lineLayer.source is String ? lineLayer.source : lineLayer.source.dict; + if (lineLayer.sourceLayer != null) + dict['source-layer'] = lineLayer.sourceLayer; + if (lineLayer.paint != null) dict['paint'] = lineLayer.paint.dict; + if (lineLayer.layout != null) dict['layout'] = lineLayer.layout.dict; + if (lineLayer.filter != null) dict['filter'] = lineLayer.filter; + return dict; + } +} + +class LinePaintJsImpl { + static toJs(LinePaint linePaint) => jsify(toDict(linePaint)); + + static toDict(LinePaint linePaint) { + Map dict = {}; + if (linePaint.lineOpacity != null) + dict['line-opacity'] = linePaint.lineOpacity; + if (linePaint.lineColor != null) dict['line-color'] = linePaint.lineColor; + if (linePaint.lineTranslate != null) + dict['line-translate'] = linePaint.lineTranslate; + if (linePaint.lineTranslateAnchor != null) + dict['line-translate-anchor'] = linePaint.lineTranslateAnchor; + if (linePaint.lineWidth != null) dict['line-width'] = linePaint.lineWidth; + if (linePaint.lineGapWidth != null) + dict['line-gap-width'] = linePaint.lineGapWidth; + if (linePaint.lineOffset != null) + dict['line-offset'] = linePaint.lineOffset; + if (linePaint.lineBlur != null) dict['line-blur'] = linePaint.lineBlur; + if (linePaint.lineDasharray != null) + dict['line-dasharray'] = linePaint.lineDasharray; + if (linePaint.linePattern != null) + dict['line-pattern'] = linePaint.linePattern; + if (linePaint.lineGradient != null) + dict['line-gradient'] = linePaint.lineGradient; + return dict; + } +} + +class LineLayoutJsImpl { + static toJs(LineLayout lineLayout) => jsify(toDict(lineLayout)); + + static toDict(LineLayout lineLayout) { + Map dict = {}; + if (lineLayout.lineCap != null) dict['line-cap'] = lineLayout.lineCap; + if (lineLayout.lineJoin != null) dict['line-join'] = lineLayout.lineJoin; + if (lineLayout.lineMiterLimit != null) + dict['line-miter-limit'] = lineLayout.lineMiterLimit; + if (lineLayout.lineRoundLimit != null) + dict['line-round-limit'] = lineLayout.lineRoundLimit; + if (lineLayout.lineSortKey != null) + dict['line-sort-key'] = lineLayout.lineSortKey; + if (lineLayout.visibility != null) + dict['visibility'] = lineLayout.visibility; + return dict; + } +} diff --git a/lib/src/interop/style/layers/symbol_layer_interop.dart b/lib/src/interop/style/layers/symbol_layer_interop.dart new file mode 100644 index 0000000..e167979 --- /dev/null +++ b/lib/src/interop/style/layers/symbol_layer_interop.dart @@ -0,0 +1,154 @@ +library mapboxgl.interop.style.layers.symbol_layer; + +import 'package:js/js_util.dart'; +import 'package:mapbox_gl_dart/mapbox_gl_dart.dart'; + +class SymbolLayerJsImpl { + static toJs(SymbolLayer symbolLayer) => jsify(toDict(symbolLayer)); + + static toDict(SymbolLayer symbolLayer) { + Map dict = { + 'id': symbolLayer.id, + 'type': 'symbol', + }; + if (symbolLayer.metadata != null) dict['metadata'] = symbolLayer.metadata; + if (symbolLayer.source != null) + dict['source'] = symbolLayer.source is String + ? symbolLayer.source + : symbolLayer.source.dict; + if (symbolLayer.sourceLayer != null) + dict['source-layer'] = symbolLayer.sourceLayer; + if (symbolLayer.minZoom != null) dict['minzoom'] = symbolLayer.minZoom; + if (symbolLayer.maxZoom != null) dict['maxzoom'] = symbolLayer.maxZoom; + if (symbolLayer.filter != null) dict['filter'] = symbolLayer.filter; + if (symbolLayer.layout != null) dict['layout'] = symbolLayer.layout.dict; + if (symbolLayer.paint != null) dict['paint'] = symbolLayer.paint.dict; + return dict; + } +} + +class SymbolPaintJsImpl { + static toJs(SymbolPaint symbolPaint) => jsify(toDict(symbolPaint)); + + static toDict(SymbolPaint symbolPaint) { + Map dict = {}; + if (symbolPaint.iconOpacity != null) + dict['icon-opacity'] = symbolPaint.iconOpacity; + if (symbolPaint.iconColor != null) + dict['icon-color'] = symbolPaint.iconColor; + if (symbolPaint.iconHaloColor != null) + dict['icon-halo-color'] = symbolPaint.iconHaloColor; + if (symbolPaint.iconHaloWidth != null) + dict['icon-halo-width'] = symbolPaint.iconHaloWidth; + if (symbolPaint.iconHaloBlur != null) + dict['icon-halo-blur'] = symbolPaint.iconHaloBlur; + if (symbolPaint.iconTranslate != null) + dict['icon-translate'] = symbolPaint.iconTranslate; + if (symbolPaint.iconTranslateAnchor != null) + dict['icon-translate-anchor'] = symbolPaint.iconTranslateAnchor; + if (symbolPaint.textOpacity != null) + dict['text-opacity'] = symbolPaint.textOpacity; + if (symbolPaint.textColor != null) + dict['text-color'] = symbolPaint.textColor; + if (symbolPaint.textHaloColor != null) + dict['text-halo-color'] = symbolPaint.textHaloColor; + if (symbolPaint.textHaloWidth != null) + dict['text-halo-width'] = symbolPaint.textHaloWidth; + if (symbolPaint.textHaloBlur != null) + dict['text-halo-blur'] = symbolPaint.textHaloBlur; + if (symbolPaint.textTranslate != null) + dict['text-translate'] = symbolPaint.textTranslate; + if (symbolPaint.textTranslateAnchor != null) + dict['text-translate-anchor'] = symbolPaint.textTranslateAnchor; + return dict; + } +} + +class SymbolLayoutJsImpl { + static toJs(SymbolLayout symbolLayout) => jsify(toDict(symbolLayout)); + + static toDict(SymbolLayout symbolLayout) { + Map dict = {}; + if (symbolLayout.symbolAvoidEdges != null) + dict['symbol-avoid-edges'] = symbolLayout.symbolAvoidEdges; + if (symbolLayout.symbolSortKey != null) + dict['symbol-sort-key'] = symbolLayout.symbolSortKey; + if (symbolLayout.symbolZOrder != null) + dict['symbol-z-order'] = symbolLayout.symbolZOrder; + if (symbolLayout.iconAllowOverlap != null) + dict['icon-allow-overlap'] = symbolLayout.iconAllowOverlap; + if (symbolLayout.iconIgnorePlacement != null) + dict['icon-ignore-placement'] = symbolLayout.iconIgnorePlacement; + if (symbolLayout.iconOptional != null) + dict['icon-optional'] = symbolLayout.iconOptional; + if (symbolLayout.iconRotationAlignment != null) + dict['icon-rotation-alignment'] = symbolLayout.iconRotationAlignment; + if (symbolLayout.iconSize != null) + dict['icon-size'] = symbolLayout.iconSize; + if (symbolLayout.iconTextFit != null) + dict['icon-text-fit'] = symbolLayout.iconTextFit; + if (symbolLayout.iconFitPadding != null) + dict['icon-fit-padding'] = symbolLayout.iconFitPadding; + if (symbolLayout.iconImage != null) + dict['icon-image'] = symbolLayout.iconImage; + if (symbolLayout.iconRotate != null) + dict['icon-rotate'] = symbolLayout.iconRotate; + if (symbolLayout.iconPadding != null) + dict['icon-padding'] = symbolLayout.iconPadding; + if (symbolLayout.iconKeepUpright != null) + dict['icon-keep-upright'] = symbolLayout.iconKeepUpright; + if (symbolLayout.iconOffset != null) + dict['icon-offset'] = symbolLayout.iconOffset; + if (symbolLayout.iconAnchor != null) + dict['icon-anchor'] = symbolLayout.iconAnchor; + if (symbolLayout.iconPitchAlignment != null) + dict['icon-pitch-alignment'] = symbolLayout.iconPitchAlignment; + if (symbolLayout.textPitchAlignment != null) + dict['text-pitch-alignment'] = symbolLayout.textPitchAlignment; + if (symbolLayout.textRotationAlignment != null) + dict['text-rotation-alignment'] = symbolLayout.textRotationAlignment; + if (symbolLayout.textField != null) + dict['text-field'] = symbolLayout.textField; + if (symbolLayout.textFont != null) + dict['text-font'] = symbolLayout.textFont; + if (symbolLayout.textSize != null) + dict['text-size'] = symbolLayout.textSize; + if (symbolLayout.textMaxWidth != null) + dict['text-max-width'] = symbolLayout.textMaxWidth; + if (symbolLayout.textLineHeight != null) + dict['text-line-height'] = symbolLayout.textLineHeight; + if (symbolLayout.textLetterSpacing != null) + dict['text-letter-spacing'] = symbolLayout.textLetterSpacing; + if (symbolLayout.textJustify != null) + dict['text-justify'] = symbolLayout.textJustify; + if (symbolLayout.textRadialOffset != null) + dict['text-radial-offset'] = symbolLayout.textRadialOffset; + if (symbolLayout.textVariableAnchor != null) + dict['text-variable-anchor'] = symbolLayout.textVariableAnchor; + if (symbolLayout.textAnchor != null) + dict['text-anchor'] = symbolLayout.textAnchor; + if (symbolLayout.textMaxAngle != null) + dict['text-max-angle'] = symbolLayout.textMaxAngle; + if (symbolLayout.textWritingMode != null) + dict['text-writing-mode'] = symbolLayout.textWritingMode; + if (symbolLayout.textRotate != null) + dict['text-rotate'] = symbolLayout.textRotate; + if (symbolLayout.textPadding != null) + dict['text-padding'] = symbolLayout.textPadding; + if (symbolLayout.textKeepUpright != null) + dict['text-keep-upright'] = symbolLayout.textKeepUpright; + if (symbolLayout.textTransform != null) + dict['text-transform'] = symbolLayout.textTransform; + if (symbolLayout.textOffset != null) + dict['text-offset'] = symbolLayout.textOffset; + if (symbolLayout.textAllowOverlap != null) + dict['text-allow-overlap'] = symbolLayout.textAllowOverlap; + if (symbolLayout.textIgnorePlacement != null) + dict['text-ignore-placement'] = symbolLayout.textIgnorePlacement; + if (symbolLayout.textOptional != null) + dict['text-optional'] = symbolLayout.textOptional; + if (symbolLayout.visibility != null) + dict['visibility'] = symbolLayout.visibility; + return dict; + } +} diff --git a/lib/src/interop/style/sources/geojson_source_interop.dart b/lib/src/interop/style/sources/geojson_source_interop.dart new file mode 100644 index 0000000..1b97222 --- /dev/null +++ b/lib/src/interop/style/sources/geojson_source_interop.dart @@ -0,0 +1,15 @@ +@JS('mapboxgl') +library mapboxgl.style.interop.sources.geojson_source; + +import 'package:js/js.dart'; +import 'package:mapbox_gl_dart/src/interop/interop.dart'; + +@JS() +@anonymous +class GeoJsonSourceJsImpl { + external FeatureCollectionJsImpl get data; + external factory GeoJsonSourceJsImpl({ + String type, + FeatureCollectionJsImpl data, + }); +} diff --git a/lib/src/interop/style/sources/vector_source_interop.dart b/lib/src/interop/style/sources/vector_source_interop.dart new file mode 100644 index 0000000..6cb8e2f --- /dev/null +++ b/lib/src/interop/style/sources/vector_source_interop.dart @@ -0,0 +1,16 @@ +@JS('mapboxgl') +library mapboxgl.style.interop.sources.vector_source; + +import 'package:js/js.dart'; + +@JS() +@anonymous +class VectorSourceJsImpl { + external String get url; + external List get tiles; + external factory VectorSourceJsImpl({ + String type, + String url, + List tiles, + }); +} diff --git a/lib/src/interop/style/style_image_interop.dart b/lib/src/interop/style/style_image_interop.dart new file mode 100644 index 0000000..fc3e3db --- /dev/null +++ b/lib/src/interop/style/style_image_interop.dart @@ -0,0 +1,27 @@ +@JS('mapboxgl') +library mapboxgl.interop.style.style_image; + +import 'package:js/js.dart'; +import 'package:mapbox_gl_dart/src/interop/interop.dart'; + +@JS() +@anonymous +abstract class StyleImageJsImpl { + external dynamic get data; + external num get pixelRatio; + external bool get sdf; + external num get version; + external bool get hasRenderCallback; + external StyleImageInterfaceJsImpl get userImage; +} + +@JS() +@anonymous +abstract class StyleImageInterfaceJsImpl { + external num get width; + external num get height; + external dynamic get data; + external Function get render; + external Function(MapboxMapJsImpl map, String id) get onAdd; + external Function get onRemove; +} diff --git a/lib/src/interop/style/style_interop.dart b/lib/src/interop/style/style_interop.dart new file mode 100644 index 0000000..0b04027 --- /dev/null +++ b/lib/src/interop/style/style_interop.dart @@ -0,0 +1,146 @@ +@JS('mapboxgl') +library mapboxgl.interop.style.style; + +import 'package:js/js.dart'; +import 'package:mapbox_gl_dart/src/interop/interop.dart'; + +@JS() +@anonymous +abstract class StyleSetterOptionsJsImpl { + external bool get validate; +} + +@JS('Style') +abstract class StyleJsImpl extends EventedJsImpl { + loadURL(String url, dynamic options); + + loadJSON(dynamic json, StyleSetterOptionsJsImpl option); + + loaded(); + + hasTransitions(); + + /// Apply queued style updates in a batch and recalculate zoom-dependent paint properties. + update(EvaluationParametersJsImpl parameters); + + /// Update this style's state to match the given style JSON, performing only + /// the necessary mutations. + /// + /// May throw an Error ('Unimplemented: METHOD') if the mapbox-gl-style-spec + /// diff algorithm produces an operation that is not supported. + /// + /// @returns {boolean} true if any changes were made; false otherwise + /// @private + setState(dynamic nextState); + + addImage(String id, StyleImageJsImpl image); + + updateImage(String id, StyleImageJsImpl image); + + StyleImageJsImpl getImage(String id); + + removeImage(String id); + + listImages(); + + addSource(String id, dynamic source, StyleSetterOptionsJsImpl options); + + /// Remove a source from this stylesheet, given its id. + /// @param {string} id id of the source to remove + /// @throws {Error} if no source is found with the given ID + removeSource(String id); + + /// Set the data of a GeoJSON source, given its id. + /// @param {string} id id of the source + /// @param {GeoJSON|string} data GeoJSON source + setGeoJSONSourceData(String id, dynamic data); + + /// Get a source by id. + /// @param {string} id id of the desired source + /// @returns {Object} source + dynamic getSource(String id); + + /// Add a layer to the map style. The layer will be inserted before the layer with + /// ID `before`, or appended if `before` is omitted. + /// @param {string} [before] ID of an existing layer to insert before + addLayer(dynamic layerObject, + [String before, StyleSetterOptionsJsImpl options]); + + /// Moves a layer to a different z-position. The layer will be inserted before the layer with + /// ID `before`, or appended if `before` is omitted. + /// @param {string} id ID of the layer to move + /// @param {string} [before] ID of an existing layer to insert before + moveLayer(String id, [String before]); + + /// Remove the layer with the given id from the style. + /// + /// If no such layer exists, an `error` event is fired. + /// + /// @param {string} id id of the layer to remove + /// @fires error + removeLayer(String id); + + /// Return the style layer object with the given `id`. + /// + /// @param {string} id - id of the desired layer + /// @returns {?Object} a layer, if one with the given `id` exists + dynamic getLayer(String id); + + setLayerZoomRange(String layerId, [num minzoom, num maxzoom]); + + setFilter(String layerId, dynamic filter, StyleSetterOptionsJsImpl options); + + /// Get a layer's filter object + /// @param {string} layer the layer to inspect + /// @returns {*} the layer's filter, if any + getFilter(String layer); + + setLayoutProperty(String layerId, String name, dynamic value, + StyleSetterOptionsJsImpl options); + + /// Get a layout property's value from a given layer + /// @param {string} layerId the layer to inspect + /// @param {string} name the name of the layout property + /// @returns {*} the property value + getLayoutProperty(String layerId, String name); + + setPaintProperty(String layerId, String name, dynamic value, + StyleSetterOptionsJsImpl options); + + getPaintProperty(String layer, String name); + + setFeatureState(dynamic target, dynamic state); + + removeFeatureState(dynamic target, [String key]); + + getFeatureState(dynamic target); + + getTransition(); + + serialize(); + + querySourceFeatures(String sourceID, dynamic params); + + addSourceType(String name, dynamic sourceType, Function callback); + + getLight(); + + setLight(dynamic lightOptions, StyleSetterOptionsJsImpl options); + + // Callbacks from web workers + + getImages(String mapId, dynamic params, Function callback); + + getGlyphs(String mapId, dynamic params, Function callback); + + getResource(String mapId, RequestParametersJsImpl params, Function callback); +} + +@JS() +@anonymous +class StyleFunctionJsImpl { + external factory StyleFunctionJsImpl({ + dynamic base, + dynamic stops, + }); +} diff --git a/lib/src/interop/ui/camera_interop.dart b/lib/src/interop/ui/camera_interop.dart new file mode 100644 index 0000000..3507948 --- /dev/null +++ b/lib/src/interop/ui/camera_interop.dart @@ -0,0 +1,480 @@ +@JS('mapboxgl') +library mapboxgl.interop.ui.camera; + +import 'dart:html'; + +import 'package:js/js.dart'; +import 'package:mapbox_gl_dart/src/interop/interop.dart'; + +/// Options common to {@link MapboxMap#jumpTo}, {@link MapboxMap#easeTo}, and {@link MapboxMap#flyTo}, controlling the desired location, +/// zoom, bearing, and pitch of the camera. All properties are optional, and when a property is omitted, the current +/// camera value for that property will remain unchanged. +/// +/// @typedef {Object} CameraOptions +/// @property {LngLatLike} center The desired center. +/// @property {number} zoom The desired zoom level. +/// @property {number} bearing The desired bearing, in degrees. The bearing is the compass direction that +/// is "up"; for example, a bearing of 90° orients the map so that east is up. +/// @property {number} pitch The desired pitch, in degrees. +/// @property {LngLatLike} around If `zoom` is specified, `around` determines the point around which the zoom is centered. +@JS() +@anonymous +class CameraOptionsJsImpl { + external LngLatJsImpl get center; + external num get zoom; + external num get bearing; + external num get pitch; + external LngLatJsImpl get around; + + external factory CameraOptionsJsImpl({ + LngLatJsImpl center, + num zoom, + num bearing, + num pitch, + LngLatJsImpl around, + }); +} + +/// Options common to map movement methods that involve animation, such as {@link MapboxMap#panBy} and +/// {@link MapboxMap#easeTo}, controlling the duration and easing function of the animation. All properties +/// are optional. +/// +/// @typedef {Object} AnimationOptions +/// @property {number} duration The animation's duration, measured in milliseconds. +/// @property {Function} easing A function taking a time in the range 0..1 and returning a number where 0 is +/// the initial state and 1 is the final state. +/// @property {PointLike} offset of the target center relative to real map container center at the end of animation. +/// @property {boolean} animate If `false`, no animation will occur. +/// @property {boolean} essential If `true`, then the animation is considered essential and will not be affected by +/// [`prefers-reduced-motion`](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion). +@JS() +@anonymous +class AnimationOptionsJsImpl { + external num get duration; + external num Function(num time) get easing; + external Point get offset; + external bool get animate; + external bool get essential; + + external factory AnimationOptionsJsImpl({ + num duration, + num Function(num time) easing, + Point offset, + bool animate, + bool essential, + }); +} + +/// Options for setting padding on a call to {@link MapboxMap#fitBounds}. All properties of this object must be +/// non-negative integers. +/// +/// @typedef {Object} PaddingOptions +/// @property {number} top Padding in pixels from the top of the map canvas. +/// @property {number} bottom Padding in pixels from the bottom of the map canvas. +/// @property {number} left Padding in pixels from the left of the map canvas. +/// @property {number} right Padding in pixels from the right of the map canvas. +@JS() +@anonymous +class PaddingOptionsJsImpl { + external num get top; + external num get bottom; + external num get left; + external num get right; + + external factory PaddingOptionsJsImpl({ + num top, + num bottom, + num left, + num right, + }); +} + +@JS('Camera') +abstract class CameraJsImpl extends EventedJsImpl { + /// Returns the map's geographical centerpoint. + /// + /// @memberof MapboxMap# + /// @returns The map's geographical centerpoint. + external LngLatJsImpl getCenter(); + + /// Sets the map's geographical centerpoint. Equivalent to `jumpTo({center: center})`. + /// + /// @memberof MapboxMap# + /// @param center The centerpoint to set. + /// @param eventData Additional properties to be added to event objects of events triggered by this method. + /// @fires movestart + /// @fires moveend + /// @returns {MapboxMap} `this` + /// @example + /// map.setCenter([-74, 38]); + external MapboxMapJsImpl setCenter(LngLatJsImpl center, [dynamic eventData]); + + /// Pans the map by the specified offset. + /// + /// @memberof MapboxMap# + /// @param offset `x` and `y` coordinates by which to pan the map. + /// @param options + /// @param eventData Additional properties to be added to event objects of events triggered by this method. + /// @fires movestart + /// @fires moveend + /// @returns {MapboxMap} `this` + /// @see [Navigate the map with game-like controls](https://www.mapbox.com/mapbox-gl-js/example/game-controls/) + external MapboxMapJsImpl panBy(Point offset, + [AnimationOptionsJsImpl options, dynamic eventData]); + + /// Pans the map to the specified location, with an animated transition. + /// + /// @memberof MapboxMap# + /// @param lnglat The location to pan the map to. + /// @param options + /// @param eventData Additional properties to be added to event objects of events triggered by this method. + /// @fires movestart + /// @fires moveend + /// @returns {MapboxMap} `this` + external MapboxMapJsImpl panTo(LngLatJsImpl lnglat, + [AnimationOptionsJsImpl options, dynamic eventData]); + + /// Returns the map's current zoom level. + /// + /// @memberof MapboxMap# + /// @returns The map's current zoom level. + external num getZoom(); + + /// Sets the map's zoom level. Equivalent to `jumpTo({zoom: zoom})`. + /// + /// @memberof MapboxMap# + /// @param zoom The zoom level to set (0-20). + /// @param eventData Additional properties to be added to event objects of events triggered by this method. + /// @fires movestart + /// @fires zoomstart + /// @fires move + /// @fires zoom + /// @fires moveend + /// @fires zoomend + /// @returns {MapboxMap} `this` + /// @example + /// // zoom the map to 5 + /// map.setZoom(5); + external MapboxMapJsImpl setZoom(num zoom, [dynamic eventData]); + + /// Zooms the map to the specified zoom level, with an animated transition. + /// + /// @memberof MapboxMap# + /// @param zoom The zoom level to transition to. + /// @param options + /// @param eventData Additional properties to be added to event objects of events triggered by this method. + /// @fires movestart + /// @fires zoomstart + /// @fires move + /// @fires zoom + /// @fires moveend + /// @fires zoomend + /// @returns {MapboxMap} `this` + external MapboxMapJsImpl zoomTo(num zoom, + [AnimationOptionsJsImpl options, dynamic eventData]); + + /// Increases the map's zoom level by 1. + /// + /// @memberof MapboxMap# + /// @param options + /// @param eventData Additional properties to be added to event objects of events triggered by this method. + /// @fires movestart + /// @fires zoomstart + /// @fires move + /// @fires zoom + /// @fires moveend + /// @fires zoomend + /// @returns {MapboxMap} `this` + external MapboxMapJsImpl zoomIn( + [AnimationOptionsJsImpl options, dynamic eventData]); + + /// Decreases the map's zoom level by 1. + /// + /// @memberof MapboxMap# + /// @param options + /// @param eventData Additional properties to be added to event objects of events triggered by this method. + /// @fires movestart + /// @fires zoomstart + /// @fires move + /// @fires zoom + /// @fires moveend + /// @fires zoomend + /// @returns {MapboxMap} `this` + external MapboxMapJsImpl zoomOut( + [AnimationOptionsJsImpl options, dynamic eventData]); + + /// Returns the map's current bearing. The bearing is the compass direction that is \"up\"; for example, a bearing + /// of 90° orients the map so that east is up. + /// + /// @memberof MapboxMap# + /// @returns The map's current bearing. + /// @see [Navigate the map with game-like controls](https://www.mapbox.com/mapbox-gl-js/example/game-controls/) + external num getBearing(); + + /// Sets the map's bearing (rotation). The bearing is the compass direction that is \"up\"; for example, a bearing + /// of 90° orients the map so that east is up. + /// + /// Equivalent to `jumpTo({bearing: bearing})`. + /// + /// @memberof MapboxMap# + /// @param bearing The desired bearing. + /// @param eventData Additional properties to be added to event objects of events triggered by this method. + /// @fires movestart + /// @fires moveend + /// @returns {MapboxMap} `this` + /// @example + /// // rotate the map to 90 degrees + /// map.setBearing(90); + external MapboxMapJsImpl setBearing(num bearing, [dynamic eventData]); + + /// Rotates the map to the specified bearing, with an animated transition. The bearing is the compass direction + /// that is \"up\"; for example, a bearing of 90° orients the map so that east is up. + /// + /// @memberof MapboxMap# + /// @param bearing The desired bearing. + /// @param options + /// @param eventData Additional properties to be added to event objects of events triggered by this method. + /// @fires movestart + /// @fires moveend + /// @returns {MapboxMap} `this` + external MapboxMapJsImpl rotateTo(num bearing, + [AnimationOptionsJsImpl options, dynamic eventData]); + + /// Rotates the map so that north is up (0° bearing), with an animated transition. + /// + /// @memberof MapboxMap# + /// @param options + /// @param eventData Additional properties to be added to event objects of events triggered by this method. + /// @fires movestart + /// @fires moveend + /// @returns {MapboxMap} `this` + external MapboxMapJsImpl resetNorth( + [AnimationOptionsJsImpl options, dynamic eventData]); + + /// Rotates and pitches the map so that north is up (0° bearing) and pitch is 0°, with an animated transition. + /// + /// @memberof MapboxMap# + /// @param options + /// @param eventData Additional properties to be added to event objects of events triggered by this method. + /// @fires movestart + /// @fires moveend + /// @returns {MapboxMap} `this` + external MapboxMapJsImpl resetNorthPitch( + [AnimationOptionsJsImpl options, dynamic eventData]); + + /// Snaps the map so that north is up (0° bearing), if the current bearing is close enough to it (i.e. within the + /// `bearingSnap` threshold). + /// + /// @memberof MapboxMap# + /// @param options + /// @param eventData Additional properties to be added to event objects of events triggered by this method. + /// @fires movestart + /// @fires moveend + /// @returns {MapboxMap} `this` + external MapboxMapJsImpl snapToNorth( + [AnimationOptionsJsImpl options, dynamic eventData]); + + /// Returns the map's current pitch (tilt). + /// + /// @memberof MapboxMap# + /// @returns The map's current pitch, measured in degrees away from the plane of the screen. + external num getPitch(); + + /// Sets the map's pitch (tilt). Equivalent to `jumpTo({pitch: pitch})`. + /// + /// @memberof MapboxMap# + /// @param pitch The pitch to set, measured in degrees away from the plane of the screen (0-60). + /// @param eventData Additional properties to be added to event objects of events triggered by this method. + /// @fires pitchstart + /// @fires movestart + /// @fires moveend + /// @returns {MapboxMap} `this` + external MapboxMapJsImpl setPitch(num pitch, [dynamic eventData]); + + /// @memberof MapboxMap# + /// @param {LatLngBoundsLike} bounds Calculate the center for these bounds in the viewport and use + /// the highest zoom level up to and including `MapboxMap#getMaxZoom()` that fits + /// in the viewport. LatLngBounds represent a box that is always axis-aligned with bearing 0. + /// @param options + /// @param {number | PaddingOptions} `options.padding` The amount of padding in pixels to add to the given bounds. + /// @param {PointLike} `options.offset=[0, 0]` The center of the given bounds relative to the map's center, measured in pixels. + /// @param {number} `options.maxZoom` The maximum zoom level to allow when the camera would transition to the specified bounds. + /// @returns {CameraOptions | void} If map is able to fit to provided bounds, returns `CameraOptions` with + /// `center`, `zoom`, and `bearing`. If map is unable to fit, method will warn and return undefined. + /// @example + /// var bbox = [[-79, 43], [-73, 45]]; + /// var newCameraTransform = map.cameraForBounds(bbox, { + /// padding: {top: 10, bottom:25, left: 15, right: 5} + /// }); + external CameraOptionsJsImpl cameraForBounds(LngLatBoundsJsImpl bounds, + [CameraOptionsJsImpl options]); + + /// Pans and zooms the map to contain its visible area within the specified geographical bounds. + /// This function will also reset the map's bearing to 0 if bearing is nonzero. + /// + /// @memberof MapboxMap# + /// @param bounds Center these bounds in the viewport and use the highest + /// zoom level up to and including `MapboxMap#getMaxZoom()` that fits them in the viewport. + /// @param {Object} [options] Options supports all properties from {@link AnimationOptions} and {@link CameraOptions} in addition to the fields below. + /// @param {number | PaddingOptions} `options.padding` The amount of padding in pixels to add to the given bounds. + /// @param {boolean} `options.linear=false` If `true`, the map transitions using + /// {@link MapboxMap#easeTo}. If `false`, the map transitions using {@link MapboxMap#flyTo}. See + /// those functions and {@link AnimationOptions} for information about options available. + /// @param {Function} `options.easing` An easing function for the animated transition. See {@link AnimationOptions}. + /// @param {PointLike} `options.offset=[0, 0]` The center of the given bounds relative to the map's center, measured in pixels. + /// @param {number} `options.maxZoom` The maximum zoom level to allow when the map view transitions to the specified bounds. + /// @param {Object} [eventData] Additional properties to be added to event objects of events triggered by this method. + /// @fires movestart + /// @fires moveend + /// @returns {MapboxMap} `this` + /// @example + /// var bbox = [[-79, 43], [-73, 45]]; + /// map.fitBounds(bbox, { + /// padding: {top: 10, bottom:25, left: 15, right: 5} + /// }); + /// @see [Fit a map to a bounding box](https://www.mapbox.com/mapbox-gl-js/example/fitbounds/) + external MapboxMapJsImpl fitBounds(LngLatBoundsJsImpl bounds, + [dynamic options, dynamic eventData]); + + /// Pans, rotates and zooms the map to to fit the box made by points p0 and p1 + /// once the map is rotated to the specified bearing. To zoom without rotating, + /// pass in the current map bearing. + /// + /// @memberof MapboxMap# + /// @param p0 First point on screen, in pixel coordinates + /// @param p1 Second point on screen, in pixel coordinates + /// @param bearing Desired map bearing at end of animation, in degrees + /// @param options + /// @param {number | PaddingOptions} `options.padding` The amount of padding in pixels to add to the given bounds. + /// @param {boolean} `options.linear=false` If `true`, the map transitions using + /// {@link MapboxMap#easeTo}. If `false`, the map transitions using {@link MapboxMap#flyTo}. See + /// those functions and {@link AnimationOptions} for information about options available. + /// @param {Function} `options.easing` An easing function for the animated transition. See {@link AnimationOptions}. + /// @param {PointLike} `options.offset=[0, 0]` The center of the given bounds relative to the map's center, measured in pixels. + /// @param {number} `options.maxZoom` The maximum zoom level to allow when the map view transitions to the specified bounds. + /// @param eventData Additional properties to be added to event objects of events triggered by this method. + /// @fires movestart + /// @fires moveend + /// @returns {MapboxMap} `this` + /// @example + /// var p0 = [220, 400]; + /// var p1 = [500, 900]; + /// map.fitScreenCoordinates(p0, p1, map.getBearing(), { + /// padding: {top: 10, bottom:25, left: 15, right: 5} + /// }); + /// @see [Used by BoxZoomHandler](https://www.mapbox.com/mapbox-gl-js/api/#boxzoomhandler) + external MapboxMapJsImpl fitScreenCoordinates(Point p0, Point p1, num bearing, + [dynamic options, dynamic eventData]); + + /// Changes any combination of center, zoom, bearing, and pitch, without + /// an animated transition. The map will retain its current values for any + /// details not specified in [options]. + /// + /// @memberof MapboxMap# + /// @param options + /// @param eventData Additional properties to be added to event objects of events triggered by this method. + /// @fires movestart + /// @fires zoomstart + /// @fires pitchstart + /// @fires rotate + /// @fires move + /// @fires zoom + /// @fires pitch + /// @fires moveend + /// @fires zoomend + /// @fires pitchend + /// @returns {MapboxMap} `this` + external MapboxMapJsImpl jumpTo(CameraOptionsJsImpl options, + [dynamic eventData]); + + /// Changes any combination of center, zoom, bearing, and pitch, with an animated transition + /// between old and new values. The map will retain its current values for any + /// details not specified in [options]. + /// + /// Note: The transition will happen instantly if the user has enabled + /// the `reduced motion` accesibility feature enabled in their operating system. + /// + /// @memberof MapboxMap# + /// @param options Options describing the destination and animation of the transition. + /// Accepts {@link CameraOptions} and {@link AnimationOptions}. + /// @param eventData Additional properties to be added to event objects of events triggered by this method. + /// @fires movestart + /// @fires zoomstart + /// @fires pitchstart + /// @fires rotate + /// @fires move + /// @fires zoom + /// @fires pitch + /// @fires moveend + /// @fires zoomend + /// @fires pitchend + /// @returns {MapboxMap} `this` + /// @see [Navigate the map with game-like controls](https://www.mapbox.com/mapbox-gl-js/example/game-controls/) + external MapboxMapJsImpl easeTo(dynamic options, [dynamic eventData]); + + /// Changes any combination of center, zoom, bearing, and pitch, animating the transition along a curve that + /// evokes flight. The animation seamlessly incorporates zooming and panning to help + /// the user maintain her bearings even after traversing a great distance. + /// + /// Note: The animation will be skipped, and this will behave equivalently to `jumpTo` + /// if the user has the `reduced motion` accesibility feature enabled in their operating system. + /// + /// @memberof MapboxMap# + /// @param {Object} options Options describing the destination and animation of the transition. + /// Accepts {@link CameraOptions}, {@link AnimationOptions}, + /// and the following additional options. + /// @param {number} [options.curve=1.42] The zooming "curve" that will occur along the + /// flight path. A high value maximizes zooming for an exaggerated animation, while a low + /// value minimizes zooming for an effect closer to {@link MapboxMap#easeTo}. 1.42 is the average + /// value selected by participants in the user study discussed in + /// [van Wijk (2003)](https://www.win.tue.nl/~vanwijk/zoompan.pdf). A value of + /// `Math.pow(6, 0.25)` would be equivalent to the root mean squared average velocity. A + /// value of 1 would produce a circular motion. + /// @param {number} `options.minZoom` The zero-based zoom level at the peak of the flight path. If + /// `options.curve` is specified, this option is ignored. + /// @param {number} `options.speed=1.2` The average speed of the animation defined in relation to + /// `options.curve`. A speed of 1.2 means that the map appears to move along the flight path + /// by 1.2 times `options.curve` screenfuls every second. A _screenful_ is the map's visible span. + /// It does not correspond to a fixed physical distance, but varies by zoom level. + /// @param {number} `options.screenSpeed` The average speed of the animation measured in screenfuls + /// per second, assuming a linear timing curve. If `options.speed` is specified, this option is ignored. + /// @param {number} `options.maxDuration` The animation's maximum duration, measured in milliseconds. + /// If duration exceeds maximum duration, it resets to 0. + /// @param eventData Additional properties to be added to event objects of events triggered by this method. + /// @fires movestart + /// @fires zoomstart + /// @fires pitchstart + /// @fires move + /// @fires zoom + /// @fires rotate + /// @fires pitch + /// @fires moveend + /// @fires zoomend + /// @fires pitchend + /// @returns {MapboxMap} `this` + /// @example + /// // fly with default options to null island + /// map.flyTo({center: [0, 0], zoom: 9}); + /// // using flyTo options + /// map.flyTo({ + /// center: [0, 0], + /// zoom: 9, + /// speed: 0.2, + /// curve: 1, + /// easing(t) { + /// return t; + /// } + /// }); + /// @see [Fly to a location](https://www.mapbox.com/mapbox-gl-js/example/flyto/) + /// @see [Slowly fly to a location](https://www.mapbox.com/mapbox-gl-js/example/flyto-options/) + /// @see [Fly to a location based on scroll position](https://www.mapbox.com/mapbox-gl-js/example/scroll-fly-to/) + external MapboxMapJsImpl flyTo(dynamic options, [dynamic eventData]); + + external bool isEasing(); + + /// Stops any animated transition underway. + /// + /// @memberof MapboxMap# + /// @returns {MapboxMap} `this` + external MapboxMapJsImpl stop(); +} diff --git a/lib/src/interop/ui/events_interop.dart b/lib/src/interop/ui/events_interop.dart new file mode 100644 index 0000000..127ec2f --- /dev/null +++ b/lib/src/interop/ui/events_interop.dart @@ -0,0 +1,77 @@ +@JS('mapboxgl') +library mapboxgl.interop.ui.events; + +import 'dart:html'; +import 'package:js/js.dart'; +import 'package:mapbox_gl_dart/src/interop/interop.dart'; + +@JS() +@anonymous +abstract class MapMouseEventJsImpl { + /// The event type. + external String get type; + + /// The `MapboxMap` object that fired the event. + external MapboxMapJsImpl get target; + + /// The DOM event which caused the map event. + external MouseEvent get originalEvent; + + /// The pixel coordinates of the mouse cursor, relative to the map and measured from the top left corner. + external Point get point; + + /// The geographic location on the map of the mouse cursor. + external LngLatJsImpl get lngLat; + + /// Prevents subsequent default processing of the event by the map. + /// + /// Calling this method will prevent the following default map behaviors: + /// + /// * On `mousedown` events, the behavior of {@link DragPanHandler} + /// * On `mousedown` events, the behavior of {@link DragRotateHandler} + /// * On `mousedown` events, the behavior of {@link BoxZoomHandler} + /// * On `dblclick` events, the behavior of {@link DoubleClickZoomHandler} + external preventDefault(); + + /// `true` if `preventDefault` has been called. + external bool get defaultPrevented; +} + +@JS() +@anonymous +abstract class MapTouchEventJsImpl { + /// The event type. + external String get type; + + /// The `MapboxMap` object that fired the event. + external MapboxMapJsImpl get target; + + /// The DOM event which caused the map event. + external TouchEvent get originalEvent; + + /// The geographic location on the map of the center of the touch event points. + external LngLatJsImpl get lngLat; + + /// The pixel coordinates of the center of the touch event points, relative to the map and measured from the top left + /// corner. + external Point get point; + + /// The array of pixel coordinates corresponding to a + /// [touch event's `touches`](https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent/touches) property. + external List get points; + + /// The geographical locations on the map corresponding to a + /// [touch event's `touches`](https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent/touches) property. + external List get lngLats; + + /// Prevents subsequent default processing of the event by the map. + /// + /// Calling this method will prevent the following default map behaviors: + /// + /// * On `touchstart` events, the behavior of {@link DragPanHandler} + /// * On `touchstart` events, the behavior of {@link TouchZoomRotateHandler} + external preventDefault(); + + /// `true` if `preventDefault` has been called. + external bool get defaultPrevented; +} diff --git a/lib/src/interop/ui/handler/box_zoom_interop.dart b/lib/src/interop/ui/handler/box_zoom_interop.dart new file mode 100644 index 0000000..e5c6c3b --- /dev/null +++ b/lib/src/interop/ui/handler/box_zoom_interop.dart @@ -0,0 +1,34 @@ +@JS('mapboxgl') +library mapboxgl.interop.ui.handler.box_zoom; + +import 'dart:html'; + +import 'package:js/js.dart'; + +@JS() +@anonymous +abstract class BoxZoomHandlerJsImpl { + /// Returns a Boolean indicating whether the "box zoom" interaction is enabled. + /// + /// @returns {boolean} `true` if the "box zoom" interaction is enabled. + external bool isEnabled(); + + /// Returns a Boolean indicating whether the "box zoom" interaction is active, i.e. currently being used. + /// + /// @returns {boolean} `true` if the "box zoom" interaction is active. + external bool isActive(); + + /// Enables the "box zoom" interaction. + /// + /// @example + /// map.boxZoom.enable(); + external enable(); + + /// Disables the "box zoom" interaction. + /// + /// @example + /// map.boxZoom.disable(); + external disable(); + + external onMouseDown(MouseEvent e); +} diff --git a/lib/src/interop/ui/handler/dblclick_zoom_interop.dart b/lib/src/interop/ui/handler/dblclick_zoom_interop.dart new file mode 100644 index 0000000..b07b1b7 --- /dev/null +++ b/lib/src/interop/ui/handler/dblclick_zoom_interop.dart @@ -0,0 +1,35 @@ +@JS('mapboxgl') +library mapboxgl.interop.ui.handler.dbclick_zoom; + +import 'package:js/js.dart'; +import 'package:mapbox_gl_dart/src/interop/interop.dart'; + +@JS() +@anonymous +abstract class DoubleClickZoomHandlerJsImpl { + /// Returns a Boolean indicating whether the "double click to zoom" interaction is enabled. + /// + /// @returns {boolean} `true` if the "double click to zoom" interaction is enabled. + external bool isEnabled(); + + /// Returns a Boolean indicating whether the "double click to zoom" interaction is active, i.e. currently being used. + /// + /// @returns {boolean} `true` if the "double click to zoom" interaction is active. + external bool isActive(); + + /// Enables the "double click to zoom" interaction. + /// + /// @example + /// map.doubleClickZoom.enable(); + external enable(); + + /// Disables the "double click to zoom" interaction. + /// + /// @example + /// map.doubleClickZoom.disable(); + external disable(); + + external onTouchStart(MapTouchEventJsImpl e); + + external onDblClick(MapMouseEventJsImpl e); +} diff --git a/lib/src/interop/ui/handler/drag_pan_interop.dart b/lib/src/interop/ui/handler/drag_pan_interop.dart new file mode 100644 index 0000000..7e30978 --- /dev/null +++ b/lib/src/interop/ui/handler/drag_pan_interop.dart @@ -0,0 +1,36 @@ +@JS('mapboxgl') +library mapboxgl.interop.ui.handler.drag_pan; + +import 'dart:html'; + +import 'package:js/js.dart'; + +@JS() +@anonymous +abstract class DragPanHandlerJsImpl { + /// Returns a Boolean indicating whether the "drag to pan" interaction is enabled. + /// + /// @returns {boolean} `true` if the "drag to pan" interaction is enabled. + external bool isEnabled(); + + /// Returns a Boolean indicating whether the "drag to pan" interaction is active, i.e. currently being used. + /// + /// @returns {boolean} `true` if the "drag to pan" interaction is active. + external bool isActive(); + + /// Enables the "drag to pan" interaction. + /// + /// @example + /// map.dragPan.enable(); + external enable(); + + /// Disables the "drag to pan" interaction. + /// + /// @example + /// map.dragPan.disable(); + external disable(); + + external onMouseDown(MouseEvent e); + + external onTouchStart(TouchEvent e); +} diff --git a/lib/src/interop/ui/handler/drag_rotate_interop.dart b/lib/src/interop/ui/handler/drag_rotate_interop.dart new file mode 100644 index 0000000..b5db76d --- /dev/null +++ b/lib/src/interop/ui/handler/drag_rotate_interop.dart @@ -0,0 +1,34 @@ +@JS('mapboxgl') +library mapboxgl.interop.ui.handler.drag_rotate; + +import 'dart:html'; + +import 'package:js/js.dart'; + +@JS() +@anonymous +abstract class DragRotateHandlerJsImpl { + /// Returns a Boolean indicating whether the "drag to rotate" interaction is enabled. + /// + /// @returns {boolean} `true` if the "drag to rotate" interaction is enabled. + external bool isEnabled(); + + /// Returns a Boolean indicating whether the "drag to rotate" interaction is active, i.e. currently being used. + /// + /// @returns {boolean} `true` if the "drag to rotate" interaction is active. + external bool isActive(); + + /// Enables the "drag to rotate" interaction. + /// + /// @example + /// map.dragRotate.enable(); + external enable(); + + /// Disables the "drag to rotate" interaction. + /// + /// @example + /// map.dragRotate.disable(); + external disable(); + + external onMouseDown(MouseEvent e); +} diff --git a/lib/src/interop/ui/handler/keyboard_interop.dart b/lib/src/interop/ui/handler/keyboard_interop.dart new file mode 100644 index 0000000..084ac91 --- /dev/null +++ b/lib/src/interop/ui/handler/keyboard_interop.dart @@ -0,0 +1,25 @@ +@JS('mapboxgl') +library mapboxgl.interop.ui.handler.keyboard; + +import 'package:js/js.dart'; + +@JS() +@anonymous +abstract class KeyboardHandlerJsImpl { + /// Returns a Boolean indicating whether keyboard interaction is enabled. + /// + /// @returns {boolean} `true` if keyboard interaction is enabled. + external bool isEnabled(); + + /// Enables keyboard interaction. + /// + /// @example + /// map.keyboard.enable(); + external bool enable(); + + /// Disables keyboard interaction. + /// + /// @example + /// map.keyboard.disable(); + external bool disable(); +} diff --git a/lib/src/interop/ui/handler/scroll_zoom_interop.dart b/lib/src/interop/ui/handler/scroll_zoom_interop.dart new file mode 100644 index 0000000..c4bf1e0 --- /dev/null +++ b/lib/src/interop/ui/handler/scroll_zoom_interop.dart @@ -0,0 +1,49 @@ +@JS('mapboxgl') +library mapboxgl.interop.ui.handler.scroll_zoom; + +import 'dart:html'; + +import 'package:js/js.dart'; + +@JS() +@anonymous +abstract class ScrollZoomHandlerJsImpl { + /// Set the zoom rate of a trackpad + /// @param {number} [zoomRate = 1/100] + external setZoomRate(num zoomRate); + + /// Set the zoom rate of a mouse wheel + /// @param {number} [wheelZoomRate = 1/450] + external setWheelZoomRate(num wheelZoomRate); + + /// Returns a Boolean indicating whether the "scroll to zoom" interaction is enabled. + /// + /// @returns {boolean} `true` if the "scroll to zoom" interaction is enabled. + external bool isEnabled(); + + /// Active state is turned on and off with every scroll wheel event and is set back to false before the map + /// render is called, so _active is not a good candidate for determining if a scroll zoom animation is in + /// progress. + external bool isActive(); + + external bool isZooming(); + + /// Enables the "scroll to zoom" interaction. + /// + /// @param {Object} [options] + /// @param {string} `options.around` If "center" is passed, map will zoom around center of map + /// + /// @example + /// map.scrollZoom.enable(); + /// @example + /// map.scrollZoom.enable({ around: 'center' }) + external enable(dynamic options); + + /// Disables the "scroll to zoom" interaction. + /// + /// @example + /// map.scrollZoom.disable(); + external disable(); + + external onWheel(WheelEvent e); +} diff --git a/lib/src/interop/ui/handler/touch_zoom_rotate_interop.dart b/lib/src/interop/ui/handler/touch_zoom_rotate_interop.dart new file mode 100644 index 0000000..7745d0b --- /dev/null +++ b/lib/src/interop/ui/handler/touch_zoom_rotate_interop.dart @@ -0,0 +1,48 @@ +@JS('mapboxgl') +library mapboxgl.interop.ui.handler.touch_zoom_rotate; + +import 'dart:html'; + +import 'package:js/js.dart'; + +@JS() +@anonymous +abstract class TouchZoomRotateHandlerJsImpl { + /// Returns a Boolean indicating whether the "pinch to rotate and zoom" interaction is enabled. + /// + /// @returns {boolean} `true` if the "pinch to rotate and zoom" interaction is enabled. + external bool isEnabled(); + + /// Enables the "pinch to rotate and zoom" interaction. + /// + /// @param {Object} [options] + /// @param {string} `options.around` If "center" is passed, map will zoom around the center + /// + /// @example + /// map.touchZoomRotate.enable(); + /// @example + /// map.touchZoomRotate.enable({ around: 'center' }); + external enable(dynamic options); + + /// Disables the "pinch to rotate and zoom" interaction. + /// + /// @example + /// map.touchZoomRotate.disable(); + external disable(); + + /// Disables the "pinch to rotate" interaction, leaving the "pinch to zoom" + /// interaction enabled. + /// + /// @example + /// map.touchZoomRotate.disableRotation(); + external disableRotation(); + + /// Enables the "pinch to rotate" interaction. + /// + /// @example + /// map.touchZoomRotate.enable(); + /// map.touchZoomRotate.enableRotation(); + external enableRotation(); + + external onStart(TouchEvent e); +} diff --git a/lib/src/interop/ui/map_interop.dart b/lib/src/interop/ui/map_interop.dart new file mode 100644 index 0000000..26b1708 --- /dev/null +++ b/lib/src/interop/ui/map_interop.dart @@ -0,0 +1,1279 @@ +@JS('mapboxgl') +library mapboxgl.interop.ui.map; + +import 'dart:html'; +import 'package:js/js.dart'; +import 'package:mapbox_gl_dart/src/interop/interop.dart'; + +/// The `MapboxMap` object represents the map on your page. It exposes methods +/// and properties that enable you to programmatically change the map, +/// and fires events as users interact with it. +/// +/// You create a `MapboxMap` by specifying a `container` and other options. +/// Then Mapbox GL JS initializes the map on the page and returns your `MapboxMap` +/// object. +/// +/// ```dart +/// var map = MapboxMap( +/// MapOptions( +/// container: 'map', +/// center: LngLat(-122.420679, 37.772537), +/// zoom: 13, +/// style: 'mapbox://styles/mapbox/satellite-streets-v11', +/// hash: true, +/// transformRequest: (url, resourceType) { +/// if (resourceType == 'Source' && url.startsWith('http://myHost')) { +/// return xr( +/// url: url.replaceAll('http', 'https'), +/// headers: {'my-custom-header': true}, +/// credentials: 'include', +/// ); +/// } +/// return RequestParameters(url: url); +/// }, +/// ), +/// ); +/// ``` +/// @see [Display a map](https://www.mapbox.com/mapbox-gl-js/examples/) +@JS('Map') +class MapboxMapJsImpl extends CameraJsImpl { + external factory MapboxMapJsImpl(MapOptionsJsImpl options); + + external StyleJsImpl get style; + external dynamic get painter; + + /// The map's {@link ScrollZoomHandler}, which implements zooming in and out with a scroll wheel or trackpad. + /// Find more details and examples using `scrollZoom` in the {@link ScrollZoomHandler} section. + external ScrollZoomHandlerJsImpl get scrollZoom; + + /// The map's {@link BoxZoomHandler}, which implements zooming using a drag gesture with the Shift key pressed. + /// Find more details and examples using `boxZoom` in the {@link BoxZoomHandler} section. + external BoxZoomHandlerJsImpl get boxZoom; + + /// The map's {@link DragRotateHandler}, which implements rotating the map while dragging with the right + /// mouse button or with the Control key pressed. Find more details and examples using `dragRotate` + /// in the {@link DragRotateHandler} section. + external DragRotateHandlerJsImpl get dragRotate; + + /// The map's {@link DragPanHandler}, which implements dragging the map with a mouse or touch gesture. + /// Find more details and examples using `dragPan` in the {@link DragPanHandler} section. + external DragPanHandlerJsImpl get dragPan; + + /// The map's {@link KeyboardHandler}, which allows the user to zoom, rotate, and pan the map using keyboard + /// shortcuts. Find more details and examples using `keyboard` in the {@link KeyboardHandler} section. + external KeyboardHandlerJsImpl get keyboard; + + /// The map's {@link DoubleClickZoomHandler}, which allows the user to zoom by double clicking. + /// Find more details and examples using `doubleClickZoom` in the {@link DoubleClickZoomHandler} section. + external DoubleClickZoomHandlerJsImpl get doubleClickZoom; + + /// The map's {@link TouchZoomRotateHandler}, which allows the user to zoom or rotate the map with touch gestures. + /// Find more details and examples using `touchZoomRotate` in the {@link TouchZoomRotateHandler} section. + external TouchZoomRotateHandlerJsImpl get touchZoomRotate; + + /// Adds an {@link IControl} to the map, calling `control.onAdd(this)`. + /// + /// @param {IControl} control The {@link IControl} to add. + /// @param {string} [position] position on the map to which the control will be added. + /// Valid values are `'top-left'`, `'top-right'`, `'bottom-left'`, and `'bottom-right'`. Defaults to `'top-right'`. + /// @returns {MapboxMap} `this` + /// @example + /// // Add zoom and rotation controls to the map. + /// map.addControl(new NavigationControl()); + /// @see [Display map navigation controls](https://www.mapbox.com/mapbox-gl-js/example/navigation/) + external MapboxMapJsImpl addControl(IControlJsImpl control, + [String position]); + + /// Removes the control from the map. + /// + /// @param {IControl} control The {@link IControl} to remove. + /// @returns {MapboxMap} `this` + /// @example + /// // Define a new navigation control. + /// var navigation = new NavigationControl(); + /// // Add zoom and rotation controls to the map. + /// map.addControl(navigation); + /// // Remove zoom and rotation controls from the map. + /// map.removeControl(navigation); + external MapboxMapJsImpl removeControl(IControlJsImpl control); + + /// Resizes the map according to the dimensions of its + /// `container` element. + /// + /// Checks if the map container size changed and updates the map if it has changed. + /// This method must be called after the map's `container` is resized programmatically + /// or when the map is shown after being initially hidden with CSS. + /// + /// @param eventData Additional properties to be passed to `movestart`, `move`, `resize`, and `moveend` + /// events that get triggered as a result of resize. This can be useful for differentiating the + /// source of an event (for example, user-initiated or programmatically-triggered events). + /// @returns {MapboxMap} `this` + /// @example + /// // Resize the map when the map container is shown + /// // after being initially hidden with CSS. + /// var mapDiv = document.getElementById('map'); + /// if (mapDiv.style.visibility === true) map.resize(); + external MapboxMapJsImpl resize([dynamic eventData]); + + /// Returns the map's geographical bounds. When the bearing or pitch is non-zero, the visible region is not + /// an axis-aligned rectangle, and the result is the smallest bounds that encompasses the visible region. + /// @example + /// var bounds = map.getBounds(); + external LngLatBoundsJsImpl getBounds(); + + /// Returns the maximum geographical bounds the map is constrained to, or `null` if none set. + /// @example + /// var maxBounds = map.getMaxBounds(); + external LngLatBoundsJsImpl getMaxBounds(); + + /// Sets or clears the map's geographical bounds. + /// + /// Pan and zoom operations are constrained within these bounds. + /// If a pan or zoom is performed that would + /// display regions outside these bounds, the map will + /// instead display a position and zoom level + /// as close as possible to the operation's request while still + /// remaining within the bounds. + /// + /// @param {LngLatBoundsLike | null | undefined} bounds The maximum bounds to set. If `null` or `undefined` is provided, the function removes the map's maximum bounds. + /// @returns {MapboxMap} `this` + /// @example + /// // Define bounds that conform to the `LngLatBoundsLike` object. + /// var bounds = [ + /// [-74.04728, 40.68392], // [west, south] + /// [-73.91058, 40.87764] // [east, north] + /// ]; + /// // Set the map's max bounds. + /// map.setMaxBounds(bounds); + external MapboxMapJsImpl setMaxBounds(LngLatBoundsJsImpl bounds); + + /// Sets or clears the map's minimum zoom level. + /// If the map's current zoom level is lower than the new minimum, + /// the map will zoom to the new minimum. + /// + /// It is not always possible to zoom out and reach the set `minZoom`. + /// Other factors such as map height may restrict zooming. For example, + /// if the map is 512px tall it will not be possible to zoom below zoom 0 + /// no matter what the `minZoom` is set to. + /// + /// @param {number | null | undefined} minZoom The minimum zoom level to set (-2 - 24). + /// If `null` or `undefined` is provided, the function removes the current minimum zoom (i.e. sets it to -2). + /// @returns {MapboxMap} `this` + /// @example + /// map.setMinZoom(12.25); + external MapboxMapJsImpl setMinZoom([num minZoom]); + + /// Returns the map's minimum allowable zoom level. + /// + /// @returns {number} minZoom + /// @example + /// var minZoom = map.getMinZoom(); + external num getMinZoom(); + + /// Sets or clears the map's maximum zoom level. + /// If the map's current zoom level is higher than the new maximum, + /// the map will zoom to the new maximum. + /// + /// @param {number | null | undefined} maxZoom The maximum zoom level to set. + /// If `null` or `undefined` is provided, the function removes the current maximum zoom (sets it to 22). + /// @returns {MapboxMap} `this` + /// @example + /// map.setMaxZoom(18.75); + external MapboxMapJsImpl setMaxZoom([num maxZoom]); + + /// Returns the map's maximum allowable zoom level. + /// + /// @returns {number} maxZoom + /// @example + /// var maxZoom = map.getMaxZoom(); + external num getMaxZoom(); + + /// Sets or clears the map's minimum pitch. + /// If the map's current pitch is lower than the new minimum, + /// the map will pitch to the new minimum. + /// + /// @param {number | null | undefined} minPitch The minimum pitch to set (0-60). + /// If `null` or `undefined` is provided, the function removes the current minimum pitch (i.e. sets it to 0). + /// @returns {MapboxMap} `this` + external MapboxMapJsImpl setMinPitch([num minPitch]); + + /// Returns the map's minimum allowable pitch. + /// + /// @returns {number} minPitch + external num getMinPitch(); + + /// Sets or clears the map's maximum pitch. + /// If the map's current pitch is higher than the new maximum, + /// the map will pitch to the new maximum. + /// + /// @param {number | null | undefined} maxPitch The maximum pitch to set. + /// If `null` or `undefined` is provided, the function removes the current maximum pitch (sets it to 60). + /// @returns {MapboxMap} `this` + external MapboxMapJsImpl setMaxPitch([num maxPitch]); + + /// Returns the map's maximum allowable pitch. + /// + /// @returns {number} maxPitch + external num getMaxPitch(); + + /// Returns the state of `renderWorldCopies`. If `true`, multiple copies of the world will be rendered side by side beyond -180 and 180 degrees longitude. If set to `false`: + /// - When the map is zoomed out far enough that a single representation of the world does not fill the map's entire + /// container, there will be blank space beyond 180 and -180 degrees longitude. + /// - Features that cross 180 and -180 degrees longitude will be cut in two (with one portion on the right edge of the + /// map and the other on the left edge of the map) at every zoom level. + /// @returns {boolean} renderWorldCopies + /// @example + /// var worldCopiesRendered = map.getRenderWorldCopies(); + /// @see [Render world copies](https://docs.mapbox.com/mapbox-gl-js/example/render-world-copies/) + external bool getRenderWorldCopies(); + + /// Sets the state of `renderWorldCopies`. + /// + /// @param {boolean} renderWorldCopies If `true`, multiple copies of the world will be rendered side by side beyond -180 and 180 degrees longitude. If set to `false`: + /// - When the map is zoomed out far enough that a single representation of the world does not fill the map's entire + /// container, there will be blank space beyond 180 and -180 degrees longitude. + /// - Features that cross 180 and -180 degrees longitude will be cut in two (with one portion on the right edge of the + /// map and the other on the left edge of the map) at every zoom level. + /// + /// `undefined` is treated as `true`, `null` is treated as `false`. + /// @returns {MapboxMap} `this` + /// @example + /// map.setRenderWorldCopies(true); + /// @see [Render world copies](https://docs.mapbox.com/mapbox-gl-js/example/render-world-copies/) + external MapboxMapJsImpl setRenderWorldCopies([bool renderWorldCopies]); + + /// Returns a {@link Point} representing pixel coordinates, relative to the map's `container`, + /// that correspond to the specified geographical location. + /// + /// @param {LngLatLike} lnglat The geographical location to project. + /// @returns {Point} The {@link Point} corresponding to `lnglat`, relative to the map's `container`. + /// @example + /// var coordinate = [-122.420679, 37.772537]; + /// var point = map.project(coordinate); + external Point project(LngLatJsImpl lnglat); + + /// Returns a {@link LngLat} representing geographical coordinates that correspond + /// to the specified pixel coordinates. + /// + /// @param {PointLike} point The pixel coordinates to unproject. + /// @returns {LngLat} The {@link LngLat} corresponding to `point`. + /// @example + /// map.on('click', function(e) { + /// // When the map is clicked, get the geographic coordinate. + /// var coordinate = map.unproject(e.point); + /// }); + external LngLatJsImpl unproject(Point point); + + /// Returns true if the map is panning, zooming, rotating, or pitching due to a camera animation or user gesture. + /// @example + /// var isMoving = map.isMoving(); + external bool isMoving(); + + /// Returns true if the map is zooming due to a camera animation or user gesture. + /// @example + /// var isZooming = map.isZooming(); + external bool isZooming(); + + /// Returns true if the map is rotating due to a camera animation or user gesture. + /// @example + /// map.isRotating(); + external bool isRotating(); + + /// Adds a listener for events of a specified type occurring on features in a specified style layer. + /// + /// @param {string} type The event type to listen for; one of `'mousedown'`, `'mouseup'`, `'click'`, `'dblclick'`, + /// `'mousemove'`, `'mouseenter'`, `'mouseleave'`, `'mouseover'`, `'mouseout'`, `'contextmenu'`, `'touchstart'`, + /// `'touchend'`, or `'touchcancel'`. `mouseenter` and `mouseover` events are triggered when the cursor enters + /// a visible portion of the specified layer from outside that layer or outside the map canvas. `mouseleave` + /// and `mouseout` events are triggered when the cursor leaves a visible portion of the specified layer, or leaves + /// the map canvas. + /// @param {string} layerId The ID of a style layer. Only events whose location is within a visible + /// feature in this layer will trigger the listener. The event will have a `features` property containing + /// an array of the matching features. + /// @param {Function} listener The function to be called when the event is fired. + /// @returns {MapboxMap} `this` + // Defined in evented.dart + //external MapboxMap on(String type, [dynamic layerIdOrListener, Listener listener]); + + /// Removes an event listener for layer-specific events previously added with `MapboxMap#on`. + /// + /// @param {string} type The event type previously used to install the listener. + /// @param {string} layerId The layer ID previously used to install the listener. + /// @param {Function} listener The function previously installed as a listener. + /// @returns {MapboxMap} `this` + // Defined in evented.dart + //external MapboxMap off(String type, [dynamic layerIdOrListener, Listener listener]); + + /// Returns an array of [GeoJSON](http://geojson.org/) + /// [Feature objects](https://tools.ietf.org/html/rfc7946#section-3.2) + /// representing visible features that satisfy the query parameters. + /// + /// @param {PointLike|Array} [geometry] - The geometry of the query region: + /// either a single point or southwest and northeast points describing a bounding box. + /// Omitting this parameter (i.e. calling {@link MapboxMap#queryRenderedFeatures} with zero arguments, + /// or with only a [options] argument) is equivalent to passing a bounding box encompassing the entire + /// map viewport. + /// @param {Object} [options] + /// @param {Array} `options.layers` An array of [style layer IDs](https://docs.mapbox.com/mapbox-gl-js/style-spec/#layer-id) for the query to inspect. + /// Only features within these layers will be returned. If this parameter is undefined, all layers will be checked. + /// @param {Array} `options.filter` A [filter](https://www.mapbox.com/mapbox-gl-js/style-spec/#other-filter) + /// to limit query results. + /// @param {boolean} [options.validate=true] Whether to check if the `options.filter` conforms to the Mapbox GL Style Specification. Disabling validation is a performance optimization that should only be used if you have previously validated the values you will be passing to this function. + /// + /// @returns {Array} An array of [GeoJSON](http://geojson.org/) + /// [feature objects](https://tools.ietf.org/html/rfc7946#section-3.2). + /// + /// The `properties` value of each returned feature object contains the properties of its source feature. For GeoJSON sources, only + /// string and numeric property values are supported (i.e. `null`, `Array`, and `Object` values are not supported). + /// + /// Each feature includes top-level `layer`, `source`, and `sourceLayer` properties. The `layer` property is an object + /// representing the style layer to which the feature belongs. Layout and paint properties in this object contain values + /// which are fully evaluated for the given zoom level and feature. + /// + /// Only features that are currently rendered are included. Some features will////// not** be included, like: + /// + /// - Features from layers whose `visibility` property is `"none"`. + /// - Features from layers whose zoom range excludes the current zoom level. + /// - Symbol features that have been hidden due to text or icon collision. + /// + /// Features from all other layers are included, including features that may have no visible + /// contribution to the rendered result; for example, because the layer's opacity or color alpha component is set to + /// 0. + /// + /// The topmost rendered feature appears first in the returned array, and subsequent features are sorted by + /// descending z-order. Features that are rendered multiple times (due to wrapping across the antimeridian at low + /// zoom levels) are returned only once (though subject to the following caveat). + /// + /// Because features come from tiled vector data or GeoJSON data that is converted to tiles internally, feature + /// geometries may be split or duplicated across tile boundaries and, as a result, features may appear multiple + /// times in query results. For example, suppose there is a highway running through the bounding rectangle of a query. + /// The results of the query will be those parts of the highway that lie within the map tiles covering the bounding + /// rectangle, even if the highway extends into other tiles, and the portion of the highway within each map tile + /// will be returned as a separate feature. Similarly, a point feature near a tile boundary may appear in multiple + /// tiles due to tile buffering. + /// + /// @example + /// // Find all features at a point + /// var features = map.queryRenderedFeatures( + /// [20, 35], + /// { layers: ['my-layer-name'] } + /// ); + /// + /// @example + /// // Find all features within a static bounding box + /// var features = map.queryRenderedFeatures( + /// [[10, 20], [30, 50]], + /// { layers: ['my-layer-name'] } + /// ); + /// + /// @example + /// // Find all features within a bounding box around a point + /// var width = 10; + /// var height = 20; + /// var features = map.queryRenderedFeatures([ + /// [point.x - width / 2, point.y - height / 2], + /// [point.x + width / 2, point.y + height / 2] + /// ], { layers: ['my-layer-name'] }); + /// + /// @example + /// // Query all rendered features from a single layer + /// var features = map.queryRenderedFeatures({ layers: ['my-layer-name'] }); + /// @see [Get features under the mouse pointer](https://www.mapbox.com/mapbox-gl-js/example/queryrenderedfeatures/) + /// @see [Highlight features within a bounding box](https://www.mapbox.com/mapbox-gl-js/example/using-box-queryrenderedfeatures/) + /// @see [Filter features within map view](https://www.mapbox.com/mapbox-gl-js/example/filter-features-within-map-view/) + external List queryRenderedFeatures(dynamic geometry, + [dynamic options]); + + /// Returns an array of [GeoJSON](http://geojson.org/) + /// [Feature objects](https://tools.ietf.org/html/rfc7946#section-3.2) + /// representing features within the specified vector tile or GeoJSON source that satisfy the query parameters. + /// + /// @param {string} sourceId The ID of the vector tile or GeoJSON source to query. + /// @param {Object} [parameters] + /// @param {string} `parameters.sourceLayer` The name of the [source layer](https://docs.mapbox.com/help/glossary/source-layer/) + /// to query./// For vector tile sources, this parameter is required.* For GeoJSON sources, it is ignored. + /// @param {Array} `parameters.filter` A [filter](https://www.mapbox.com/mapbox-gl-js/style-spec/#other-filter) + /// to limit query results. + /// @param {boolean} `parameters.validate=true` Whether to check if the `parameters.filter` conforms to the Mapbox GL Style Specification. Disabling validation is a performance optimization that should only be used if you have previously validated the values you will be passing to this function. + /// + /// @returns {Array} An array of [GeoJSON](http://geojson.org/) + /// [Feature objects](https://tools.ietf.org/html/rfc7946#section-3.2). + /// + /// In contrast to {@link MapboxMap#queryRenderedFeatures}, this function returns all features matching the query parameters, + /// whether or not they are rendered by the current style (i.e. visible). The domain of the query includes all currently-loaded + /// vector tiles and GeoJSON source tiles: this function does not check tiles outside the currently + /// visible viewport. + /// + /// Because features come from tiled vector data or GeoJSON data that is converted to tiles internally, feature + /// geometries may be split or duplicated across tile boundaries and, as a result, features may appear multiple + /// times in query results. For example, suppose there is a highway running through the bounding rectangle of a query. + /// The results of the query will be those parts of the highway that lie within the map tiles covering the bounding + /// rectangle, even if the highway extends into other tiles, and the portion of the highway within each map tile + /// will be returned as a separate feature. Similarly, a point feature near a tile boundary may appear in multiple + /// tiles due to tile buffering. + /// + /// @example + /// // Find all features in one source layer in a vector source + /// var features = map.querySourceFeatures('your-source-id', { + /// sourceLayer: 'your-source-layer' + /// }); + /// + /// @see [Highlight features containing similar data](https://www.mapbox.com/mapbox-gl-js/example/query-similar-features/) + external List querySourceFeatures( + String sourceId, dynamic parameters); + + /// Updates the map's Mapbox style object with a new value. + /// + /// If a style is already set when this is used and options.diff is set to true, the map renderer will attempt to compare the given style + /// against the map's current state and perform only the changes necessary to make the map style match the desired state. Changes in sprites + /// (images used for icons and patterns) and glyphs (fonts for label text)////// cannot** be diffed. If the sprites or fonts used in the current + /// style and the given style are different in any way, the map renderer will force a full update, removing the current style and building + /// the given one from scratch. + /// + /// + /// @param style A JSON object conforming to the schema described in the + /// [Mapbox Style Specification](https://mapbox.com/mapbox-gl-style-spec/), or a URL to such JSON. + /// @param {Object} [options] + /// @param {boolean} [options.diff=true] If false, force a 'full' update, removing the current style + /// and building the given one instead of attempting a diff-based update. + /// @param {string} [options.localIdeographFontFamily='sans-serif'] Defines a CSS + /// font-family for locally overriding generation of glyphs in the 'CJK Unified Ideographs', 'Hiragana', 'Katakana' and 'Hangul Syllables' ranges. + /// In these ranges, font settings from the map's style will be ignored, except for font-weight keywords (light/regular/medium/bold). + /// Set to `false`, to enable font settings from the map's style for these glyph ranges. + /// Forces a full update. + /// @returns {MapboxMap} `this` + /// + /// @example + /// map.setStyle("mapbox://styles/mapbox/streets-v11"); + /// + /// @see [Change a map's style](https://www.mapbox.com/mapbox-gl-js/example/setstyle/) + external MapboxMapJsImpl setStyle(dynamic style, [dynamic options]); + + /// Returns the map's Mapbox style object, which can be used to recreate the map's style. + /// + /// @returns {Object} The map's style object. + /// + /// @example + /// var styleJson = map.getStyle(); + external dynamic getStyle(); + + /// Returns a Boolean indicating whether the map's style is fully loaded. + /// + /// @returns {boolean} A Boolean indicating whether the style is fully loaded. + /// + /// @example + /// var styleLoadStatus = map.isStyleLoaded(); + external bool isStyleLoaded(); + + /// Adds a source to the map's style. + /// + /// @param {string} id The ID of the source to add. Must not conflict with existing sources. + /// @param {Object} source The source object, conforming to the + /// Mapbox Style Specification's [source definition](https://www.mapbox.com/mapbox-gl-style-spec/#sources) or + /// {@link CanvasSourceOptions}. + /// @fires source.add + /// @returns {MapboxMap} `this` + /// @example + /// map.addSource('my-data', { + /// type: 'vector', + /// url: 'mapbox://myusername.tilesetid' + /// }); + /// @example + /// map.addSource('my-data', { + /// "type": "geojson", + /// "data": { + /// "type": "Feature", + /// "geometry": { + /// "type": "Point", + /// "coordinates": [-77.0323, 38.9131] + /// }, + /// "properties": { + /// "title": "Mapbox DC", + /// "marker-symbol": "monument" + /// } + /// } + /// }); + /// @see Vector source: [Show and hide layers](https://docs.mapbox.com/mapbox-gl-js/example/toggle-layers/) + /// @see GeoJSON source: [Add live realtime data](https://docs.mapbox.com/mapbox-gl-js/example/live-geojson/) + /// @see Raster DEM source: [Add hillshading](https://docs.mapbox.com/mapbox-gl-js/example/hillshade/) + external MapboxMapJsImpl addSource(String id, dynamic source); + + /// Returns a Boolean indicating whether the source is loaded. + /// + /// @param {string} id The ID of the source to be checked. + /// @returns {boolean} A Boolean indicating whether the source is loaded. + /// @example + /// var sourceLoaded = map.isSourceLoaded('bathymetry-data'); + external bool isSourceLoaded(String id); + + /// Returns a Boolean indicating whether all tiles in the viewport from all sources on + /// the style are loaded. + /// + /// @returns {boolean} A Boolean indicating whether all tiles are loaded. + /// @example + /// var tilesLoaded = map.areTilesLoaded(); + external bool areTilesLoaded(); + + /// Adds a/// *custom source type**(#Custom Sources), making it available for use with + /// {@link MapboxMap#addSource}. + /// @private + /// @param {string} name The name of the source type; source definition objects use this name in the `{type: ...}` field. + /// @param {Function} SourceType A {@link Source} constructor. + /// @param {Function} callback Called when the source type is ready or with an error argument if there is an error. + external addSourceType(String name, dynamic sourceType, Function callback); + + /// Removes a source from the map's style. + /// + /// @param {string} id The ID of the source to remove. + /// @returns {MapboxMap} `this` + /// @example + /// map.removeSource('bathymetry-data'); + external removeSource(String id); + + /// Returns the source with the specified ID in the map's style. + /// + /// @param {string} id The ID of the source to get. + /// @returns {?Object} The style source with the specified ID, or `undefined` + /// if the ID corresponds to no existing sources. + /// @example + /// var sourceObject = map.getSource('points'); + /// @see [Create a draggable point](https://www.mapbox.com/mapbox-gl-js/example/drag-a-point/) + /// @see [Animate a point](https://www.mapbox.com/mapbox-gl-js/example/animate-point-along-line/) + /// @see [Add live realtime data](https://www.mapbox.com/mapbox-gl-js/example/live-geojson/) + external dynamic getSource(String id); + + /// Add an image to the style. This image can be displayed on the map like any other icon in the style's + /// [sprite](https://docs.mapbox.com/help/glossary/sprite/) using the image's ID with + /// [`icon-image`](https://docs.mapbox.com/mapbox-gl-js/style-spec/#layout-symbol-icon-image), + /// [`background-pattern`](https://docs.mapbox.com/mapbox-gl-js/style-spec/#paint-background-background-pattern), + /// [`fill-pattern`](https://docs.mapbox.com/mapbox-gl-js/style-spec/#paint-fill-fill-pattern), + /// or [`line-pattern`](https://docs.mapbox.com/mapbox-gl-js/style-spec/#paint-line-line-pattern). + /// A {@link MapboxMap#error} event will be fired if there is not enough space in the sprite to add this image. + /// + /// @param id The ID of the image. + /// @param image The image as an `HTMLImageElement`, `ImageData`, or object with `width`, `height`, and `data` + /// properties with the same format as `ImageData`. + /// @param options + /// @param options.pixelRatio The ratio of pixels in the image to physical pixels on the screen + /// @param options.sdf Whether the image should be interpreted as an SDF image + /// @param options.content `[x1, y1, x2, y2]` If `icon-text-fit` is used in a layer with this image, this option defines the part of the image that can be covered by the content in `text-field`. + /// @param options.stretchX `[[x1, x2], ...]` If `icon-text-fit` is used in a layer with this image, this option defines the part(s) of the image that can be stretched horizontally. + /// @param options.stretchY `[[y1, y2], ...]` If `icon-text-fit` is used in a layer with this image, this option defines the part(s) of the image that can be stretched vertically. + /// + /// @example + /// // If the style's sprite does not already contain an image with ID 'cat', + /// // add the image 'cat-icon.png' to the style's sprite with the ID 'cat'. + /// map.loadImage('https://upload.wikimedia.org/wikipedia/commons/thumb/6/60/Cat_silhouette.svg/400px-Cat_silhouette.svg.png', function(error, image) { + /// if (error) throw error; + /// if (!map.hasImage('cat')) map.addImage('cat', image); + /// }); + /// + /// + /// // Add a stretchable image that can be used with `icon-text-fit` + /// // In this example, the image is 600px wide by 400px high. + /// map.loadImage('https://upload.wikimedia.org/wikipedia/commons/8/89/Black_and_White_Boxed_%28bordered%29.png', function(error, image) { + /// if (error) throw error; + /// if (!map.hasImage('border-image')) { + /// map.addImage('border-image', image, { + /// content: [16, 16, 300, 384], // place text over left half of image, avoiding the 16px border + /// stretchX: [[16, 584]], // stretch everything horizontally except the 16px border + /// stretchY: [[16, 384]], // stretch everything vertically except the 16px border + /// }); + /// } + /// }); + /// + /// + /// @see Use `HTMLImageElement`: [Add an icon to the map](https://www.mapbox.com/mapbox-gl-js/example/add-image/) + /// @see Use `ImageData`: [Add a generated icon to the map](https://www.mapbox.com/mapbox-gl-js/example/add-image-generated/) + external addImage(String id, dynamic image, dynamic options); + + /// Update an existing image in a style. This image can be displayed on the map like any other icon in the style's + /// [sprite](https://docs.mapbox.com/help/glossary/sprite/) using the image's ID with + /// [`icon-image`](https://docs.mapbox.com/mapbox-gl-js/style-spec/#layout-symbol-icon-image), + /// [`background-pattern`](https://docs.mapbox.com/mapbox-gl-js/style-spec/#paint-background-background-pattern), + /// [`fill-pattern`](https://docs.mapbox.com/mapbox-gl-js/style-spec/#paint-fill-fill-pattern), + /// or [`line-pattern`](https://docs.mapbox.com/mapbox-gl-js/style-spec/#paint-line-line-pattern). + /// + /// @param id The ID of the image. + /// @param image The image as an `HTMLImageElement`, `ImageData`, or object with `width`, `height`, and `data` + /// properties with the same format as `ImageData`. + /// + /// @example + /// // If an image with the ID 'cat' already exists in the style's sprite, + /// // replace that image with a new image, 'other-cat-icon.png'. + /// if (map.hasImage('cat')) map.updateImage('cat', './other-cat-icon.png'); + external updateImage(String id, dynamic image); + + /// Check whether or not an image with a specific ID exists in the style. This checks both images + /// in the style's original [sprite](https://docs.mapbox.com/help/glossary/sprite/) and any images + /// that have been added at runtime using {@link addImage}. + /// + /// @param id The ID of the image. + /// + /// @returns {boolean} A Boolean indicating whether the image exists. + /// @example + /// // Check if an image with the ID 'cat' exists in + /// // the style's sprite. + /// var catIconExists = map.hasImage('cat'); + external bool hasImage(String id); + + /// Remove an image from a style. This can be an image from the style's original + /// [sprite](https://docs.mapbox.com/help/glossary/sprite/) or any images + /// that have been added at runtime using {@link addImage}. + /// + /// @param id The ID of the image. + /// + /// @example + /// // If an image with the ID 'cat' exists in + /// // the style's sprite, remove it. + /// if (map.hasImage('cat')) map.removeImage('cat'); + external removeImage(String id); + + /// Load an image from an external URL to be used with `MapboxMap#addImage`. External + /// domains must support [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS). + /// + /// @param {string} url The URL of the image file. Image file must be in png, webp, or jpg format. + /// @param {Function} callback Expecting `callback(error, data)`. Called when the image has loaded or with an error argument if there is an error. + /// + /// @example + /// // Load an image from an external URL. + /// map.loadImage('http://placekitten.com/50/50', function(error, image) { + /// if (error) throw error; + /// // Add the loaded image to the style's sprite with the ID 'kitten'. + /// map.addImage('kitten', image); + /// }); + /// + /// @see [Add an icon to the map](https://www.mapbox.com/mapbox-gl-js/example/add-image/) + external loadImage(String url, Function callback); + + ////// + /// Returns an Array of strings containing the IDs of all images currently available in the map. + /// This includes both images from the style's original [sprite](https://docs.mapbox.com/help/glossary/sprite/) + /// and any images that have been added at runtime using {@link addImage}. + /// + /// @returns {Array} An Array of strings containing the names of all sprites/images currently available in the map. + /// + /// @example + /// var allImages = map.listImages(); + /// + external List listImages(); + + /// Adds a [Mapbox style layer](https://docs.mapbox.com/mapbox-gl-js/style-spec/#layers) + /// to the map's style. + /// + /// A layer defines how data from a specified source will be styled. Read more about layer types + /// and available paint and layout properties in the [Mapbox Style Specification](https://docs.mapbox.com/mapbox-gl-js/style-spec/#layers). + /// + /// @param {Object | CustomLayerInterface} layer The style layer to add, conforming to the Mapbox Style Specification's + /// [layer definition](https://docs.mapbox.com/mapbox-gl-js/style-spec/#layers). + /// @param {string} [beforeId] The ID of an existing layer to insert the new layer before. + /// If this argument is omitted, the layer will be appended to the end of the layers array. + /// + /// @returns {MapboxMap} `this` + /// + /// @example + /// // Add a circle layer with a vector source. + /// map.addLayer({ + /// id: 'points-of-interest', + /// source: { + /// type: 'vector', + /// url: 'mapbox://mapbox.mapbox-streets-v8' + /// }, + /// 'source-layer': 'poi_label', + /// type: 'circle', + /// paint: { + /// // Mapbox Style Specification paint properties + /// }, + /// layout: { + /// // Mapbox Style Specification layout properties + /// } + /// }); + /// + /// @see [Create and style clusters](https://www.mapbox.com/mapbox-gl-js/example/cluster/) + /// @see [Add a vector tile source](https://www.mapbox.com/mapbox-gl-js/example/vector-source/) + /// @see [Add a WMS source](https://www.mapbox.com/mapbox-gl-js/example/wms/) + external MapboxMapJsImpl addLayer(dynamic layer, [String beforeId]); + + /// Moves a layer to a different z-position. + /// + /// @param {string} id The ID of the layer to move. + /// @param {string} [beforeId] The ID of an existing layer to insert the new layer before. + /// If this argument is omitted, the layer will be appended to the end of the layers array. + /// @returns {MapboxMap} `this` + /// + /// @example + /// // Move a layer with ID 'label' before the layer with ID 'waterways'. + /// map.moveLayer('label', 'waterways'); + external MapboxMapJsImpl moveLayer(String id, String beforeId); + + /// Removes the layer with the given ID from the map's style. + /// + /// If no such layer exists, an `error` event is fired. + /// + /// @param {string} id id of the layer to remove + /// @fires error + /// + /// @example + /// // If a layer with ID 'state-data' exists, remove it. + /// if (map.getLayer('state-data')) map.removeLayer('state-data'); + external removeLayer(String id); + + /// Returns the layer with the specified ID in the map's style. + /// + /// @param {string} id The ID of the layer to get. + /// @returns {?Object} The layer with the specified ID, or `undefined` + /// if the ID corresponds to no existing layers. + /// + /// @example + /// var stateDataLayer = map.getLayer('state-data'); + /// + /// @see [Filter symbols by toggling a list](https://www.mapbox.com/mapbox-gl-js/example/filter-markers/) + /// @see [Filter symbols by text input](https://www.mapbox.com/mapbox-gl-js/example/filter-markers-by-input/) + external dynamic getLayer(String id); + + /// Sets the zoom extent for the specified style layer. The zoom extent includes the + /// [minimum zoom level](https://docs.mapbox.com/mapbox-gl-js/style-spec/#layer-minzoom) + /// and [maximum zoom level](https://docs.mapbox.com/mapbox-gl-js/style-spec/#layer-maxzoom)) + /// at which the layer will be rendered. + /// + /// Note: For style layers using vector sources, style layers cannot be rendered at zoom levels lower than the + /// minimum zoom level of the _source layer_ because the data does not exist at those zoom levels. If the minimum + /// zoom level of the source layer is higher than the minimum zoom level defined in the style layer, the style + /// layer will not be rendered at all zoom levels in the zoom range. + /// + /// @param {string} layerId The ID of the layer to which the zoom extent will be applied. + /// @param {number} minzoom The minimum zoom to set (0-24). + /// @param {number} maxzoom The maximum zoom to set (0-24). + /// @returns {MapboxMap} `this` + /// + /// @example + /// map.setLayerZoomRange('my-layer', 2, 5); + external MapboxMapJsImpl setLayerZoomRange( + String layerId, num minzoom, num maxzoom); + + /// Sets the filter for the specified style layer. + /// + /// @param {string} layerId The ID of the layer to which the filter will be applied. + /// @param {Array | null | undefined} filter The filter, conforming to the Mapbox Style Specification's + /// [filter definition](https://www.mapbox.com/mapbox-gl-js/style-spec/#other-filter). If `null` or `undefined` is provided, the function removes any existing filter from the layer. + /// @param {Object} [options] + /// @param {boolean} [options.validate=true] Whether to check if the filter conforms to the Mapbox GL Style Specification. Disabling validation is a performance optimization that should only be used if you have previously validated the values you will be passing to this function. + /// + /// @returns {MapboxMap} `this` + /// @example + /// map.setFilter('my-layer', ['==', 'name', 'USA']); + /// + /// @see [Filter features within map view](https://www.mapbox.com/mapbox-gl-js/example/filter-features-within-map-view/) + /// @see [Highlight features containing similar data](https://www.mapbox.com/mapbox-gl-js/example/query-similar-features/) + /// @see [Create a timeline animation](https://www.mapbox.com/mapbox-gl-js/example/timeline-animation/) + external MapboxMapJsImpl setFilter(String layerId, dynamic filter, + [StyleSetterOptionsJsImpl options]); + + /// Returns the filter applied to the specified style layer. + /// + /// @param {string} layerId The ID of the style layer whose filter to get. + /// @returns {Array} The layer's filter. + external List getFilter(String layerId); + + /// Sets the value of a paint property in the specified style layer. + /// + /// @param {string} layerId The ID of the layer to set the paint property in. + /// @param {string} name The name of the paint property to set. + /// @param {*} value The value of the paint property to set. + /// Must be of a type appropriate for the property, as defined in the [Mapbox Style Specification](https://www.mapbox.com/mapbox-gl-style-spec/). + /// @param {Object} [options] + /// @param {boolean} [options.validate=true] Whether to check if `value` conforms to the Mapbox GL Style Specification. Disabling validation is a performance optimization that should only be used if you have previously validated the values you will be passing to this function. + /// @returns {MapboxMap} `this` + /// @example + /// map.setPaintProperty('my-layer', 'fill-color', '#faafee'); + /// @see [Change a layer's color with buttons](https://www.mapbox.com/mapbox-gl-js/example/color-switcher/) + /// @see [Adjust a layer's opacity](https://www.mapbox.com/mapbox-gl-js/example/adjust-layer-opacity/) + /// @see [Create a draggable point](https://www.mapbox.com/mapbox-gl-js/example/drag-a-point/) + external setPaintProperty(String layerId, String name, dynamic value, + [StyleSetterOptionsJsImpl options]); + + /// Returns the value of a paint property in the specified style layer. + /// + /// @param {string} layerId The ID of the layer to get the paint property from. + /// @param {string} name The name of a paint property to get. + /// @returns {*} The value of the specified paint property. + external dynamic getPaintProperty(String layerId, String name); + + /// Sets the value of a layout property in the specified style layer. + /// + /// @param {string} layerId The ID of the layer to set the layout property in. + /// @param {string} name The name of the layout property to set. + /// @param {*} value The value of the layout property. Must be of a type appropriate for the property, as defined in the [Mapbox Style Specification](https://www.mapbox.com/mapbox-gl-style-spec/). + /// @param {Object} [options] + /// @param {boolean} [options.validate=true] Whether to check if `value` conforms to the Mapbox GL Style Specification. Disabling validation is a performance optimization that should only be used if you have previously validated the values you will be passing to this function. + /// @returns {MapboxMap} `this` + /// @example + /// map.setLayoutProperty('my-layer', 'visibility', 'none'); + external MapboxMapJsImpl setLayoutProperty( + String layerId, String name, dynamic value, + [StyleSetterOptionsJsImpl options]); + + /// Returns the value of a layout property in the specified style layer. + /// + /// @param {string} layerId The ID of the layer to get the layout property from. + /// @param {string} name The name of the layout property to get. + /// @returns {*} The value of the specified layout property. + external dynamic getLayoutProperty(String layerId, String name); + + /// Sets the any combination of light values. + /// + /// @param light Light properties to set. Must conform to the [Mapbox Style Specification](https://www.mapbox.com/mapbox-gl-style-spec/#light). + /// @param {Object} [options] + /// @param {boolean} [options.validate=true] Whether to check if the filter conforms to the Mapbox GL Style Specification. Disabling validation is a performance optimization that should only be used if you have previously validated the values you will be passing to this function. + /// @returns {MapboxMap} `this` + external MapboxMapJsImpl setLight( + dynamic light, StyleSetterOptionsJsImpl options); + + /// Returns the value of the light object. + /// + /// @returns {Object} light Light properties of the style. + external dynamic getLight(); + + /// Sets the state of a feature. The `state` object is merged in with the existing state of the feature. + /// Features are identified by their `id` attribute, which must be an integer or a string that can be + /// cast to an integer. + /// + /// @param {Object} feature Feature identifier. Feature objects returned from + /// {@link MapboxMap#queryRenderedFeatures} or event handlers can be used as feature identifiers. + /// @param {string | number} feature.id Unique id of the feature. + /// @param {string} feature.source The Id of the vector source or GeoJSON source for the feature. + /// @param {string} `feature.sourceLayer` (optional) /// For vector tile sources, the sourceLayer is + /// required.* + /// @param {Object} state A set of key-value pairs. The values should be valid JSON types. + /// + /// This method requires the `feature.id` attribute on data sets. For GeoJSON sources without + /// feature ids, set the `generateId` option in the `GeoJSONSourceSpecification` to auto-assign them. This + /// option assigns ids based on a feature's index in the source data. If you change feature data using + /// `map.getSource('some id').setData(..)`, you may need to re-apply state taking into account updated `id` values. + external setFeatureState(dynamic feature, dynamic state); + + /// Removes feature state, setting it back to the default behavior. If only + /// source is specified, removes all states of that source. If + /// target.id is also specified, removes all keys for that feature's state. + /// If key is also specified, removes that key from that feature's state. + /// Features are identified by their `id` attribute, which must be an integer or a string that can be + /// cast to an integer. + /// @param {Object} target Identifier of where to set state: can be a source, a feature, or a specific key of feature. + /// Feature objects returned from {@link MapboxMap#queryRenderedFeatures} or event handlers can be used as feature identifiers. + /// @param {string | number} target.id (optional) Unique id of the feature. Optional if key is not specified. + /// @param {string} target.source The Id of the vector source or GeoJSON source for the feature. + /// @param {string} `target.sourceLayer` (optional) /// For vector tile sources, the sourceLayer is + /// required.* + /// @param {string} key (optional) The key in the feature state to reset. + external removeFeatureState(dynamic target, [String key]); + + /// Gets the state of a feature. + /// Features are identified by their `id` attribute, which must be an integer or a string that can be + /// cast to an integer. + /// + /// @param {Object} feature Feature identifier. Feature objects returned from + /// {@link MapboxMap#queryRenderedFeatures} or event handlers can be used as feature identifiers. + /// @param {string | number} feature.id Unique id of the feature. + /// @param {string} feature.source The Id of the vector source or GeoJSON source for the feature. + /// @param {string} `feature.sourceLayer` (optional) /// For vector tile sources, the sourceLayer is + /// required.* + /// + /// @returns {Object} The state of the feature. + external dynamic getFeatureState(dynamic feature); + + /// Returns the map's containing HTML element. + /// + /// @returns {HTMLElement} The map's container. + external HtmlElement getContainer(); + + /// Returns the HTML element containing the map's `` element. + /// + /// If you want to add non-GL overlays to the map, you should append them to this element. + /// + /// This is the element to which event bindings for map interactivity (such as panning and zooming) are + /// attached. It will receive bubbled events from child elements such as the ``, but not from + /// map controls. + /// + /// @returns {HTMLElement} The container of the map's ``. + /// @see [Create a draggable point](https://www.mapbox.com/mapbox-gl-js/example/drag-a-point/) + /// @see [Highlight features within a bounding box](https://www.mapbox.com/mapbox-gl-js/example/using-box-queryrenderedfeatures/) + external HtmlElement getCanvasContainer(); + + /// Returns the map's `` element. + /// + /// @returns {HTMLCanvasElement} The map's `` element. + /// @see [Measure distances](https://www.mapbox.com/mapbox-gl-js/example/measure/) + /// @see [Display a popup on hover](https://www.mapbox.com/mapbox-gl-js/example/popup-on-hover/) + /// @see [Center the map on a clicked symbol](https://www.mapbox.com/mapbox-gl-js/example/center-on-symbol/) + external CanvasElement getCanvas(); + + /// Returns a Boolean indicating whether the map is fully loaded. + /// + /// Returns `false` if the style is not yet fully loaded, + /// or if there has been a change to the sources or style that + /// has not yet fully loaded. + /// + /// @returns {boolean} A Boolean indicating whether the map is fully loaded. + external bool loaded(); + + /// Clean up and release all internal resources associated with this map. + /// + /// This includes DOM elements, event bindings, web workers, and WebGL resources. + /// + /// Use this method when you are done using the map and wish to ensure that it no + /// longer consumes browser resources. Afterwards, you must not call any other + /// methods on the map. + external remove(); + + /// Trigger the rendering of a single frame. Use this method with custom layers to + /// repaint the map when the layer changes. Calling this multiple times before the + /// next frame is rendered will still result in only a single frame being rendered. + external triggerRepaint(); + + /// Gets and sets a Boolean indicating whether the map will render an outline + /// around each tile and the tile ID. These tile boundaries are useful for + /// debugging. + /// + /// The uncompressed file size of the first vector source is drawn in the top left + /// corner of each tile, next to the tile ID. + /// + /// @name showTileBoundaries + /// @type {boolean} + /// @instance + /// @memberof MapboxMap + external bool get showTileBoundaries; + external set showTileBoundaries(bool value); + + /// Gets and sets a Boolean indicating whether the map will render boxes + /// around all symbols in the data source, revealing which symbols + /// were rendered or which were hidden due to collisions. + /// This information is useful for debugging. + /// + /// @name showCollisionBoxes + /// @type {boolean} + /// @instance + /// @memberof MapboxMap + external bool get showCollisionBoxes; + external set showCollisionBoxes(bool value); + + /// Gets and sets a Boolean indicating whether the map should color-code + /// each fragment to show how many times it has been shaded. + /// White fragments have been shaded 8 or more times. + /// Black fragments have been shaded 0 times. + /// This information is useful for debugging. + /// + /// @name showOverdraw + /// @type {boolean} + /// @instance + /// @memberof MapboxMap + external bool get showOverdrawInspector; + external set showOverdrawInspector(bool value); + + /// Gets and sets a Boolean indicating whether the map will + /// continuously repaint. This information is useful for analyzing performance. + /// + /// @name repaint + /// @type {boolean} + /// @instance + /// @memberof MapboxMap + external bool get repaint; + external set repaint(bool value); + + /// show vertices + external bool get vertices; + external set vertices(bool value); + + /// The version of Mapbox GL JS in use as specified in package.json, CHANGELOG.md, and the GitHub release. + /// + /// @name version + /// @instance + /// @memberof MapboxMap + /// @var {string} version + external String get version; +} + +@JS() +@anonymous +class MapOptionsJsImpl { + /// If `true`, the map's position (zoom, center latitude, center longitude, bearing, and pitch) will be synced with the hash fragment of the page's URL. + /// For example, `http://path/to/my/page.html#2.59/39.26/53.07/-24.1/60`. + /// An additional string may optionally be provided to indicate a parameter-styled hash, + /// e.g. http://path/to/my/page.html#map=2.59/39.26/53.07/-24.1/60&foo=bar, where foo + /// is a custom parameter and bar is an arbitrary hash distinct from the map hash. + /// `bool` or `String` + external dynamic get hash; + + /// If `false`, no mouse, touch, or keyboard listeners will be attached to the map, so it will not respond to interaction. + external bool get interactive; + + /// The HTML element in which Mapbox GL JS will render the map, or the element's string `id`. The specified element must have no children. + /// `HTMLElement` or `String` + external dynamic get container; + + /// The threshold, measured in degrees, that determines when the map's + /// bearing will snap to north. For example, with a `bearingSnap` of 7, if the user rotates + /// the map within 7 degrees of north, the map will automatically snap to exact north. + external num get bearingSnap; + + /// If `false`, the map's pitch (tilt) control with "drag to rotate" interaction will be disabled. + external bool get pitchWithRotate; + + /// The max number of pixels a user can shift the mouse pointer during a click for it to be considered a valid click (as opposed to a mouse drag). + external num get clickTolerance; + + /// If `true`, an {@link AttributionControl} will be added to the map. + external bool get attributionControl; + + /// String or strings to show in an {@link AttributionControl}. Only applicable if `options.attributionControl` is `true`. + /// `String` or `List` + external dynamic get customAttribution; + + /// A string representing the position of the Mapbox wordmark on the map. Valid options are `top-left`,`top-right`, `bottom-left`, `bottom-right`. + external String get logoPosition; + + /// If `true`, map creation will fail if the performance of Mapbox + /// GL JS would be dramatically worse than expected (i.e. a software renderer would be used). + external bool get failIfMajorPerformanceCaveat; + + /// If `true`, the map's canvas can be exported to a PNG using `map.getCanvas().toDataURL()`. This is `false` by default as a performance optimization. + external bool get preserveDrawingBuffer; + + /// If `true`, the gl context will be created with MSAA antialiasing, which can be useful for antialiasing custom layers. this is `false` by default as a performance optimization. + external bool get antialias; + + /// If `false`, the map won't attempt to re-request tiles once they expire per their HTTP `cacheControl`/`expires` headers. + external bool get refreshExpiredTiles; + + /// If set, the map will be constrained to the given bounds. + external LngLatBoundsJsImpl get maxBounds; + + /// If `true`, the "scroll to zoom" interaction is enabled. An `Object` value is passed as options to {@link ScrollZoomHandler#enable}. + external bool get scrollZoom; + + /// The minimum zoom level of the map (0-24). + external num get minZoom; + + /// The maximum zoom level of the map (0-24). + external num get maxZoom; + + /// The minimum pitch of the map (0-60). + external num get minPitch; + + /// The maximum pitch of the map (0-60). + external num get maxPitch; + + /// The map's Mapbox style. This must be an a JSON object conforming to + /// the schema described in the [Mapbox Style Specification](https://mapbox.com/mapbox-gl-style-spec/), or a URL to + /// such JSON. + /// + /// To load a style from the Mapbox API, you can use a URL of the form `mapbox://styles/:owner/:style`, + /// where `:owner` is your Mapbox account name and `:style` is the style ID. Or you can use one of the following + /// [the predefined Mapbox styles](https://www.mapbox.com/maps/): + /// + /// * `mapbox://styles/mapbox/streets-v11` + /// * `mapbox://styles/mapbox/outdoors-v11` + /// * `mapbox://styles/mapbox/light-v10` + /// * `mapbox://styles/mapbox/dark-v10` + /// * `mapbox://styles/mapbox/satellite-v9` + /// * `mapbox://styles/mapbox/satellite-streets-v11` + /// * `mapbox://styles/mapbox/navigation-preview-day-v4` + /// * `mapbox://styles/mapbox/navigation-preview-night-v4` + /// * `mapbox://styles/mapbox/navigation-guidance-day-v4` + /// * `mapbox://styles/mapbox/navigation-guidance-night-v4` + /// + /// Tilesets hosted with Mapbox can be style-optimized if you append `?optimize=true` to the end of your style URL, like `mapbox://styles/mapbox/streets-v11?optimize=true`. + /// Learn more about style-optimized vector tiles in our [API documentation](https://www.mapbox.com/api-documentation/maps/#retrieve-tiles). + external dynamic get style; + + /// If `true`, the "box zoom" interaction is enabled (see {@link BoxZoomHandler}). + external bool get boxZoom; + + /// If `true`, the "drag to rotate" interaction is enabled (see {@link DragRotateHandler}). + external bool get dragRotate; + + /// If `true`, the "drag to pan" interaction is enabled. An `Object` value is passed as options to {@link DragPanHandler#enable}. + external dynamic get dragPan; + + /// If `true`, keyboard shortcuts are enabled (see {@link KeyboardHandler}). + external bool get keyboard; + + /// If `true`, the "double click to zoom" interaction is enabled (see {@link DoubleClickZoomHandler}). + external bool get doubleClickZoom; + + /// If `true`, the "pinch to rotate and zoom" interaction is enabled. An `Object` value is passed as options to {@link TouchZoomRotateHandler#enable}. + external bool get touchZoomRotate; + + /// If `true`, the map will automatically resize when the browser window resizes. + external bool get trackResize; + + /// The inital geographical centerpoint of the map. If `center` is not specified in the constructor options, Mapbox GL JS will look for it in the map's style object. If it is not specified in the style, either, it will default to `[0, 0]` Note: Mapbox GL uses longitude, latitude coordinate order (as opposed to latitude, longitude) to match GeoJSON. + external LngLatJsImpl get center; + + /// The initial zoom level of the map. If `zoom` is not specified in the constructor options, Mapbox GL JS will look for it in the map's style object. If it is not specified in the style, either, it will default to `0`. + external num get zoom; + + /// The initial bearing (rotation) of the map, measured in degrees counter-clockwise from north. If `bearing` is not specified in the constructor options, Mapbox GL JS will look for it in the map's style object. If it is not specified in the style, either, it will default to `0`. + external num get bearing; + + /// The initial pitch (tilt) of the map, measured in degrees away from the plane of the screen (0-60). If `pitch` is not specified in the constructor options, Mapbox GL JS will look for it in the map's style object. If it is not specified in the style, either, it will default to `0`. + external num get pitch; + + /// The initial bounds of the map. If `bounds` is specified, it overrides `center` and `zoom` constructor options. + external LngLatBoundsJsImpl get bounds; + + /// A [`fitBounds`](#map#fitbounds) options object to use _only_ when fitting the initial `bounds` provided above. + external dynamic get fitBoundsOptions; + + /// If `true`, multiple copies of the world will be rendered side by side beyond -180 and 180 degrees longitude. If set to `false`: + /// - When the map is zoomed out far enough that a single representation of the world does not fill the map's entire + /// container, there will be blank space beyond 180 and -180 degrees longitude. + /// - Features that cross 180 and -180 degrees longitude will be cut in two (with one portion on the right edge of the + /// map and the other on the left edge of the map) at every zoom level. + external bool get renderWorldCopies; + + /// The maximum number of tiles stored in the tile cache for a given source. If omitted, the cache will be dynamically sized based on the current viewport. + external num get maxTileCacheSize; + + /// Defines a CSS + /// font-family for locally overriding generation of glyphs in the 'CJK Unified Ideographs', 'Hiragana', 'Katakana' and 'Hangul Syllables' ranges. + /// In these ranges, font settings from the map's style will be ignored, except for font-weight keywords (light/regular/medium/bold). + /// Set to `false`, to enable font settings from the map's style for these glyph ranges. Note that [Mapbox Studio](https://studio.mapbox.com/) sets this value to `false` by default. + /// The purpose of this option is to avoid bandwidth-intensive glyph server requests. (See [Use locally generated ideographs](https://www.mapbox.com/mapbox-gl-js/example/local-ideographs).) + external String get localIdeographFontFamily; + + /// A callback run before the MapboxMap makes a request for an external URL. The callback can be used to modify the url, set headers, or set the credentials property for cross-origin requests. + /// Expected to return an object with a `url` property and optionally `headers` and `credentials` properties. + external RequestTransformFunctionJsImpl + get transformRequest; //TODO: Remove JsImpl + + /// If `true`, Resource Timing API information will be collected for requests made by GeoJSON and Vector Tile web workers (this information is normally inaccessible from the main Javascript thread). Information will be returned in a `resourceTiming` property of relevant `data` events. + external bool get collectResourceTiming; + + /// Controls the duration of the fade-in/fade-out animation for label collisions, in milliseconds. This setting affects all symbol layers. This setting does not affect the duration of runtime styling transitions or raster tile cross-fading. + external num get fadeDuration; + + /// If `true`, symbols from multiple sources can collide with each other during collision detection. If `false`, collision detection is run separately for the symbols in each source. + external bool get crossSourceCollisions; + + /// If specified, map will use this token instead of the one defined in accessToken. + external String get accessToken; + + /// A patch to apply to the default localization table for UI strings, e.g. control tooltips. The `locale` object maps namespaced UI string IDs to translated strings in the target language; see `src/ui/default_locale.js` for an example with all supported string IDs. The object may specify all UI strings (thereby adding support for a new translation) or only a subset of strings (thereby patching the default translation table). + external dynamic get locale; + + external factory MapOptionsJsImpl({ + dynamic hash, + bool interactive, + dynamic container, + num bearingSnap, + bool pitchWithRotate, + bool clickTolerance, + bool attributionControl, + dynamic customAttribution, + String logoPosition, + bool failIfMajorPerformanceCaveat, + bool preserveDrawingBuffer, + bool antialias, + bool refreshExpiredTiles, + LngLatBoundsJsImpl maxBounds, + bool scrollZoom, + num minZoom, + num maxZoom, + num minPitch, + num maxPitch, + dynamic style, + bool boxZoom, + bool dragRotate, + dynamic dragPan, + bool keyboard, + bool doubleClickZoom, + bool touchZoomRotate, + bool trackResize, + LngLatJsImpl center, + num zoom, + num bearing, + num pitch, + LngLatBoundsJsImpl bounds, + dynamic fitBoundsOptions, + bool renderWorldCopies, + num maxTileCacheSize, + String localIdeographFontFamily, + RequestTransformFunctionJsImpl transformRequest, + bool collectResourceTiming, + num fadeDuration, + bool crossSourceCollisions, + String accessToken, + dynamic locale, + }); +} + +typedef RequestTransformFunctionJsImpl = RequestParametersJsImpl Function( + String url, String resourceType); + +@JS() +@anonymous +class RequestParametersJsImpl { + String url; + String credentials; + dynamic headers; + String method; + bool collectResourceTiming; + + external factory RequestParametersJsImpl({ + String url, + String credentials, + dynamic headers, + String method, + bool collectResourceTiming, + }); +} + +/// Interface for interactive controls added to the map. This is a +/// specification for implementers to model: it is not +/// an exported method or class. +/// +/// Controls must implement `onAdd` and `onRemove`, and must own an +/// element, which is often a `div` element. To use Mapbox GL JS's +/// default control styling, add the `mapboxgl-ctrl` class to your control's +/// node. +/// +/// ```dart +/// class HelloWorldControl implements IControl { +/// DivElement _divElement; +/// @override +/// String getDefaultPosition() { +/// return 'bottom-left'; +/// } +/// +/// @override +/// HtmlElement onAdd(MapboxMap map) { +/// _divElement = DivElement(); +/// _divElement.text = 'Hello World'; +/// return _divElement; +/// } +/// +/// @override +/// onRemove(MapboxMap map) { +/// _divElement.remove(); +/// } +/// } +/// ``` +@JS() +@anonymous +abstract class IControlJsImpl { + /// Register a control on the map and give it a chance to register event listeners + /// and resources. This method is called by {@link MapboxMap#addControl} + /// internally. + external HtmlElement onAdd(MapboxMapJsImpl map); + + /// Unregister a control on the map and give it a chance to detach event listeners + /// and resources. This method is called by {@link MapboxMap#removeControl} + /// internally. + external onRemove(MapboxMapJsImpl map); + + /// Optionally provide a default position for this control. If this method + /// is implemented and {@link MapboxMap#addControl} is called without the `position` + /// parameter, the value returned by getDefaultPosition will be used as the + /// control's position. + external String getDefaultPosition(); +} diff --git a/lib/src/interop/ui/marker_interop.dart b/lib/src/interop/ui/marker_interop.dart new file mode 100644 index 0000000..2d3a180 --- /dev/null +++ b/lib/src/interop/ui/marker_interop.dart @@ -0,0 +1,131 @@ +@JS('mapboxgl') +library mapboxgl.interop.ui.marker; + +import 'dart:html'; +import 'package:js/js.dart'; +import 'package:mapbox_gl_dart/src/interop/interop.dart'; + +/// Creates a marker component +/// @param {HTMLElement} [element] DOM element to use as a marker. The default is a light blue, droplet-shaped SVG marker. +/// @param {string} [anchor='center'] A string indicating the part of the Marker that should be positioned closest to the coordinate set via {@link Marker#setLngLat}. +/// Options are `'center'`, `'top'`, `'bottom'`, `'left'`, `'right'`, `'top-left'`, `'top-right'`, `'bottom-left'`, and `'bottom-right'`. +/// @param {PointLike} [offset] The offset in pixels as a {@link PointLike} object to apply relative to the element's center. Negatives indicate left and up. +/// @param {string} [color='#3FB1CE'] The color to use for the default marker if `element` is not provided. The default is light blue. +/// @param {boolean} [draggable=false] A boolean indicating whether or not a marker is able to be dragged to a new position on the map. +/// @param {number} [rotation=0] The rotation angle of the marker in degrees, relative to its respective {@link Marker#rotationAlignment} setting. A positive value will rotate the marker clockwise. +/// @param {string} [pitchAlignment='auto'] `map` aligns the `Marker` to the plane of the map. `viewport` aligns the `Marker` to the plane of the viewport. `auto` automatically matches the value of `rotationAlignment`. +/// @param {string} [rotationAlignment='auto'] `map` aligns the `Marker`'s rotation relative to the map, maintaining a bearing as the map rotates. `viewport` aligns the `Marker`'s rotation relative to the viewport, agnostic to map rotations. `auto` is equivalent to `viewport`. +/// ```dart +/// var marker = mapboxgl.Marker() +/// .setLngLat([30.5, 50.5]) +/// .addTo(map); +/// ``` +/// @see [Add custom icons with Markers](https://www.mapbox.com/mapbox-gl-js/example/custom-marker-icons/) +/// @see [Create a draggable Marker](https://www.mapbox.com/mapbox-gl-js/example/drag-a-marker/) +@JS('Marker') +class MarkerJsImpl extends EventedJsImpl { + external factory MarkerJsImpl([MarkerOptionsJsImpl options]); + + /// Attaches the marker to a map + /// @param {MapboxMap} map + /// @returns {Marker} `this` + external MarkerJsImpl addTo(MapboxMapJsImpl map); + + /// Removes the marker from a map + /// @example + /// var marker = new mapboxgl.Marker().addTo(map); + /// marker.remove(); + /// @returns {Marker} `this` + external MarkerJsImpl remove(); + + /// Get the marker's geographical location. + /// + /// The longitude of the result may differ by a multiple of 360 degrees from the longitude previously + /// set by `setLngLat` because `Marker` wraps the anchor longitude across copies of the world to keep + /// the marker on screen. + /// + /// @returns {LngLat} + external LngLatJsImpl getLngLat(); + + /// Set the marker's geographical position and move it. + /// @returns {Marker} `this` + external MarkerJsImpl setLngLat(LngLatJsImpl lnglat); + + /// Returns the `Marker`'s HTML element. + /// @returns {HtmlElement} element + external HtmlElement getElement(); + + /// Binds a Popup to the Marker + /// @param popup an instance of the `Popup` class. If undefined or null, any popup + /// set on this `Marker` instance is unset + /// @returns {Marker} `this` + external MarkerJsImpl setPopup(PopupJsImpl popup); + + /// Returns the Popup instance that is bound to the Marker + /// @returns {Popup} popup + external PopupJsImpl getPopup(); + + /// Opens or closes the bound popup, depending on the current state + /// @returns {Marker} `this` + external MarkerJsImpl togglePopup(); + + /// Get the marker's offset. + /// @returns {Point} + external Point getOffset(); + + /// Sets the offset of the marker + /// @param {PointLike} offset The offset in pixels as a {@link PointLike} object to apply relative to the element's center. Negatives indicate left and up. + /// @returns {Marker} `this` + external MarkerJsImpl setOffset(Point offset); + + /// Sets the `draggable` property and functionality of the marker + /// @param {boolean} [shouldBeDraggable=false] Turns drag functionality on/off + /// @returns {Marker} `this` + external MarkerJsImpl setDraggable(bool shouldBeDraggable); + + /// Returns true if the marker can be dragged + /// @returns {boolean} + external bool isDraggable(); + + /// Sets the `rotation` property of the marker. + /// @param {number} [rotation=0] The rotation angle of the marker (clockwise, in degrees), relative to its respective {@link Marker#rotationAlignment} setting. + /// @returns {Marker} `this` + external MarkerJsImpl setRotation(num rotation); + + /// Returns the current rotation angle of the marker (in degrees). + /// @returns {number} + external num getRotation(); + + /// Sets the `rotationAlignment` property of the marker. + /// @param {string} [alignment='auto'] Sets the `rotationAlignment` property of the marker. + /// @returns {Marker} `this` + external MarkerJsImpl setRotationAlignment(String alignment); + + /// Returns the current `rotationAlignment` property of the marker. + /// @returns {string} + external String getRotationAlignment(); + + /// Sets the `pitchAlignment` property of the marker. + /// @param {string} [alignment] Sets the `pitchAlignment` property of the marker. If alignment is 'auto', it will automatically match `rotationAlignment`. + /// @returns {Marker} `this` + external MarkerJsImpl setPitchAlignment(String alignment); + + /// Returns the current `pitchAlignment` property of the marker. + /// @returns {string} + external String getPitchAlignment(); +} + +@JS() +@anonymous +class MarkerOptionsJsImpl { + external factory MarkerOptionsJsImpl({ + HtmlElement element, + Point offset, + String anchor, + String color, + bool draggable, + num rotation, + String rotationAlignment, + String pitchAlignment, + }); +} diff --git a/lib/src/interop/ui/popup_interop.dart b/lib/src/interop/ui/popup_interop.dart new file mode 100644 index 0000000..a0c14d9 --- /dev/null +++ b/lib/src/interop/ui/popup_interop.dart @@ -0,0 +1,195 @@ +@JS('mapboxgl') +library mapboxgl.interop.ui.popup; + +import 'dart:html'; +import 'package:js/js.dart'; +import 'package:mapbox_gl_dart/src/interop/interop.dart'; + +/// A popup component. +/// +/// @param {Object} [options] +/// @param {boolean} [options.closeButton=true] If `true`, a close button will appear in the +/// top right corner of the popup. +/// @param {boolean} [options.closeOnClick=true] If `true`, the popup will closed when the +/// map is clicked. +/// @param {string} [options.anchor] - A string indicating the part of the Popup that should +/// be positioned closest to the coordinate set via {@link Popup#setLngLat}. +/// Options are `'center'`, `'top'`, `'bottom'`, `'left'`, `'right'`, `'top-left'`, +/// `'top-right'`, `'bottom-left'`, and `'bottom-right'`. If unset the anchor will be +/// dynamically set to ensure the popup falls within the map container with a preference +/// for `'bottom'`. +/// @param {number|PointLike|Object} [options.offset] - +/// A pixel offset applied to the popup's location specified as: +/// - a single number specifying a distance from the popup's location +/// - a {@link PointLike} specifying a constant offset +/// - an object of {@link Point}s specifing an offset for each anchor position +/// Negative offsets indicate left and up. +/// @param {string} [options.className] Space-separated CSS class names to add to popup container +/// @param {string} [options.maxWidth='240px'] - +/// A string that sets the CSS property of the popup's maximum width, eg `'300px'`. +/// To ensure the popup resizes to fit its content, set this property to `'none'`. +/// Available values can be found here: https://developer.mozilla.org/en-US/docs/Web/CSS/max-width +/// @example +/// var markerHeight = 50, markerRadius = 10, linearOffset = 25; +/// var popupOffsets = { +/// 'top': [0, 0], +/// 'top-left': [0,0], +/// 'top-right': [0,0], +/// 'bottom': [0, -markerHeight], +/// 'bottom-left': [linearOffset, (markerHeight - markerRadius + linearOffset) /// -1], +/// 'bottom-right': [-linearOffset, (markerHeight - markerRadius + linearOffset) /// -1], +/// 'left': [markerRadius, (markerHeight - markerRadius) /// -1], +/// 'right': [-markerRadius, (markerHeight - markerRadius) /// -1] +/// }; +/// var popup = new mapboxgl.Popup({offset: popupOffsets, className: 'my-class'}) +/// .setLngLat(e.lngLat) +/// .setHTML("

Hello World!

") +/// .setMaxWidth("300px") +/// .addTo(map); +/// @see [Display a popup](https://www.mapbox.com/mapbox-gl-js/example/popup/) +/// @see [Display a popup on hover](https://www.mapbox.com/mapbox-gl-js/example/popup-on-hover/) +/// @see [Display a popup on click](https://www.mapbox.com/mapbox-gl-js/example/popup-on-click/) +/// @see [Attach a popup to a marker instance](https://www.mapbox.com/mapbox-gl-js/example/set-popup/) +@JS('Popup') +class PopupJsImpl extends EventedJsImpl { + external dynamic get options; + + external factory PopupJsImpl([PopupOptionsJsImpl options]); + + /// Adds the popup to a map. + /// + /// @param {MapboxMap} map The Mapbox GL JS map to add the popup to. + /// @returns {Popup} `this` + external PopupJsImpl addTo(MapboxMapJsImpl map); + + /// @returns {boolean} `true` if the popup is open, `false` if it is closed. + external bool isOpen(); + + /// Removes the popup from the map it has been added to. + /// + /// @example + /// var popup = new mapboxgl.Popup().addTo(map); + /// popup.remove(); + /// @returns {Popup} `this` + external PopupJsImpl remove(); + + /// Returns the geographical location of the popup's anchor. + /// + /// The longitude of the result may differ by a multiple of 360 degrees from the longitude previously + /// set by `setLngLat` because `Popup` wraps the anchor longitude across copies of the world to keep + /// the popup on screen. + /// + /// @returns {LngLat} The geographical location of the popup's anchor. + external LngLatJsImpl getLngLat(); + + /// Sets the geographical location of the popup's anchor, and moves the popup to it. Replaces trackPointer() behavior. + /// + /// @param lnglat The geographical location to set as the popup's anchor. + /// @returns {Popup} `this` + external PopupJsImpl setLngLat(LngLatJsImpl lnglat); + + /// Tracks the popup anchor to the cursor position, on screens with a pointer device (will be hidden on touchscreens). Replaces the setLngLat behavior. + /// For most use cases, `closeOnClick` and `closeButton` should also be set to `false` here. + /// @returns {Popup} `this` + //// + external PopupJsImpl trackPointer(); + + /// Returns the `Popup`'s HTML element. + /// @returns {HtmlElement} element + external HtmlElement getElement(); + + /// Sets the popup's content to a string of text. + /// + /// This function creates a [Text](https://developer.mozilla.org/en-US/docs/Web/API/Text) node in the DOM, + /// so it cannot insert raw HTML. Use this method for security against XSS + /// if the popup content is user-provided. + /// + /// @param text Textual content for the popup. + /// @returns {Popup} `this` + /// @example + /// var popup = new mapboxgl.Popup() + /// .setLngLat(e.lngLat) + /// .setText('Hello, world!') + /// .addTo(map); + external PopupJsImpl setText(String text); + + /// Sets the popup's content to the HTML provided as a string. + /// + /// This method does not perform HTML filtering or sanitization, and must be + /// used only with trusted content. Consider {@link Popup#setText} if + /// the content is an untrusted text string. + /// + /// @param html A string representing HTML content for the popup. + /// @returns {Popup} `this` + external PopupJsImpl setHTML(String html); + + /// Returns the popup's maximum width. + /// + /// @returns {string} The maximum width of the popup. + //// + external String getMaxWidth(); + + /// Sets the popup's maximum width. This is setting the CSS property `max-width`. + /// Available values can be found here: https://developer.mozilla.org/en-US/docs/Web/CSS/max-width + /// + /// @param maxWidth A string representing the value for the maximum width. + /// @returns {Popup} `this` + external PopupJsImpl setMaxWidth(String maxWidth); + + /// Sets the popup's content to the element provided as a DOM node. + /// + /// @param htmlNode A DOM node to be used as content for the popup. + /// @returns {Popup} `this` + /// @example + /// // create an element with the popup content + /// var div = window.document.createElement('div'); + /// div.innerHTML = 'Hello, world!'; + /// var popup = new mapboxgl.Popup() + /// .setLngLat(e.lngLat) + /// .setDOMContent(div) + /// .addTo(map); + external PopupJsImpl setDOMContent(Node htmlNode); + + /// Adds a CSS class to the popup container element. + /// + /// @param {string} className Non-empty string with CSS class name to add to popup container + /// + /// @example + /// let popup = new mapboxgl.Popup() + /// popup.addClassName('some-class') + external addClassName(String className); + + /// Removes a CSS class from the popup container element. + /// + /// @param {string} className Non-empty string with CSS class name to remove from popup container + /// + /// @example + /// let popup = new mapboxgl.Popup() + /// popup.removeClassName('some-class') + external removeClassName(String className); + + /// Add or remove the given CSS class on the popup container, depending on whether the container currently has that class. + /// + /// @param {string} className Non-empty string with CSS class name to add/remove + /// + /// @returns {boolean} if the class was removed return false, if class was added, then return true + /// + /// @example + /// let popup = new mapboxgl.Popup() + /// popup.toggleClassName('toggleClass') + external bool toggleClassName(String className); +} + +@JS() +@anonymous +class PopupOptionsJsImpl { + external factory PopupOptionsJsImpl({ + bool loseButton, + bool closeButton, + bool closeOnClick, + String anchor, + dynamic offset, + String className, + String maxWidth, + }); +} diff --git a/lib/src/interop/util/evented_interop.dart b/lib/src/interop/util/evented_interop.dart new file mode 100644 index 0000000..85cbf7d --- /dev/null +++ b/lib/src/interop/util/evented_interop.dart @@ -0,0 +1,73 @@ +@JS('mapboxgl') +library mapboxgl.interop.util.evented; + +import 'dart:html'; + +import 'package:js/js.dart'; +import 'package:mapbox_gl_dart/src/interop/interop.dart'; + +typedef ListenerJsImpl = dynamic Function(EventJsImpl object); + +@JS() +@anonymous +abstract class EventJsImpl { + external String get type; + external LngLatJsImpl get lngLat; + external List get features; + external Point get point; + + external factory EventJsImpl({ + String type, + LngLatJsImpl lngLat, + List features, + Point point, + }); +} + +@JS('Evented') +abstract class EventedJsImpl { + /// Adds a listener to a specified event type. + /// + /// @param {string} type The event type to add a listen for. + /// @param {Function} listener The function to be called when the event is fired. + /// The listener function is called with the data object passed to `fire`, + /// extended with `target` and `type` properties. + /// @returns {Object} `this` + //external on(String type, Listener listener); + external MapboxMapJsImpl on(String type, + [dynamic layerIdOrListener, ListenerJsImpl listener]); + + /// Removes a previously registered event listener. + /// + /// @param {string} type The event type to remove listeners for. + /// @param {Function} listener The listener function to remove. + /// @returns {Object} `this` + //external off(String type, Listener listener); + external MapboxMapJsImpl off(String type, + [dynamic layerIdOrListener, ListenerJsImpl listener]); + + /// Adds a listener that will be called only once to a specified event type. + /// + /// The listener will be called first time the event fires after the listener is registered. + /// + /// @param {string} type The event type to listen for. + /// @param {Function} listener The function to be called when the event is fired the first time. + /// @returns {Object} `this` + external MapboxMapJsImpl once(String type, ListenerJsImpl listener); + + external fire(EventJsImpl event, [dynamic properties]); + + /// Returns a true if this instance of Evented or any forwardeed instances of Evented have a listener for the specified type. + /// + /// @param {string} type The event type + /// @returns {boolean} `true` if there is at least one registered listener for specified event type, `false` otherwise + /// @private + external listens(String type); + + /// Bubble all events fired by this instance of Evented to this parent instance of Evented. + /// + /// @private + /// @returns {Object} `this` + /// @private + external setEventedParent([EventedJsImpl parent, dynamic data]); +} diff --git a/lib/src/style/evaluation_parameters.dart b/lib/src/style/evaluation_parameters.dart index e882513..39c01da 100644 --- a/lib/src/style/evaluation_parameters.dart +++ b/lib/src/style/evaluation_parameters.dart @@ -1,21 +1,25 @@ -@JS('mapboxgl') library mapboxgl.style.evaluation_parameters; -import 'package:js/js.dart'; +import 'package:mapbox_gl_dart/src/interop/interop.dart'; -@JS() -class EvaluationParameters { - external num get zoom; - external num get now; - external num get fadeDuration; - external dynamic get zoomHistory; - external dynamic get transition; +class EvaluationParameters extends JsObjectWrapper { + num get zoom => jsObject.zoom; + num get now => jsObject.now; + num get fadeDuration => jsObject.fadeDuration; + dynamic get zoomHistory => jsObject.zoomHistory; + dynamic get transition => jsObject.transition; - external factory EvaluationParameters(num zoom, [dynamic options]); + factory EvaluationParameters(num zoom, [dynamic options]) => + EvaluationParameters.fromJsObject( + EvaluationParametersJsImpl(zoom, options)); - external bool isSupportedScript(String str); + bool isSupportedScript(String str) => jsObject.isSupportedScript(str); - external crossFadingFactor(); + crossFadingFactor() => jsObject.crossFadingFactor(); - external dynamic getCrossfadeParameters(); + dynamic getCrossfadeParameters() => jsObject.getCrossfadeParameters(); + + /// Creates a new EvaluationParameters from a [jsObject]. + EvaluationParameters.fromJsObject(EvaluationParametersJsImpl jsObject) + : super.fromJsObject(jsObject); } diff --git a/lib/src/style/layers/circle_layer.dart b/lib/src/style/layers/circle_layer.dart index 8427ed6..e9dd4a6 100644 --- a/lib/src/style/layers/circle_layer.dart +++ b/lib/src/style/layers/circle_layer.dart @@ -1,33 +1,29 @@ library mapboxgl.style.layers.circle_layer; -import 'package:js/js_util.dart'; import 'package:mapbox_gl_dart/mapbox_gl_dart.dart'; +import 'package:mapbox_gl_dart/src/interop/interop.dart'; +import 'package:meta/meta.dart'; -class CircleLayer { - String type; +class CircleLayer extends Layer { String id; - Source source; - dynamic paint; + + /// Source or String + dynamic source; + CirclePaint paint; dynamic sourceLayer; CircleLayer({ - this.id, + @required this.id, this.source, this.paint, this.sourceLayer, - }) { - type = 'circle'; - } - - dynamic toJs() { - return jsify({ - 'id': id, - 'type': type, - 'source': source.toDict(), - 'source-layer': sourceLayer, - 'paint': paint.toDict(), - }); - } + }); + + @override + get jsObject => CircleLayerJsImpl.toJs(this); + + @override + get dict => CircleLayerJsImpl.toDict(this); } class CirclePaint { @@ -39,10 +35,7 @@ class CirclePaint { this.circleColor, }); - dynamic toDict() { - return { - 'circle-radius': this.circleRadius, - 'circle-color': this.circleColor, - }; - } + get jsObject => CirclePaintJsImpl.toJs(this); + + get dict => CirclePaintJsImpl.toDict(this); } diff --git a/lib/src/style/layers/layer.dart b/lib/src/style/layers/layer.dart new file mode 100644 index 0000000..7715e68 --- /dev/null +++ b/lib/src/style/layers/layer.dart @@ -0,0 +1,9 @@ +library mapboxgl.style.layers.layer; + +abstract class Layer { + /// JS object. + dynamic get jsObject => throw Exception('jsObject not implemented!'); + + /// Dict object. + Map get dict => throw Exception('dict not implemented!'); +} diff --git a/lib/src/style/layers/layout.dart b/lib/src/style/layers/layout.dart deleted file mode 100644 index ae09b4d..0000000 --- a/lib/src/style/layers/layout.dart +++ /dev/null @@ -1,18 +0,0 @@ -library mapboxgl.style.layers.layout; - -class Layout { - String iconImage; - bool iconAllowOverlap; - - Layout({ - this.iconImage, - this.iconAllowOverlap, - }); - - dynamic toDict() { - return { - 'icon-image': iconImage, - 'icon-allow-overlap': iconAllowOverlap, - }; - } -} diff --git a/lib/src/style/layers/line_layer.dart b/lib/src/style/layers/line_layer.dart index 39d87ee..92a049c 100644 --- a/lib/src/style/layers/line_layer.dart +++ b/lib/src/style/layers/line_layer.dart @@ -1,12 +1,14 @@ library mapboxgl.style.layers.line_layer; -import 'package:js/js_util.dart'; +import 'package:mapbox_gl_dart/mapbox_gl_dart.dart'; +import 'package:mapbox_gl_dart/src/interop/interop.dart'; import 'package:meta/meta.dart'; -class LineLayer { - String type; +class LineLayer extends Layer { String id; - String source; + + /// Source or String + dynamic source; String sourceLayer; LinePaint paint; LineLayout layout; @@ -19,26 +21,13 @@ class LineLayer { this.paint, this.layout, this.filter, - }) { - type = 'line'; - } + }); - dynamic toDict() { - Map dict = { - 'id': id, - }; - if (type != null) dict['type'] = type; - if (source != null) dict['source'] = source; - if (sourceLayer != null) dict['source-layer'] = sourceLayer; - if (paint != null) dict['paint'] = paint.toDict(); - if (layout != null) dict['layout'] = layout.toDict(); - if (filter != null) dict['filter'] = filter; - return dict; - } + @override + get jsObject => LineLayerJsImpl.toJs(this); - dynamic toJs() { - return jsify(toDict()); - } + @override + get dict => LineLayerJsImpl.toDict(this); } class LinePaint { @@ -68,22 +57,9 @@ class LinePaint { this.lineGradient, }); - dynamic toDict() { - Map dict = {}; - if (lineOpacity != null) dict['line-opacity'] = lineOpacity; - if (lineColor != null) dict['line-color'] = lineColor; - if (lineTranslate != null) dict['line-translate'] = lineTranslate; - if (lineTranslateAnchor != null) - dict['line-translate-anchor'] = lineTranslateAnchor; - if (lineWidth != null) dict['line-width'] = lineWidth; - if (lineGapWidth != null) dict['line-gap-width'] = lineGapWidth; - if (lineOffset != null) dict['line-offset'] = lineOffset; - if (lineBlur != null) dict['line-blur'] = lineBlur; - if (lineDasharray != null) dict['line-dasharray'] = lineDasharray; - if (linePattern != null) dict['line-pattern'] = linePattern; - if (lineGradient != null) dict['line-gradient'] = lineGradient; - return dict; - } + get jsObject => LinePaintJsImpl.toJs(this); + + get dict => LinePaintJsImpl.toDict(this); } class LineLayout { @@ -103,14 +79,7 @@ class LineLayout { this.visibility, }); - dynamic toDict() { - Map dict = {}; - if (lineCap != null) dict['line-cap'] = lineCap; - if (lineJoin != null) dict['line-join'] = lineJoin; - if (lineMiterLimit != null) dict['line-miter-limit'] = lineMiterLimit; - if (lineRoundLimit != null) dict['line-round-limit'] = lineRoundLimit; - if (lineSortKey != null) dict['line-sort-key'] = lineSortKey; - if (visibility != null) dict['visibility'] = visibility; - return dict; - } + get jsObject => LineLayoutJsImpl.toJs(this); + + get dict => LineLayoutJsImpl.toDict(this); } diff --git a/lib/src/style/layers/symbol_layer.dart b/lib/src/style/layers/symbol_layer.dart index dc546f4..e1969c0 100644 --- a/lib/src/style/layers/symbol_layer.dart +++ b/lib/src/style/layers/symbol_layer.dart @@ -1,13 +1,15 @@ library mapboxgl.style.layers.symbol_layer; -import 'package:js/js_util.dart'; import 'package:mapbox_gl_dart/mapbox_gl_dart.dart'; +import 'package:mapbox_gl_dart/src/interop/interop.dart'; +import 'package:meta/meta.dart'; -class SymbolLayer { +class SymbolLayer extends Layer { String id; - String type; String metadata; - Source source; + + /// Source or String + dynamic source; String sourceLayer; num minZoom; num maxZoom; @@ -16,7 +18,7 @@ class SymbolLayer { SymbolPaint paint; SymbolLayer({ - this.id, + @required this.id, this.metadata, this.source, this.sourceLayer, @@ -25,29 +27,13 @@ class SymbolLayer { this.filter, this.layout, this.paint, - }) { - this.type = 'symbol'; - } + }); - dynamic toDict() { - Map dict = { - 'id': id, - }; - if (type != null) dict['type'] = type; - if (metadata != null) dict['metadata'] = metadata; - if (source != null) dict['source'] = source.toDict(); - if (sourceLayer != null) dict['source-layer'] = sourceLayer; - if (minZoom != null) dict['minzoom'] = minZoom; - if (maxZoom != null) dict['maxzoom'] = maxZoom; - if (filter != null) dict['filter'] = filter; - if (layout != null) dict['layout'] = layout.toDict(); - if (paint != null) dict['paint'] = paint.toDict(); - return dict; - } + @override + get jsObject => SymbolLayerJsImpl.toJs(this); - dynamic toJs() { - return jsify(toDict()); - } + @override + get dict => SymbolLayerJsImpl.toDict(this); } class SymbolPaint { @@ -83,26 +69,9 @@ class SymbolPaint { this.textTranslateAnchor, }); - dynamic toDict() { - Map dict = {}; - if (iconOpacity != null) dict['icon-opacity'] = iconOpacity; - if (iconColor != null) dict['icon-color'] = iconColor; - if (iconHaloColor != null) dict['icon-halo-color'] = iconHaloColor; - if (iconHaloWidth != null) dict['icon-halo-width'] = iconHaloWidth; - if (iconHaloBlur != null) dict['icon-halo-blur'] = iconHaloBlur; - if (iconTranslate != null) dict['icon-translate'] = iconTranslate; - if (iconTranslateAnchor != null) - dict['icon-translate-anchor'] = iconTranslateAnchor; - if (textOpacity != null) dict['text-opacity'] = textOpacity; - if (textColor != null) dict['text-color'] = textColor; - if (textHaloColor != null) dict['text-halo-color'] = textHaloColor; - if (textHaloWidth != null) dict['text-halo-width'] = textHaloWidth; - if (textHaloBlur != null) dict['text-halo-blur'] = textHaloBlur; - if (textTranslate != null) dict['text-translate'] = textTranslate; - if (textTranslateAnchor != null) - dict['text-translate-anchor'] = textTranslateAnchor; - return dict; - } + get jsObject => SymbolPaintJsImpl.toJs(this); + + get dict => SymbolPaintJsImpl.toDict(this); } class SymbolLayout { @@ -190,56 +159,7 @@ class SymbolLayout { this.visibility, }); - dynamic toDict() { - Map dict = {}; - if (symbolAvoidEdges != null) dict['symbol-avoid-edges'] = symbolAvoidEdges; - if (symbolSortKey != null) dict['symbol-sort-key'] = symbolSortKey; - if (symbolZOrder != null) dict['symbol-z-order'] = symbolZOrder; - if (iconAllowOverlap != null) dict['icon-allow-overlap'] = iconAllowOverlap; - if (iconIgnorePlacement != null) - dict['icon-ignore-placement'] = iconIgnorePlacement; - if (iconOptional != null) dict['icon-optional'] = iconOptional; - if (iconRotationAlignment != null) - dict['icon-rotation-alignment'] = iconRotationAlignment; - if (iconSize != null) dict['icon-size'] = iconSize; - if (iconTextFit != null) dict['icon-text-fit'] = iconTextFit; - if (iconFitPadding != null) dict['icon-fit-padding'] = iconFitPadding; - if (iconImage != null) dict['icon-image'] = iconImage; - if (iconRotate != null) dict['icon-rotate'] = iconRotate; - if (iconPadding != null) dict['icon-padding'] = iconPadding; - if (iconKeepUpright != null) dict['icon-keep-upright'] = iconKeepUpright; - if (iconOffset != null) dict['icon-offset'] = iconOffset; - if (iconAnchor != null) dict['icon-anchor'] = iconAnchor; - if (iconPitchAlignment != null) - dict['icon-pitch-alignment'] = iconPitchAlignment; - if (textPitchAlignment != null) - dict['text-pitch-alignment'] = textPitchAlignment; - if (textRotationAlignment != null) - dict['text-rotation-alignment'] = textRotationAlignment; - if (textField != null) dict['text-field'] = textField; - if (textFont != null) dict['text-font'] = textFont; - if (textSize != null) dict['text-size'] = textSize; - if (textMaxWidth != null) dict['text-max-width'] = textMaxWidth; - if (textLineHeight != null) dict['text-line-height'] = textLineHeight; - if (textLetterSpacing != null) - dict['text-letter-spacing'] = textLetterSpacing; - if (textJustify != null) dict['text-justify'] = textJustify; - if (textRadialOffset != null) dict['text-radial-offset'] = textRadialOffset; - if (textVariableAnchor != null) - dict['text-variable-anchor'] = textVariableAnchor; - if (textAnchor != null) dict['text-anchor'] = textAnchor; - if (textMaxAngle != null) dict['text-max-angle'] = textMaxAngle; - if (textWritingMode != null) dict['text-writing-mode'] = textWritingMode; - if (textRotate != null) dict['text-rotate'] = textRotate; - if (textPadding != null) dict['text-padding'] = textPadding; - if (textKeepUpright != null) dict['text-keep-upright'] = textKeepUpright; - if (textTransform != null) dict['text-transform'] = textTransform; - if (textOffset != null) dict['text-offset'] = textOffset; - if (textAllowOverlap != null) dict['text-allow-overlap'] = textAllowOverlap; - if (textIgnorePlacement != null) - dict['text-ignore-placement'] = textIgnorePlacement; - if (textOptional != null) dict['text-optional'] = textOptional; - if (visibility != null) dict['visibility'] = visibility; - return dict; - } + get jsObject => SymbolLayoutJsImpl.toJs(this); + + get dict => SymbolLayoutJsImpl.toDict(this); } diff --git a/lib/src/style/sources/geojson_source.dart b/lib/src/style/sources/geojson_source.dart index e92a149..cfba7e0 100644 --- a/lib/src/style/sources/geojson_source.dart +++ b/lib/src/style/sources/geojson_source.dart @@ -1,85 +1,26 @@ library mapboxgl.style.sources.geojson_source; -import 'package:js/js_util.dart'; import 'package:mapbox_gl_dart/mapbox_gl_dart.dart'; +import 'package:mapbox_gl_dart/src/interop/interop.dart'; -class GeoJsonSource implements Source { - String type; - FeatureCollection data; +class GeoJsonSource extends Source { + FeatureCollection get data => FeatureCollection.fromJsObject(jsObject.data); - GeoJsonSource({ - this.data, - }) { - this.type = 'geojson'; - } + factory GeoJsonSource({ + FeatureCollection data, + }) => + GeoJsonSource.fromJsObject(GeoJsonSourceJsImpl( + type: 'geojson', + data: data.jsObject, + )); - @override - toDict() { - return { - 'type': type, - 'data': data.toDict(), - }; - } + /// Creates a new GeoJsonSource from a [jsObject]. + GeoJsonSource.fromJsObject(GeoJsonSourceJsImpl jsObject) + : super.fromJsObject(jsObject); @override - toJs() { - return jsify(toDict()); - } -} - -class FeatureCollection { - String type; - List features; - FeatureCollection({ - this.features, - }) { - this.type = 'FeatureCollection'; - } - - dynamic toDict() { - return { - 'type': type, - 'features': features.map((f) => f.toDict()).toList(), - }; - } - - toJs() { - return jsify(toDict()); - } -} - -class Feature { - String type; - Map properties; - Geometry geometry; - String source; - Feature({ - this.properties, - this.geometry, - }) { - this.type = 'Feature'; - } - - dynamic toDict() { - return { - 'type': type, - 'properties': properties, - 'geometry': geometry.toDict(), - }; - } -} - -class Geometry { - String type; - List coordinates; - Geometry({ - this.type, - this.coordinates, - }); - dynamic toDict() { - return { - 'type': type, - 'coordinates': coordinates, - }; - } + get dict => { + 'type': 'geojson', + 'data': data.jsObject, + }; } diff --git a/lib/src/style/sources/source.dart b/lib/src/style/sources/source.dart index 1fd7a53..69b3744 100644 --- a/lib/src/style/sources/source.dart +++ b/lib/src/style/sources/source.dart @@ -1,6 +1,11 @@ library mapboxgl.style.sources.source; -abstract class Source { - Map toDict(); - dynamic toJs(); +abstract class Source { + final T jsObject; + + /// Creates a new JsObjectWrapper type from a [jsObject]. + Source.fromJsObject(this.jsObject); + + /// Dict object. + Map get dict => throw Exception('dict not implemented!'); } diff --git a/lib/src/style/sources/vector_source.dart b/lib/src/style/sources/vector_source.dart index 2f54db1..81d0f38 100644 --- a/lib/src/style/sources/vector_source.dart +++ b/lib/src/style/sources/vector_source.dart @@ -1,32 +1,41 @@ library mapboxgl.style.sources.vector_source; -import 'package:js/js_util.dart'; import 'package:mapbox_gl_dart/mapbox_gl_dart.dart'; +import 'package:mapbox_gl_dart/src/interop/interop.dart'; -class VectorSource implements Source { - String type; - String url; - List tiles; +class VectorSource extends Source { + String get url => jsObject.url; + List get tiles => jsObject.tiles; - VectorSource({ - this.url, - this.tiles, + factory VectorSource({ + String url, + List tiles, }) { - this.type = 'vector'; + if (url != null && tiles != null) + throw Exception('Specify only one between url and tiles'); + if (url != null) { + return VectorSource.fromJsObject(VectorSourceJsImpl( + type: 'vector', + url: url, + )); + } + return VectorSource.fromJsObject(VectorSourceJsImpl( + type: 'vector', + tiles: tiles, + )); } + /// Creates a new VectorSource from a [jsObject]. + VectorSource.fromJsObject(VectorSourceJsImpl jsObject) + : super.fromJsObject(jsObject); + @override - toDict() { + get dict { Map dict = { - 'type': type, + 'type': 'vector', }; if (url != null) dict['url'] = url; if (tiles != null) dict['tiles'] = tiles; return dict; } - - @override - toJs() { - return jsify(toDict()); - } } diff --git a/lib/src/style/style.dart b/lib/src/style/style.dart index 00f75f7..bd7874a 100644 --- a/lib/src/style/style.dart +++ b/lib/src/style/style.dart @@ -1,27 +1,29 @@ -@JS('mapboxgl') library mapboxgl.style.style; -import 'package:js/js.dart'; import 'package:mapbox_gl_dart/mapbox_gl_dart.dart'; +import 'package:mapbox_gl_dart/src/interop/interop.dart'; -@JS() -@anonymous -abstract class StyleSetterOptions { - external bool get validate; +class StyleSetterOptions extends JsObjectWrapper { + bool get validate => jsObject.validate; + + /// Creates a new StyleSetterOptions from a [jsObject]. + StyleSetterOptions.fromJsObject(StyleSetterOptionsJsImpl jsObject) + : super.fromJsObject(jsObject); } -@JS() -abstract class Style extends Evented { - loadURL(String url, dynamic options); +class Style extends JsObjectWrapper { + loadURL(String url, dynamic options) => jsObject.loadURL(url, options); - loadJSON(dynamic json, StyleSetterOptions option); + loadJSON(dynamic json, StyleSetterOptions option) => + jsObject.loadJSON(json, option.jsObject); - loaded(); + loaded() => jsObject.loaded(); - hasTransitions(); + hasTransitions() => jsObject.hasTransitions(); /// Apply queued style updates in a batch and recalculate zoom-dependent paint properties. - update(EvaluationParameters parameters); + update(EvaluationParameters parameters) => + jsObject.update(parameters.jsObject); /// Update this style's state to match the given style JSON, performing only /// the necessary mutations. @@ -31,45 +33,51 @@ abstract class Style extends Evented { /// /// @returns {boolean} true if any changes were made; false otherwise /// @private - setState(dynamic nextState); + setState(dynamic nextState) => jsObject.setState(nextState); - addImage(String id, StyleImage image); + addImage(String id, StyleImage image) => + jsObject.addImage(id, image.jsObject); - updateImage(String id, StyleImage image); + updateImage(String id, StyleImage image) => + jsObject.updateImage(id, image.jsObject); - StyleImage getImage(String id); + StyleImage getImage(String id) => + StyleImage.fromJsObject(jsObject.getImage(id)); - removeImage(String id); + removeImage(String id) => jsObject.removeImage(id); - listImages(); + listImages() => jsObject.listImages(); - addSource(String id, dynamic source, StyleSetterOptions options); + addSource(String id, dynamic source, StyleSetterOptions options) => + jsObject.addSource(id, source, options.jsObject); /// Remove a source from this stylesheet, given its id. /// @param {string} id id of the source to remove /// @throws {Error} if no source is found with the given ID - removeSource(String id); + removeSource(String id) => jsObject.removeSource(id); /// Set the data of a GeoJSON source, given its id. /// @param {string} id id of the source /// @param {GeoJSON|string} data GeoJSON source - setGeoJSONSourceData(String id, dynamic data); + setGeoJSONSourceData(String id, dynamic data) => + jsObject.setGeoJSONSourceData(id, data); /// Get a source by id. /// @param {string} id id of the desired source /// @returns {Object} source - dynamic getSource(String id); + dynamic getSource(String id) => jsObject.getSource(id); /// Add a layer to the map style. The layer will be inserted before the layer with /// ID `before`, or appended if `before` is omitted. /// @param {string} [before] ID of an existing layer to insert before - addLayer(dynamic layerObject, [String before, StyleSetterOptions options]); + addLayer(dynamic layerObject, [String before, StyleSetterOptions options]) => + jsObject.addLayer(layerObject); /// Moves a layer to a different z-position. The layer will be inserted before the layer with /// ID `before`, or appended if `before` is omitted. /// @param {string} id ID of the layer to move /// @param {string} [before] ID of an existing layer to insert before - moveLayer(String id, [String before]); + moveLayer(String id, [String before]) => jsObject.moveLayer(id); /// Remove the layer with the given id from the style. /// @@ -77,69 +85,89 @@ abstract class Style extends Evented { /// /// @param {string} id id of the layer to remove /// @fires error - removeLayer(String id); + removeLayer(String id) => jsObject.removeLayer(id); /// Return the style layer object with the given `id`. /// /// @param {string} id - id of the desired layer /// @returns {?Object} a layer, if one with the given `id` exists - dynamic getLayer(String id); + dynamic getLayer(String id) => jsObject.getLayer(id); - setLayerZoomRange(String layerId, [num minzoom, num maxzoom]); + setLayerZoomRange(String layerId, [num minzoom, num maxzoom]) => + jsObject.setLayerZoomRange(layerId); - setFilter(String layerId, dynamic filter, StyleSetterOptions options); + setFilter(String layerId, dynamic filter, StyleSetterOptions options) => + jsObject.setFilter(layerId, filter, options.jsObject); /// Get a layer's filter object /// @param {string} layer the layer to inspect /// @returns {*} the layer's filter, if any - getFilter(String layer); + getFilter(String layer) => jsObject.getFilter(layer); - setLayoutProperty( - String layerId, String name, dynamic value, StyleSetterOptions options); + setLayoutProperty(String layerId, String name, dynamic value, + StyleSetterOptions options) => + jsObject.setLayoutProperty(layerId, name, value, options.jsObject); /// Get a layout property's value from a given layer /// @param {string} layerId the layer to inspect /// @param {string} name the name of the layout property /// @returns {*} the property value - getLayoutProperty(String layerId, String name); + getLayoutProperty(String layerId, String name) => + jsObject.getLayoutProperty(layerId, name); - setPaintProperty( - String layerId, String name, dynamic value, StyleSetterOptions options); + setPaintProperty(String layerId, String name, dynamic value, + StyleSetterOptions options) => + jsObject.setPaintProperty(layerId, name, value, options.jsObject); - getPaintProperty(String layer, String name); + getPaintProperty(String layer, String name) => + jsObject.getPaintProperty(layer, name); - setFeatureState(dynamic target, dynamic state); + setFeatureState(dynamic target, dynamic state) => + jsObject.setFeatureState(target, state); - removeFeatureState(dynamic target, [String key]); + removeFeatureState(dynamic target, [String key]) => + jsObject.removeFeatureState(target); - getFeatureState(dynamic target); + getFeatureState(dynamic target) => jsObject.getFeatureState(target); - getTransition(); + getTransition() => jsObject.getTransition(); - serialize(); + serialize() => jsObject.serialize(); - querySourceFeatures(String sourceID, dynamic params); + querySourceFeatures(String sourceID, dynamic params) => + jsObject.querySourceFeatures(sourceID, params); - addSourceType(String name, dynamic sourceType, Function callback); + addSourceType(String name, dynamic sourceType, Function callback) => + jsObject.addSourceType(name, sourceType, callback); - getLight(); + getLight() => jsObject.getLight(); - setLight(dynamic lightOptions, StyleSetterOptions options); + setLight(dynamic lightOptions, StyleSetterOptions options) => + jsObject.setLight(lightOptions, options.jsObject); // Callbacks from web workers - getImages(String mapId, dynamic params, Function callback); + getImages(String mapId, dynamic params, Function callback) => + jsObject.getImages(mapId, params, callback); + + getGlyphs(String mapId, dynamic params, Function callback) => + jsObject.getGlyphs(mapId, params, callback); - getGlyphs(String mapId, dynamic params, Function callback); + getResource(String mapId, RequestParameters params, Function callback) => + jsObject.getResource(mapId, params.jsObject, callback); - getResource(String mapId, RequestParameters params, Function callback); + /// Creates a new Style from a [jsObject]. + Style.fromJsObject(StyleJsImpl jsObject) : super.fromJsObject(jsObject); } -@JS() -@anonymous -class StyleFunction { - external factory StyleFunction({ +class StyleFunction extends JsObjectWrapper { + factory StyleFunction({ dynamic base, dynamic stops, - }); + }) => + StyleFunction.fromJsObject(StyleFunctionJsImpl(base: base, stops: stops)); + + /// Creates a new StyleFunction from a [jsObject]. + StyleFunction.fromJsObject(StyleFunctionJsImpl jsObject) + : super.fromJsObject(jsObject); } diff --git a/lib/src/style/style_image.dart b/lib/src/style/style_image.dart index 494d0b3..e621364 100644 --- a/lib/src/style/style_image.dart +++ b/lib/src/style/style_image.dart @@ -1,27 +1,31 @@ -@JS('mapboxgl') library mapboxgl.style.style_image; -import 'package:js/js.dart'; -import 'package:mapbox_gl_dart/mapbox_gl_dart.dart'; +import 'package:mapbox_gl_dart/src/interop/interop.dart'; -@JS() -@anonymous -abstract class StyleImage { - external dynamic get data; - external num get pixelRatio; - external bool get sdf; - external num get version; - external bool get hasRenderCallback; - external StyleImageInterface get userImage; +class StyleImage extends JsObjectWrapper { + dynamic get data => jsObject.data; + num get pixelRatio => jsObject.pixelRatio; + bool get sdf => jsObject.sdf; + num get version => jsObject.version; + bool get hasRenderCallback => jsObject.hasRenderCallback; + StyleImageInterface get userImage => + StyleImageInterface.fromJsObject(jsObject.userImage); + + /// Creates a new EvaluationParameters from a [jsObject]. + StyleImage.fromJsObject(StyleImageJsImpl jsObject) + : super.fromJsObject(jsObject); } -@JS() -@anonymous -abstract class StyleImageInterface { - external num get width; - external num get height; - external dynamic get data; - external Function get render; - external Function(MapboxMap map, String id) get onAdd; - external Function get onRemove; +class StyleImageInterface extends JsObjectWrapper { + num get width => jsObject.width; + num get height => jsObject.height; + dynamic get data => jsObject.data; + Function get render => jsObject.render; + Function(MapboxMapJsImpl map, String id) get onAdd => + jsObject.onAdd; //TODO: Remove JsImpl + Function get onRemove => jsObject.onRemove; + + /// Creates a new EvaluationParameters from a [jsObject]. + StyleImageInterface.fromJsObject(StyleImageInterfaceJsImpl jsObject) + : super.fromJsObject(jsObject); } diff --git a/lib/src/ui/camera.dart b/lib/src/ui/camera.dart index 012e22e..bf59e80 100644 --- a/lib/src/ui/camera.dart +++ b/lib/src/ui/camera.dart @@ -1,10 +1,10 @@ -@JS('mapboxgl') library mapboxgl.ui.camera; import 'dart:html'; -import 'package:js/js.dart'; +import 'package:js/js_util.dart'; import 'package:mapbox_gl_dart/mapbox_gl_dart.dart'; +import 'package:mapbox_gl_dart/src/interop/interop.dart'; /// Options common to {@link MapboxMap#jumpTo}, {@link MapboxMap#easeTo}, and {@link MapboxMap#flyTo}, controlling the desired location, /// zoom, bearing, and pitch of the camera. All properties are optional, and when a property is omitted, the current @@ -17,22 +17,32 @@ import 'package:mapbox_gl_dart/mapbox_gl_dart.dart'; /// is "up"; for example, a bearing of 90° orients the map so that east is up. /// @property {number} pitch The desired pitch, in degrees. /// @property {LngLatLike} around If `zoom` is specified, `around` determines the point around which the zoom is centered. -@JS() -@anonymous -class CameraOptions { - external LngLat get center; - external num get zoom; - external num get bearing; - external num get pitch; - external LngLat get around; - - external factory CameraOptions({ + +class CameraOptions extends JsObjectWrapper { + LngLat get center => LngLat.fromJsObject(jsObject.center); + num get zoom => jsObject.zoom; + num get bearing => jsObject.bearing; + num get pitch => jsObject.pitch; + LngLat get around => LngLat.fromJsObject(jsObject.around); + + factory CameraOptions({ LngLat center, num zoom, num bearing, num pitch, LngLat around, - }); + }) => + CameraOptions.fromJsObject(CameraOptionsJsImpl( + center: center?.jsObject, + zoom: zoom, + bearing: bearing, + pitch: pitch, + around: around?.jsObject, + )); + + /// Creates a new CameraOptions from a [jsObject]. + CameraOptions.fromJsObject(CameraOptionsJsImpl jsObject) + : super.fromJsObject(jsObject); } /// Options common to map movement methods that involve animation, such as {@link MapboxMap#panBy} and @@ -47,22 +57,31 @@ class CameraOptions { /// @property {boolean} animate If `false`, no animation will occur. /// @property {boolean} essential If `true`, then the animation is considered essential and will not be affected by /// [`prefers-reduced-motion`](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion). -@JS() -@anonymous -class AnimationOptions { - external num get duration; - external num Function(num time) get easing; - external Point get offset; - external bool get animate; - external bool get essential; - - external factory AnimationOptions({ +class AnimationOptions extends JsObjectWrapper { + num get duration => jsObject.duration; + num Function(num time) get easing => jsObject.easing; + Point get offset => jsObject.offset; + bool get animate => jsObject.animate; + bool get essential => jsObject.essential; + + factory AnimationOptions({ num duration, num Function(num time) easing, Point offset, bool animate, bool essential, - }); + }) => + AnimationOptions.fromJsObject(AnimationOptionsJsImpl( + duration: duration, + easing: easing, + offset: offset, + animate: animate, + essential: essential, + )); + + /// Creates a new AnimationOptions from a [jsObject]. + AnimationOptions.fromJsObject(AnimationOptionsJsImpl jsObject) + : super.fromJsObject(jsObject); } /// Options for setting padding on a call to {@link MapboxMap#fitBounds}. All properties of this object must be @@ -73,29 +92,38 @@ class AnimationOptions { /// @property {number} bottom Padding in pixels from the bottom of the map canvas. /// @property {number} left Padding in pixels from the left of the map canvas. /// @property {number} right Padding in pixels from the right of the map canvas. -@JS() -@anonymous -class PaddingOptions { - external num get top; - external num get bottom; - external num get left; - external num get right; - - external factory PaddingOptions({ +class PaddingOptions extends JsObjectWrapper { + num get top => jsObject.top; + num get bottom => jsObject.bottom; + num get left => jsObject.left; + num get right => jsObject.right; + + factory PaddingOptions({ num top, num bottom, num left, num right, - }); + }) => + PaddingOptions.fromJsObject(PaddingOptionsJsImpl( + top: top, + bottom: bottom, + left: left, + right: right, + )); + + /// Creates a new PaddingOptions from a [jsObject]. + PaddingOptions.fromJsObject(PaddingOptionsJsImpl jsObject) + : super.fromJsObject(jsObject); } -@JS() -abstract class Camera extends Evented { +class Camera extends Evented { + final CameraJsImpl jsObject; + /// Returns the map's geographical centerpoint. /// /// @memberof MapboxMap# /// @returns The map's geographical centerpoint. - external LngLat getCenter(); + LngLat getCenter() => LngLat.fromJsObject(jsObject.getCenter()); /// Sets the map's geographical centerpoint. Equivalent to `jumpTo({center: center})`. /// @@ -107,7 +135,8 @@ abstract class Camera extends Evented { /// @returns {MapboxMap} `this` /// @example /// map.setCenter([-74, 38]); - external MapboxMap setCenter(LngLat center, [dynamic eventData]); + MapboxMap setCenter(LngLat center, [dynamic eventData]) => + MapboxMap.fromJsObject(jsObject.setCenter(center.jsObject)); /// Pans the map by the specified offset. /// @@ -119,8 +148,9 @@ abstract class Camera extends Evented { /// @fires moveend /// @returns {MapboxMap} `this` /// @see [Navigate the map with game-like controls](https://www.mapbox.com/mapbox-gl-js/example/game-controls/) - external MapboxMap panBy(Point offset, - [AnimationOptions options, dynamic eventData]); + MapboxMap panBy(Point offset, + [AnimationOptions options, dynamic eventData]) => + MapboxMap.fromJsObject(jsObject.panBy(offset)); /// Pans the map to the specified location, with an animated transition. /// @@ -131,14 +161,15 @@ abstract class Camera extends Evented { /// @fires movestart /// @fires moveend /// @returns {MapboxMap} `this` - external MapboxMap panTo(LngLat lnglat, - [AnimationOptions options, dynamic eventData]); + MapboxMap panTo(LngLat lnglat, + [AnimationOptions options, dynamic eventData]) => + MapboxMap.fromJsObject(jsObject.panTo(lnglat.jsObject)); /// Returns the map's current zoom level. /// /// @memberof MapboxMap# /// @returns The map's current zoom level. - external num getZoom(); + num getZoom() => jsObject.getZoom(); /// Sets the map's zoom level. Equivalent to `jumpTo({zoom: zoom})`. /// @@ -155,7 +186,8 @@ abstract class Camera extends Evented { /// @example /// // zoom the map to 5 /// map.setZoom(5); - external MapboxMap setZoom(num zoom, [dynamic eventData]); + MapboxMap setZoom(num zoom, [dynamic eventData]) => + MapboxMap.fromJsObject(jsObject.setZoom(zoom)); /// Zooms the map to the specified zoom level, with an animated transition. /// @@ -170,8 +202,8 @@ abstract class Camera extends Evented { /// @fires moveend /// @fires zoomend /// @returns {MapboxMap} `this` - external MapboxMap zoomTo(num zoom, - [AnimationOptions options, dynamic eventData]); + MapboxMap zoomTo(num zoom, [AnimationOptions options, dynamic eventData]) => + MapboxMap.fromJsObject(jsObject.zoomTo(zoom)); /// Increases the map's zoom level by 1. /// @@ -185,7 +217,8 @@ abstract class Camera extends Evented { /// @fires moveend /// @fires zoomend /// @returns {MapboxMap} `this` - external MapboxMap zoomIn([AnimationOptions options, dynamic eventData]); + MapboxMap zoomIn([AnimationOptions options, dynamic eventData]) => + MapboxMap.fromJsObject(jsObject.zoomIn()); /// Decreases the map's zoom level by 1. /// @@ -199,7 +232,8 @@ abstract class Camera extends Evented { /// @fires moveend /// @fires zoomend /// @returns {MapboxMap} `this` - external MapboxMap zoomOut([AnimationOptions options, dynamic eventData]); + MapboxMap zoomOut([AnimationOptions options, dynamic eventData]) => + MapboxMap.fromJsObject(jsObject.zoomOut()); /// Returns the map's current bearing. The bearing is the compass direction that is \"up\"; for example, a bearing /// of 90° orients the map so that east is up. @@ -207,7 +241,7 @@ abstract class Camera extends Evented { /// @memberof MapboxMap# /// @returns The map's current bearing. /// @see [Navigate the map with game-like controls](https://www.mapbox.com/mapbox-gl-js/example/game-controls/) - external num getBearing(); + num getBearing() => jsObject.getBearing(); /// Sets the map's bearing (rotation). The bearing is the compass direction that is \"up\"; for example, a bearing /// of 90° orients the map so that east is up. @@ -223,7 +257,8 @@ abstract class Camera extends Evented { /// @example /// // rotate the map to 90 degrees /// map.setBearing(90); - external MapboxMap setBearing(num bearing, [dynamic eventData]); + MapboxMap setBearing(num bearing, [dynamic eventData]) => + MapboxMap.fromJsObject(jsObject.setBearing(bearing)); /// Rotates the map to the specified bearing, with an animated transition. The bearing is the compass direction /// that is \"up\"; for example, a bearing of 90° orients the map so that east is up. @@ -235,8 +270,9 @@ abstract class Camera extends Evented { /// @fires movestart /// @fires moveend /// @returns {MapboxMap} `this` - external MapboxMap rotateTo(num bearing, - [AnimationOptions options, dynamic eventData]); + MapboxMap rotateTo(num bearing, + [AnimationOptions options, dynamic eventData]) => + MapboxMap.fromJsObject(jsObject.rotateTo(bearing)); /// Rotates the map so that north is up (0° bearing), with an animated transition. /// @@ -246,7 +282,8 @@ abstract class Camera extends Evented { /// @fires movestart /// @fires moveend /// @returns {MapboxMap} `this` - external MapboxMap resetNorth([AnimationOptions options, dynamic eventData]); + MapboxMap resetNorth([AnimationOptions options, dynamic eventData]) => + MapboxMap.fromJsObject(jsObject.resetNorth()); /// Rotates and pitches the map so that north is up (0° bearing) and pitch is 0°, with an animated transition. /// @@ -256,8 +293,8 @@ abstract class Camera extends Evented { /// @fires movestart /// @fires moveend /// @returns {MapboxMap} `this` - external MapboxMap resetNorthPitch( - [AnimationOptions options, dynamic eventData]); + MapboxMap resetNorthPitch([AnimationOptions options, dynamic eventData]) => + MapboxMap.fromJsObject(jsObject.resetNorthPitch()); /// Snaps the map so that north is up (0° bearing), if the current bearing is close enough to it (i.e. within the /// `bearingSnap` threshold). @@ -268,13 +305,14 @@ abstract class Camera extends Evented { /// @fires movestart /// @fires moveend /// @returns {MapboxMap} `this` - external MapboxMap snapToNorth([AnimationOptions options, dynamic eventData]); + MapboxMap snapToNorth([AnimationOptions options, dynamic eventData]) => + MapboxMap.fromJsObject(jsObject.snapToNorth()); /// Returns the map's current pitch (tilt). /// /// @memberof MapboxMap# /// @returns The map's current pitch, measured in degrees away from the plane of the screen. - external num getPitch(); + num getPitch() => jsObject.getPitch(); /// Sets the map's pitch (tilt). Equivalent to `jumpTo({pitch: pitch})`. /// @@ -285,7 +323,8 @@ abstract class Camera extends Evented { /// @fires movestart /// @fires moveend /// @returns {MapboxMap} `this` - external MapboxMap setPitch(num pitch, [dynamic eventData]); + MapboxMap setPitch(num pitch, [dynamic eventData]) => + MapboxMap.fromJsObject(jsObject.setPitch(pitch)); /// @memberof MapboxMap# /// @param {LatLngBoundsLike} bounds Calculate the center for these bounds in the viewport and use @@ -302,8 +341,8 @@ abstract class Camera extends Evented { /// var newCameraTransform = map.cameraForBounds(bbox, { /// padding: {top: 10, bottom:25, left: 15, right: 5} /// }); - external CameraOptions cameraForBounds(LngLatBounds bounds, - [CameraOptions options]); + CameraOptions cameraForBounds(LngLatBounds bounds, [CameraOptions options]) => + CameraOptions.fromJsObject(jsObject.cameraForBounds(bounds.jsObject)); /// Pans and zooms the map to contain its visible area within the specified geographical bounds. /// This function will also reset the map's bearing to 0 if bearing is nonzero. @@ -329,8 +368,10 @@ abstract class Camera extends Evented { /// padding: {top: 10, bottom:25, left: 15, right: 5} /// }); /// @see [Fit a map to a bounding box](https://www.mapbox.com/mapbox-gl-js/example/fitbounds/) - external MapboxMap fitBounds(LngLatBounds bounds, - [dynamic options, dynamic eventData]); + MapboxMap fitBounds(LngLatBounds bounds, + [Map options, dynamic eventData]) => + MapboxMap.fromJsObject( + jsObject.fitBounds(bounds.jsObject, jsify(options), eventData)); /// Pans, rotates and zooms the map to to fit the box made by points p0 and p1 /// once the map is rotated to the specified bearing. To zoom without rotating, @@ -359,8 +400,9 @@ abstract class Camera extends Evented { /// padding: {top: 10, bottom:25, left: 15, right: 5} /// }); /// @see [Used by BoxZoomHandler](https://www.mapbox.com/mapbox-gl-js/api/#boxzoomhandler) - external MapboxMap fitScreenCoordinates(Point p0, Point p1, num bearing, - [dynamic options, dynamic eventData]); + MapboxMap fitScreenCoordinates(Point p0, Point p1, num bearing, + [dynamic options, dynamic eventData]) => + MapboxMap.fromJsObject(jsObject.fitScreenCoordinates(p0, p1, bearing)); /// Changes any combination of center, zoom, bearing, and pitch, without /// an animated transition. The map will retain its current values for any @@ -380,7 +422,8 @@ abstract class Camera extends Evented { /// @fires zoomend /// @fires pitchend /// @returns {MapboxMap} `this` - external MapboxMap jumpTo(CameraOptions options, [dynamic eventData]); + MapboxMap jumpTo(CameraOptions options, [dynamic eventData]) => + MapboxMap.fromJsObject(jsObject.jumpTo(options.jsObject)); /// Changes any combination of center, zoom, bearing, and pitch, with an animated transition /// between old and new values. The map will retain its current values for any @@ -405,7 +448,8 @@ abstract class Camera extends Evented { /// @fires pitchend /// @returns {MapboxMap} `this` /// @see [Navigate the map with game-like controls](https://www.mapbox.com/mapbox-gl-js/example/game-controls/) - external MapboxMap easeTo(dynamic options, [dynamic eventData]); + MapboxMap easeTo(dynamic options, [dynamic eventData]) => + MapboxMap.fromJsObject(jsObject.easeTo(options)); /// Changes any combination of center, zoom, bearing, and pitch, animating the transition along a curve that /// evokes flight. The animation seamlessly incorporates zooming and panning to help @@ -463,13 +507,18 @@ abstract class Camera extends Evented { /// @see [Fly to a location](https://www.mapbox.com/mapbox-gl-js/example/flyto/) /// @see [Slowly fly to a location](https://www.mapbox.com/mapbox-gl-js/example/flyto-options/) /// @see [Fly to a location based on scroll position](https://www.mapbox.com/mapbox-gl-js/example/scroll-fly-to/) - external MapboxMap flyTo(dynamic options, [dynamic eventData]); + MapboxMap flyTo(dynamic options, [String eventData]) => + MapboxMap.fromJsObject(jsObject + .flyTo(options is CameraOptions ? options.jsObject : jsify(options))); - external bool isEasing(); + bool isEasing() => jsObject.isEasing(); /// Stops any animated transition underway. /// /// @memberof MapboxMap# /// @returns {MapboxMap} `this` - external MapboxMap stop(); + MapboxMap stop() => MapboxMap.fromJsObject(jsObject.stop()); + + /// Creates a new Camera from a [jsObject]. + Camera.fromJsObject(this.jsObject) : super.fromJsObject(jsObject); } diff --git a/lib/src/ui/events.dart b/lib/src/ui/events.dart index a2d9bb6..30cbc9b 100644 --- a/lib/src/ui/events.dart +++ b/lib/src/ui/events.dart @@ -1,27 +1,24 @@ -@JS('mapboxgl') library mapboxgl.ui.events; import 'dart:html'; -import 'package:js/js.dart'; import 'package:mapbox_gl_dart/mapbox_gl_dart.dart'; +import 'package:mapbox_gl_dart/src/interop/interop.dart'; -@JS() -@anonymous -abstract class MapMouseEvent { +class MapMouseEvent extends JsObjectWrapper { /// The event type. - external String get type; + String get type => jsObject.type; /// The `MapboxMap` object that fired the event. - external MapboxMap get target; + MapboxMap get target => MapboxMap.fromJsObject(jsObject.target); /// The DOM event which caused the map event. - external MouseEvent get originalEvent; + MouseEvent get originalEvent => jsObject.originalEvent; /// The pixel coordinates of the mouse cursor, relative to the map and measured from the top left corner. - external Point get point; + Point get point => jsObject.point; /// The geographic location on the map of the mouse cursor. - external LngLat get lngLat; + LngLat get lngLat => LngLat.fromJsObject(jsObject.lngLat); /// Prevents subsequent default processing of the event by the map. /// @@ -31,38 +28,41 @@ abstract class MapMouseEvent { /// * On `mousedown` events, the behavior of {@link DragRotateHandler} /// * On `mousedown` events, the behavior of {@link BoxZoomHandler} /// * On `dblclick` events, the behavior of {@link DoubleClickZoomHandler} - external preventDefault(); + preventDefault() => jsObject.preventDefault(); /// `true` if `preventDefault` has been called. - external bool get defaultPrevented; + bool get defaultPrevented => jsObject.defaultPrevented; + + /// Creates a new MapMouseEvent from a [jsObject]. + MapMouseEvent.fromJsObject(MapMouseEventJsImpl jsObject) + : super.fromJsObject(jsObject); } -@JS() -@anonymous -abstract class MapTouchEvent { +class MapTouchEvent extends JsObjectWrapper { /// The event type. - external String get type; + String get type => jsObject.type; /// The `MapboxMap` object that fired the event. - external MapboxMap get target; + MapboxMap get target => MapboxMap.fromJsObject(jsObject.target); /// The DOM event which caused the map event. - external TouchEvent get originalEvent; + TouchEvent get originalEvent => jsObject.originalEvent; /// The geographic location on the map of the center of the touch event points. - external LngLat get lngLat; + LngLat get lngLat => LngLat.fromJsObject(jsObject.lngLat); /// The pixel coordinates of the center of the touch event points, relative to the map and measured from the top left /// corner. - external Point get point; + Point get point => jsObject.point; /// The array of pixel coordinates corresponding to a /// [touch event's `touches`](https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent/touches) property. - external List get points; + List get points => jsObject.points; /// The geographical locations on the map corresponding to a /// [touch event's `touches`](https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent/touches) property. - external List get lngLats; + List get lngLats => + jsObject.lngLats.map((dynamic f) => LngLat.fromJsObject(f)).toList(); /// Prevents subsequent default processing of the event by the map. /// @@ -70,8 +70,12 @@ abstract class MapTouchEvent { /// /// * On `touchstart` events, the behavior of {@link DragPanHandler} /// * On `touchstart` events, the behavior of {@link TouchZoomRotateHandler} - external preventDefault(); + preventDefault() => jsObject.preventDefault(); /// `true` if `preventDefault` has been called. - external bool get defaultPrevented; + bool get defaultPrevented => jsObject.defaultPrevented; + + /// Creates a new MapTouchEvent from a [jsObject]. + MapTouchEvent.fromJsObject(MapTouchEventJsImpl jsObject) + : super.fromJsObject(jsObject); } diff --git a/lib/src/ui/handler/box_zoom.dart b/lib/src/ui/handler/box_zoom.dart index c39f351..f9d8e77 100644 --- a/lib/src/ui/handler/box_zoom.dart +++ b/lib/src/ui/handler/box_zoom.dart @@ -1,34 +1,35 @@ -@JS('mapboxgl') library mapboxgl.ui.handler.box_zoom; import 'dart:html'; -import 'package:js/js.dart'; +import 'package:mapbox_gl_dart/src/interop/interop.dart'; -@JS() -@anonymous -abstract class BoxZoomHandler { +class BoxZoomHandler extends JsObjectWrapper { /// Returns a Boolean indicating whether the "box zoom" interaction is enabled. /// /// @returns {boolean} `true` if the "box zoom" interaction is enabled. - external bool isEnabled(); + bool isEnabled() => jsObject.isEnabled(); /// Returns a Boolean indicating whether the "box zoom" interaction is active, i.e. currently being used. /// /// @returns {boolean} `true` if the "box zoom" interaction is active. - external bool isActive(); + bool isActive() => jsObject.isActive(); /// Enables the "box zoom" interaction. /// /// @example /// map.boxZoom.enable(); - external enable(); + enable() => jsObject.enable(); /// Disables the "box zoom" interaction. /// /// @example /// map.boxZoom.disable(); - external disable(); + disable() => jsObject.disable(); - external onMouseDown(MouseEvent e); + onMouseDown(MouseEvent e) => jsObject.onMouseDown(e); + + /// Creates a new BoxZoomHandler from a [jsObject]. + BoxZoomHandler.fromJsObject(BoxZoomHandlerJsImpl jsObject) + : super.fromJsObject(jsObject); } diff --git a/lib/src/ui/handler/dblclick_zoom.dart b/lib/src/ui/handler/dblclick_zoom.dart index 6f9ff7b..4e2958f 100644 --- a/lib/src/ui/handler/dblclick_zoom.dart +++ b/lib/src/ui/handler/dblclick_zoom.dart @@ -1,35 +1,37 @@ -@JS('mapboxgl') library mapboxgl.ui.handler.dbclick_zoom; -import 'package:js/js.dart'; import 'package:mapbox_gl_dart/mapbox_gl_dart.dart'; +import 'package:mapbox_gl_dart/src/interop/interop.dart'; -@JS() -@anonymous -abstract class DoubleClickZoomHandler { +class DoubleClickZoomHandler + extends JsObjectWrapper { /// Returns a Boolean indicating whether the "double click to zoom" interaction is enabled. /// /// @returns {boolean} `true` if the "double click to zoom" interaction is enabled. - external bool isEnabled(); + bool isEnabled() => jsObject.isEnabled(); /// Returns a Boolean indicating whether the "double click to zoom" interaction is active, i.e. currently being used. /// /// @returns {boolean} `true` if the "double click to zoom" interaction is active. - external bool isActive(); + bool isActive() => jsObject.isActive(); /// Enables the "double click to zoom" interaction. /// /// @example /// map.doubleClickZoom.enable(); - external enable(); + enable() => jsObject.enable(); /// Disables the "double click to zoom" interaction. /// /// @example /// map.doubleClickZoom.disable(); - external disable(); + disable() => jsObject.disable(); - external onTouchStart(MapTouchEvent e); + onTouchStart(MapTouchEvent e) => jsObject.onTouchStart(e.jsObject); - external onDblClick(MapMouseEvent e); + onDblClick(MapMouseEvent e) => jsObject.onDblClick(e.jsObject); + + /// Creates a new DoubleClickZoomHandler from a [jsObject]. + DoubleClickZoomHandler.fromJsObject(DoubleClickZoomHandlerJsImpl jsObject) + : super.fromJsObject(jsObject); } diff --git a/lib/src/ui/handler/drag_pan.dart b/lib/src/ui/handler/drag_pan.dart index 20e82c4..f1625d6 100644 --- a/lib/src/ui/handler/drag_pan.dart +++ b/lib/src/ui/handler/drag_pan.dart @@ -1,36 +1,37 @@ -@JS('mapboxgl') library mapboxgl.ui.handler.drag_pan; import 'dart:html'; -import 'package:js/js.dart'; +import 'package:mapbox_gl_dart/src/interop/interop.dart'; -@JS() -@anonymous -abstract class DragPanHandler { +class DragPanHandler extends JsObjectWrapper { /// Returns a Boolean indicating whether the "drag to pan" interaction is enabled. /// /// @returns {boolean} `true` if the "drag to pan" interaction is enabled. - external bool isEnabled(); + bool isEnabled() => jsObject.isEnabled(); /// Returns a Boolean indicating whether the "drag to pan" interaction is active, i.e. currently being used. /// /// @returns {boolean} `true` if the "drag to pan" interaction is active. - external bool isActive(); + bool isActive() => jsObject.isActive(); /// Enables the "drag to pan" interaction. /// /// @example /// map.dragPan.enable(); - external enable(); + enable() => jsObject.enable(); /// Disables the "drag to pan" interaction. /// /// @example /// map.dragPan.disable(); - external disable(); + disable() => jsObject.disable(); - external onMouseDown(MouseEvent e); + onMouseDown(MouseEvent e) => jsObject.onMouseDown(e); - external onTouchStart(TouchEvent e); + onTouchStart(TouchEvent e) => jsObject.onTouchStart(e); + + /// Creates a new DragPanHandler from a [jsObject]. + DragPanHandler.fromJsObject(DragPanHandlerJsImpl jsObject) + : super.fromJsObject(jsObject); } diff --git a/lib/src/ui/handler/drag_rotate.dart b/lib/src/ui/handler/drag_rotate.dart index f08e994..0e21f86 100644 --- a/lib/src/ui/handler/drag_rotate.dart +++ b/lib/src/ui/handler/drag_rotate.dart @@ -1,34 +1,35 @@ -@JS('mapboxgl') library mapboxgl.ui.handler.drag_rotate; import 'dart:html'; -import 'package:js/js.dart'; +import 'package:mapbox_gl_dart/src/interop/interop.dart'; -@JS() -@anonymous -abstract class DragRotateHandler { +class DragRotateHandler extends JsObjectWrapper { /// Returns a Boolean indicating whether the "drag to rotate" interaction is enabled. /// /// @returns {boolean} `true` if the "drag to rotate" interaction is enabled. - external bool isEnabled(); + bool isEnabled() => jsObject.isEnabled(); /// Returns a Boolean indicating whether the "drag to rotate" interaction is active, i.e. currently being used. /// /// @returns {boolean} `true` if the "drag to rotate" interaction is active. - external bool isActive(); + bool isActive() => jsObject.isActive(); /// Enables the "drag to rotate" interaction. /// /// @example /// map.dragRotate.enable(); - external enable(); + enable() => jsObject.enable(); /// Disables the "drag to rotate" interaction. /// /// @example /// map.dragRotate.disable(); - external disable(); + disable() => jsObject.disable(); - external onMouseDown(MouseEvent e); + onMouseDown(MouseEvent e) => jsObject.onMouseDown(e); + + /// Creates a new DragPanHandler from a [jsObject]. + DragRotateHandler.fromJsObject(DragRotateHandlerJsImpl jsObject) + : super.fromJsObject(jsObject); } diff --git a/lib/src/ui/handler/keyboard.dart b/lib/src/ui/handler/keyboard.dart index c1aa279..54adf6f 100644 --- a/lib/src/ui/handler/keyboard.dart +++ b/lib/src/ui/handler/keyboard.dart @@ -1,25 +1,26 @@ -@JS('mapboxgl') library mapboxgl.ui.handler.keyboard; -import 'package:js/js.dart'; +import 'package:mapbox_gl_dart/src/interop/interop.dart'; -@JS() -@anonymous -abstract class KeyboardHandler { +class KeyboardHandler extends JsObjectWrapper { /// Returns a Boolean indicating whether keyboard interaction is enabled. /// /// @returns {boolean} `true` if keyboard interaction is enabled. - external bool isEnabled(); + bool isEnabled() => jsObject.isEnabled(); /// Enables keyboard interaction. /// /// @example /// map.keyboard.enable(); - external bool enable(); + bool enable() => jsObject.enable(); /// Disables keyboard interaction. /// /// @example /// map.keyboard.disable(); - external bool disable(); + bool disable() => jsObject.disable(); + + /// Creates a new KeyboardHandler from a [jsObject]. + KeyboardHandler.fromJsObject(KeyboardHandlerJsImpl jsObject) + : super.fromJsObject(jsObject); } diff --git a/lib/src/ui/handler/scroll_zoom.dart b/lib/src/ui/handler/scroll_zoom.dart index fb6aba0..60f317b 100644 --- a/lib/src/ui/handler/scroll_zoom.dart +++ b/lib/src/ui/handler/scroll_zoom.dart @@ -1,32 +1,30 @@ -@JS('mapboxgl') library mapboxgl.ui.handler.scroll_zoom; import 'dart:html'; -import 'package:js/js.dart'; +import 'package:mapbox_gl_dart/src/interop/interop.dart'; -@JS() -@anonymous -abstract class ScrollZoomHandler { +class ScrollZoomHandler extends JsObjectWrapper { /// Set the zoom rate of a trackpad /// @param {number} [zoomRate = 1/100] - external setZoomRate(num zoomRate); + setZoomRate(num zoomRate) => jsObject.setZoomRate(zoomRate); /// Set the zoom rate of a mouse wheel /// @param {number} [wheelZoomRate = 1/450] - external setWheelZoomRate(num wheelZoomRate); + setWheelZoomRate(num wheelZoomRate) => + jsObject.setWheelZoomRate(wheelZoomRate); /// Returns a Boolean indicating whether the "scroll to zoom" interaction is enabled. /// /// @returns {boolean} `true` if the "scroll to zoom" interaction is enabled. - external bool isEnabled(); + bool isEnabled() => jsObject.isEnabled(); /// Active state is turned on and off with every scroll wheel event and is set back to false before the map /// render is called, so _active is not a good candidate for determining if a scroll zoom animation is in /// progress. - external bool isActive(); + bool isActive() => jsObject.isActive(); - external bool isZooming(); + bool isZooming() => jsObject.isZooming(); /// Enables the "scroll to zoom" interaction. /// @@ -37,13 +35,17 @@ abstract class ScrollZoomHandler { /// map.scrollZoom.enable(); /// @example /// map.scrollZoom.enable({ around: 'center' }) - external enable(dynamic options); + enable(dynamic options) => jsObject.enable(options); /// Disables the "scroll to zoom" interaction. /// /// @example /// map.scrollZoom.disable(); - external disable(); + disable() => jsObject.disable(); - external onWheel(WheelEvent e); + onWheel(WheelEvent e) => jsObject.onWheel(e); + + /// Creates a new ScrollZoomHandler from a [jsObject]. + ScrollZoomHandler.fromJsObject(ScrollZoomHandlerJsImpl jsObject) + : super.fromJsObject(jsObject); } diff --git a/lib/src/ui/handler/touch_zoom_rotate.dart b/lib/src/ui/handler/touch_zoom_rotate.dart index cabe3b1..7f1a6c9 100644 --- a/lib/src/ui/handler/touch_zoom_rotate.dart +++ b/lib/src/ui/handler/touch_zoom_rotate.dart @@ -1,17 +1,15 @@ -@JS('mapboxgl') library mapboxgl.ui.handler.touch_zoom_rotate; import 'dart:html'; -import 'package:js/js.dart'; +import 'package:mapbox_gl_dart/src/interop/interop.dart'; -@JS() -@anonymous -abstract class TouchZoomRotateHandler { +class TouchZoomRotateHandler + extends JsObjectWrapper { /// Returns a Boolean indicating whether the "pinch to rotate and zoom" interaction is enabled. /// /// @returns {boolean} `true` if the "pinch to rotate and zoom" interaction is enabled. - external bool isEnabled(); + bool isEnabled() => jsObject.isEnabled(); /// Enables the "pinch to rotate and zoom" interaction. /// @@ -22,27 +20,31 @@ abstract class TouchZoomRotateHandler { /// map.touchZoomRotate.enable(); /// @example /// map.touchZoomRotate.enable({ around: 'center' }); - external enable(dynamic options); + enable(dynamic options) => jsObject.enable(options); /// Disables the "pinch to rotate and zoom" interaction. /// /// @example /// map.touchZoomRotate.disable(); - external disable(); + disable() => jsObject.disable(); /// Disables the "pinch to rotate" interaction, leaving the "pinch to zoom" /// interaction enabled. /// /// @example /// map.touchZoomRotate.disableRotation(); - external disableRotation(); + disableRotation() => jsObject.disableRotation(); /// Enables the "pinch to rotate" interaction. /// /// @example /// map.touchZoomRotate.enable(); /// map.touchZoomRotate.enableRotation(); - external enableRotation(); + enableRotation() => jsObject.enableRotation(); - external onStart(TouchEvent e); + onStart(TouchEvent e) => jsObject.onStart(e); + + /// Creates a new TouchZoomRotateHandler from a [jsObject]. + TouchZoomRotateHandler.fromJsObject(TouchZoomRotateHandlerJsImpl jsObject) + : super.fromJsObject(jsObject); } diff --git a/lib/src/ui/map.dart b/lib/src/ui/map.dart index 116d47f..4068588 100644 --- a/lib/src/ui/map.dart +++ b/lib/src/ui/map.dart @@ -1,9 +1,9 @@ -@JS('mapboxgl') library mapboxgl.ui.map; import 'dart:html'; -import 'package:js/js.dart'; +import 'package:js/js_util.dart'; import 'package:mapbox_gl_dart/mapbox_gl_dart.dart'; +import 'package:mapbox_gl_dart/src/interop/interop.dart'; /// The `MapboxMap` object represents the map on your page. It exposes methods /// and properties that enable you to programmatically change the map, @@ -35,41 +35,48 @@ import 'package:mapbox_gl_dart/mapbox_gl_dart.dart'; /// ); /// ``` /// @see [Display a map](https://www.mapbox.com/mapbox-gl-js/examples/) -@JS('Map') class MapboxMap extends Camera { - external factory MapboxMap(MapOptions options); + final MapboxMapJsImpl jsObject; - external Style get style; - external dynamic get painter; + factory MapboxMap(MapOptions options) => + MapboxMap.fromJsObject(MapboxMapJsImpl(options.jsObject)); + + Style get style => Style.fromJsObject(jsObject.style); + dynamic get painter => jsObject.painter; /// The map's {@link ScrollZoomHandler}, which implements zooming in and out with a scroll wheel or trackpad. /// Find more details and examples using `scrollZoom` in the {@link ScrollZoomHandler} section. - external ScrollZoomHandler get scrollZoom; + ScrollZoomHandler get scrollZoom => + ScrollZoomHandler.fromJsObject(jsObject.scrollZoom); /// The map's {@link BoxZoomHandler}, which implements zooming using a drag gesture with the Shift key pressed. /// Find more details and examples using `boxZoom` in the {@link BoxZoomHandler} section. - external BoxZoomHandler get boxZoom; + BoxZoomHandler get boxZoom => BoxZoomHandler.fromJsObject(jsObject.boxZoom); /// The map's {@link DragRotateHandler}, which implements rotating the map while dragging with the right /// mouse button or with the Control key pressed. Find more details and examples using `dragRotate` /// in the {@link DragRotateHandler} section. - external DragRotateHandler get dragRotate; + DragRotateHandler get dragRotate => + DragRotateHandler.fromJsObject(jsObject.dragRotate); /// The map's {@link DragPanHandler}, which implements dragging the map with a mouse or touch gesture. /// Find more details and examples using `dragPan` in the {@link DragPanHandler} section. - external DragPanHandler get dragPan; + DragPanHandler get dragPan => DragPanHandler.fromJsObject(jsObject.dragPan); /// The map's {@link KeyboardHandler}, which allows the user to zoom, rotate, and pan the map using keyboard /// shortcuts. Find more details and examples using `keyboard` in the {@link KeyboardHandler} section. - external KeyboardHandler get keyboard; + KeyboardHandler get keyboard => + KeyboardHandler.fromJsObject(jsObject.keyboard); /// The map's {@link DoubleClickZoomHandler}, which allows the user to zoom by double clicking. /// Find more details and examples using `doubleClickZoom` in the {@link DoubleClickZoomHandler} section. - external DoubleClickZoomHandler get doubleClickZoom; + DoubleClickZoomHandler get doubleClickZoom => + DoubleClickZoomHandler.fromJsObject(jsObject.doubleClickZoom); /// The map's {@link TouchZoomRotateHandler}, which allows the user to zoom or rotate the map with touch gestures. /// Find more details and examples using `touchZoomRotate` in the {@link TouchZoomRotateHandler} section. - external TouchZoomRotateHandler get touchZoomRotate; + TouchZoomRotateHandler get touchZoomRotate => + TouchZoomRotateHandler.fromJsObject(jsObject.touchZoomRotate); /// Adds an {@link IControl} to the map, calling `control.onAdd(this)`. /// @@ -81,7 +88,8 @@ class MapboxMap extends Camera { /// // Add zoom and rotation controls to the map. /// map.addControl(new NavigationControl()); /// @see [Display map navigation controls](https://www.mapbox.com/mapbox-gl-js/example/navigation/) - external MapboxMap addControl(IControl control, [String position]); + MapboxMap addControl(IControl control, [String position]) => + MapboxMap.fromJsObject(jsObject.addControl(control.jsObject, position)); /// Removes the control from the map. /// @@ -94,7 +102,8 @@ class MapboxMap extends Camera { /// map.addControl(navigation); /// // Remove zoom and rotation controls from the map. /// map.removeControl(navigation); - external MapboxMap removeControl(IControl control); + MapboxMap removeControl(IControl control) => + MapboxMap.fromJsObject(jsObject.removeControl(control.jsObject)); /// Resizes the map according to the dimensions of its /// `container` element. @@ -112,18 +121,20 @@ class MapboxMap extends Camera { /// // after being initially hidden with CSS. /// var mapDiv = document.getElementById('map'); /// if (mapDiv.style.visibility === true) map.resize(); - external MapboxMap resize([dynamic eventData]); + MapboxMap resize([dynamic eventData]) => + MapboxMap.fromJsObject(jsObject.resize()); /// Returns the map's geographical bounds. When the bearing or pitch is non-zero, the visible region is not /// an axis-aligned rectangle, and the result is the smallest bounds that encompasses the visible region. /// @example /// var bounds = map.getBounds(); - external LngLatBounds getBounds(); + LngLatBounds getBounds() => LngLatBounds.fromJsObject(jsObject.getBounds()); /// Returns the maximum geographical bounds the map is constrained to, or `null` if none set. /// @example /// var maxBounds = map.getMaxBounds(); - external LngLatBounds getMaxBounds(); + LngLatBounds getMaxBounds() => + LngLatBounds.fromJsObject(jsObject.getMaxBounds()); /// Sets or clears the map's geographical bounds. /// @@ -144,7 +155,8 @@ class MapboxMap extends Camera { /// ]; /// // Set the map's max bounds. /// map.setMaxBounds(bounds); - external MapboxMap setMaxBounds(LngLatBounds bounds); + MapboxMap setMaxBounds(LngLatBounds bounds) => + MapboxMap.fromJsObject(jsObject.setMaxBounds(bounds.jsObject)); /// Sets or clears the map's minimum zoom level. /// If the map's current zoom level is lower than the new minimum, @@ -160,14 +172,15 @@ class MapboxMap extends Camera { /// @returns {MapboxMap} `this` /// @example /// map.setMinZoom(12.25); - external MapboxMap setMinZoom([num minZoom]); + MapboxMap setMinZoom([num minZoom]) => + MapboxMap.fromJsObject(jsObject.setMinZoom()); /// Returns the map's minimum allowable zoom level. /// /// @returns {number} minZoom /// @example /// var minZoom = map.getMinZoom(); - external num getMinZoom(); + num getMinZoom() => jsObject.getMinZoom(); /// Sets or clears the map's maximum zoom level. /// If the map's current zoom level is higher than the new maximum, @@ -178,14 +191,15 @@ class MapboxMap extends Camera { /// @returns {MapboxMap} `this` /// @example /// map.setMaxZoom(18.75); - external MapboxMap setMaxZoom([num maxZoom]); + MapboxMap setMaxZoom([num maxZoom]) => + MapboxMap.fromJsObject(jsObject.setMaxZoom()); /// Returns the map's maximum allowable zoom level. /// /// @returns {number} maxZoom /// @example /// var maxZoom = map.getMaxZoom(); - external num getMaxZoom(); + num getMaxZoom() => jsObject.getMaxZoom(); /// Sets or clears the map's minimum pitch. /// If the map's current pitch is lower than the new minimum, @@ -194,12 +208,13 @@ class MapboxMap extends Camera { /// @param {number | null | undefined} minPitch The minimum pitch to set (0-60). /// If `null` or `undefined` is provided, the function removes the current minimum pitch (i.e. sets it to 0). /// @returns {MapboxMap} `this` - external MapboxMap setMinPitch([num minPitch]); + MapboxMap setMinPitch([num minPitch]) => + MapboxMap.fromJsObject(jsObject.setMinPitch()); /// Returns the map's minimum allowable pitch. /// /// @returns {number} minPitch - external num getMinPitch(); + num getMinPitch() => jsObject.getMinPitch(); /// Sets or clears the map's maximum pitch. /// If the map's current pitch is higher than the new maximum, @@ -208,12 +223,13 @@ class MapboxMap extends Camera { /// @param {number | null | undefined} maxPitch The maximum pitch to set. /// If `null` or `undefined` is provided, the function removes the current maximum pitch (sets it to 60). /// @returns {MapboxMap} `this` - external MapboxMap setMaxPitch([num maxPitch]); + MapboxMap setMaxPitch([num maxPitch]) => + MapboxMap.fromJsObject(jsObject.setMaxPitch()); /// Returns the map's maximum allowable pitch. /// /// @returns {number} maxPitch - external num getMaxPitch(); + num getMaxPitch() => jsObject.getMaxPitch(); /// Returns the state of `renderWorldCopies`. If `true`, multiple copies of the world will be rendered side by side beyond -180 and 180 degrees longitude. If set to `false`: /// - When the map is zoomed out far enough that a single representation of the world does not fill the map's entire @@ -224,7 +240,7 @@ class MapboxMap extends Camera { /// @example /// var worldCopiesRendered = map.getRenderWorldCopies(); /// @see [Render world copies](https://docs.mapbox.com/mapbox-gl-js/example/render-world-copies/) - external bool getRenderWorldCopies(); + bool getRenderWorldCopies() => jsObject.getRenderWorldCopies(); /// Sets the state of `renderWorldCopies`. /// @@ -239,7 +255,8 @@ class MapboxMap extends Camera { /// @example /// map.setRenderWorldCopies(true); /// @see [Render world copies](https://docs.mapbox.com/mapbox-gl-js/example/render-world-copies/) - external MapboxMap setRenderWorldCopies([bool renderWorldCopies]); + MapboxMap setRenderWorldCopies([bool renderWorldCopies]) => + MapboxMap.fromJsObject(jsObject.setRenderWorldCopies(renderWorldCopies)); /// Returns a {@link Point} representing pixel coordinates, relative to the map's `container`, /// that correspond to the specified geographical location. @@ -249,7 +266,7 @@ class MapboxMap extends Camera { /// @example /// var coordinate = [-122.420679, 37.772537]; /// var point = map.project(coordinate); - external Point project(LngLat lnglat); + Point project(LngLat lnglat) => jsObject.project(lnglat.jsObject); /// Returns a {@link LngLat} representing geographical coordinates that correspond /// to the specified pixel coordinates. @@ -261,22 +278,23 @@ class MapboxMap extends Camera { /// // When the map is clicked, get the geographic coordinate. /// var coordinate = map.unproject(e.point); /// }); - external LngLat unproject(Point point); + LngLat unproject(Point point) => + LngLat.fromJsObject(jsObject.unproject(point)); /// Returns true if the map is panning, zooming, rotating, or pitching due to a camera animation or user gesture. /// @example /// var isMoving = map.isMoving(); - external bool isMoving(); + bool isMoving() => jsObject.isMoving(); /// Returns true if the map is zooming due to a camera animation or user gesture. /// @example /// var isZooming = map.isZooming(); - external bool isZooming(); + bool isZooming() => jsObject.isZooming(); /// Returns true if the map is rotating due to a camera animation or user gesture. /// @example /// map.isRotating(); - external bool isRotating(); + bool isRotating() => jsObject.isRotating(); /// Adds a listener for events of a specified type occurring on features in a specified style layer. /// @@ -292,7 +310,7 @@ class MapboxMap extends Camera { /// @param {Function} listener The function to be called when the event is fired. /// @returns {MapboxMap} `this` // Defined in evented.dart - //external MapboxMap on(String type, [dynamic layerIdOrListener, Listener listener]); + // MapboxMap on(String type, [dynamic layerIdOrListener, Listener listener]); /// Removes an event listener for layer-specific events previously added with `MapboxMap#on`. /// @@ -301,7 +319,7 @@ class MapboxMap extends Camera { /// @param {Function} listener The function previously installed as a listener. /// @returns {MapboxMap} `this` // Defined in evented.dart - //external MapboxMap off(String type, [dynamic layerIdOrListener, Listener listener]); + // MapboxMap off(String type, [dynamic layerIdOrListener, Listener listener]); /// Returns an array of [GeoJSON](http://geojson.org/) /// [Feature objects](https://tools.ietf.org/html/rfc7946#section-3.2) @@ -380,7 +398,12 @@ class MapboxMap extends Camera { /// @see [Get features under the mouse pointer](https://www.mapbox.com/mapbox-gl-js/example/queryrenderedfeatures/) /// @see [Highlight features within a bounding box](https://www.mapbox.com/mapbox-gl-js/example/using-box-queryrenderedfeatures/) /// @see [Filter features within map view](https://www.mapbox.com/mapbox-gl-js/example/filter-features-within-map-view/) - external List queryRenderedFeatures(dynamic geometry, [dynamic options]); + List queryRenderedFeatures(dynamic geometry, + [Map options]) => + jsObject + .queryRenderedFeatures(geometry, jsify(options)) + .map((dynamic f) => Feature.fromJsObject(f)) + .toList(); /// Returns an array of [GeoJSON](http://geojson.org/) /// [Feature objects](https://tools.ietf.org/html/rfc7946#section-3.2) @@ -417,7 +440,8 @@ class MapboxMap extends Camera { /// }); /// /// @see [Highlight features containing similar data](https://www.mapbox.com/mapbox-gl-js/example/query-similar-features/) - external List querySourceFeatures(String sourceId, dynamic parameters); + List querySourceFeatures(String sourceId, dynamic parameters) => + jsObject.querySourceFeatures(sourceId, parameters); /// Updates the map's Mapbox style object with a new value. /// @@ -444,7 +468,8 @@ class MapboxMap extends Camera { /// map.setStyle("mapbox://styles/mapbox/streets-v11"); /// /// @see [Change a map's style](https://www.mapbox.com/mapbox-gl-js/example/setstyle/) - external MapboxMap setStyle(dynamic style, [dynamic options]); + MapboxMap setStyle(dynamic style, [dynamic options]) => + MapboxMap.fromJsObject(jsObject.setStyle(style)); /// Returns the map's Mapbox style object, which can be used to recreate the map's style. /// @@ -452,7 +477,7 @@ class MapboxMap extends Camera { /// /// @example /// var styleJson = map.getStyle(); - external dynamic getStyle(); + dynamic getStyle() => jsObject.getStyle(); /// Returns a Boolean indicating whether the map's style is fully loaded. /// @@ -460,7 +485,7 @@ class MapboxMap extends Camera { /// /// @example /// var styleLoadStatus = map.isStyleLoaded(); - external bool isStyleLoaded(); + bool isStyleLoaded() => jsObject.isStyleLoaded(); /// Adds a source to the map's style. /// @@ -493,7 +518,12 @@ class MapboxMap extends Camera { /// @see Vector source: [Show and hide layers](https://docs.mapbox.com/mapbox-gl-js/example/toggle-layers/) /// @see GeoJSON source: [Add live realtime data](https://docs.mapbox.com/mapbox-gl-js/example/live-geojson/) /// @see Raster DEM source: [Add hillshading](https://docs.mapbox.com/mapbox-gl-js/example/hillshade/) - external MapboxMap addSource(String id, dynamic source); + MapboxMap addSource(String id, dynamic source) { + if (source is Source) { + return MapboxMap.fromJsObject(jsObject.addSource(id, source.jsObject)); + } + return MapboxMap.fromJsObject(jsObject.addSource(id, jsify(source))); + } /// Returns a Boolean indicating whether the source is loaded. /// @@ -501,7 +531,7 @@ class MapboxMap extends Camera { /// @returns {boolean} A Boolean indicating whether the source is loaded. /// @example /// var sourceLoaded = map.isSourceLoaded('bathymetry-data'); - external bool isSourceLoaded(String id); + bool isSourceLoaded(String id) => jsObject.isSourceLoaded(id); /// Returns a Boolean indicating whether all tiles in the viewport from all sources on /// the style are loaded. @@ -509,7 +539,7 @@ class MapboxMap extends Camera { /// @returns {boolean} A Boolean indicating whether all tiles are loaded. /// @example /// var tilesLoaded = map.areTilesLoaded(); - external bool areTilesLoaded(); + bool areTilesLoaded() => jsObject.areTilesLoaded(); /// Adds a/// *custom source type**(#Custom Sources), making it available for use with /// {@link MapboxMap#addSource}. @@ -517,7 +547,8 @@ class MapboxMap extends Camera { /// @param {string} name The name of the source type; source definition objects use this name in the `{type: ...}` field. /// @param {Function} SourceType A {@link Source} constructor. /// @param {Function} callback Called when the source type is ready or with an error argument if there is an error. - external addSourceType(String name, dynamic sourceType, Function callback); + addSourceType(String name, dynamic sourceType, Function callback) => + jsObject.addSourceType(name, sourceType, callback); /// Removes a source from the map's style. /// @@ -525,7 +556,7 @@ class MapboxMap extends Camera { /// @returns {MapboxMap} `this` /// @example /// map.removeSource('bathymetry-data'); - external removeSource(String id); + removeSource(String id) => jsObject.removeSource(id); /// Returns the source with the specified ID in the map's style. /// @@ -537,7 +568,7 @@ class MapboxMap extends Camera { /// @see [Create a draggable point](https://www.mapbox.com/mapbox-gl-js/example/drag-a-point/) /// @see [Animate a point](https://www.mapbox.com/mapbox-gl-js/example/animate-point-along-line/) /// @see [Add live realtime data](https://www.mapbox.com/mapbox-gl-js/example/live-geojson/) - external dynamic getSource(String id); + dynamic getSource(String id) => jsObject.getSource(id); /// Add an image to the style. This image can be displayed on the map like any other icon in the style's /// [sprite](https://docs.mapbox.com/help/glossary/sprite/) using the image's ID with @@ -582,7 +613,8 @@ class MapboxMap extends Camera { /// /// @see Use `HTMLImageElement`: [Add an icon to the map](https://www.mapbox.com/mapbox-gl-js/example/add-image/) /// @see Use `ImageData`: [Add a generated icon to the map](https://www.mapbox.com/mapbox-gl-js/example/add-image-generated/) - external addImage(String id, dynamic image, dynamic options); + addImage(String id, dynamic image, dynamic options) => + jsObject.addImage(id, image, options); /// Update an existing image in a style. This image can be displayed on the map like any other icon in the style's /// [sprite](https://docs.mapbox.com/help/glossary/sprite/) using the image's ID with @@ -599,7 +631,7 @@ class MapboxMap extends Camera { /// // If an image with the ID 'cat' already exists in the style's sprite, /// // replace that image with a new image, 'other-cat-icon.png'. /// if (map.hasImage('cat')) map.updateImage('cat', './other-cat-icon.png'); - external updateImage(String id, dynamic image); + updateImage(String id, dynamic image) => jsObject.updateImage(id, image); /// Check whether or not an image with a specific ID exists in the style. This checks both images /// in the style's original [sprite](https://docs.mapbox.com/help/glossary/sprite/) and any images @@ -612,7 +644,7 @@ class MapboxMap extends Camera { /// // Check if an image with the ID 'cat' exists in /// // the style's sprite. /// var catIconExists = map.hasImage('cat'); - external bool hasImage(String id); + bool hasImage(String id) => jsObject.hasImage(id); /// Remove an image from a style. This can be an image from the style's original /// [sprite](https://docs.mapbox.com/help/glossary/sprite/) or any images @@ -624,7 +656,7 @@ class MapboxMap extends Camera { /// // If an image with the ID 'cat' exists in /// // the style's sprite, remove it. /// if (map.hasImage('cat')) map.removeImage('cat'); - external removeImage(String id); + removeImage(String id) => jsObject.removeImage(id); /// Load an image from an external URL to be used with `MapboxMap#addImage`. External /// domains must support [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS). @@ -641,7 +673,7 @@ class MapboxMap extends Camera { /// }); /// /// @see [Add an icon to the map](https://www.mapbox.com/mapbox-gl-js/example/add-image/) - external loadImage(String url, Function callback); + loadImage(String url, Function callback) => jsObject.loadImage(url, callback); ////// /// Returns an Array of strings containing the IDs of all images currently available in the map. @@ -653,7 +685,7 @@ class MapboxMap extends Camera { /// @example /// var allImages = map.listImages(); /// - external List listImages(); + List listImages() => jsObject.listImages(); /// Adds a [Mapbox style layer](https://docs.mapbox.com/mapbox-gl-js/style-spec/#layers) /// to the map's style. @@ -689,7 +721,14 @@ class MapboxMap extends Camera { /// @see [Create and style clusters](https://www.mapbox.com/mapbox-gl-js/example/cluster/) /// @see [Add a vector tile source](https://www.mapbox.com/mapbox-gl-js/example/vector-source/) /// @see [Add a WMS source](https://www.mapbox.com/mapbox-gl-js/example/wms/) - external MapboxMap addLayer(dynamic layer, [String beforeId]); + MapboxMap addLayer(dynamic layer, [String beforeId]) { + if (layer is Layer) { + return MapboxMap.fromJsObject(jsObject.addLayer(layer.jsObject)); + } + return MapboxMap.fromJsObject(jsObject.addLayer(jsify(layer))); + } + + //jsObject.addLayer(layer.jsObject ?? jsify(layer)); /// Moves a layer to a different z-position. /// @@ -701,7 +740,8 @@ class MapboxMap extends Camera { /// @example /// // Move a layer with ID 'label' before the layer with ID 'waterways'. /// map.moveLayer('label', 'waterways'); - external MapboxMap moveLayer(String id, String beforeId); + MapboxMap moveLayer(String id, String beforeId) => + MapboxMap.fromJsObject(jsObject.moveLayer(id, beforeId)); /// Removes the layer with the given ID from the map's style. /// @@ -713,7 +753,7 @@ class MapboxMap extends Camera { /// @example /// // If a layer with ID 'state-data' exists, remove it. /// if (map.getLayer('state-data')) map.removeLayer('state-data'); - external removeLayer(String id); + removeLayer(String id) => jsObject.removeLayer(id); /// Returns the layer with the specified ID in the map's style. /// @@ -726,7 +766,7 @@ class MapboxMap extends Camera { /// /// @see [Filter symbols by toggling a list](https://www.mapbox.com/mapbox-gl-js/example/filter-markers/) /// @see [Filter symbols by text input](https://www.mapbox.com/mapbox-gl-js/example/filter-markers-by-input/) - external dynamic getLayer(String id); + dynamic getLayer(String id) => jsObject.getLayer(id); /// Sets the zoom extent for the specified style layer. The zoom extent includes the /// [minimum zoom level](https://docs.mapbox.com/mapbox-gl-js/style-spec/#layer-minzoom) @@ -745,7 +785,9 @@ class MapboxMap extends Camera { /// /// @example /// map.setLayerZoomRange('my-layer', 2, 5); - external MapboxMap setLayerZoomRange(String layerId, num minzoom, num maxzoom); + MapboxMap setLayerZoomRange(String layerId, num minzoom, num maxzoom) => + MapboxMap.fromJsObject( + jsObject.setLayerZoomRange(layerId, minzoom, maxzoom)); /// Sets the filter for the specified style layer. /// @@ -762,13 +804,15 @@ class MapboxMap extends Camera { /// @see [Filter features within map view](https://www.mapbox.com/mapbox-gl-js/example/filter-features-within-map-view/) /// @see [Highlight features containing similar data](https://www.mapbox.com/mapbox-gl-js/example/query-similar-features/) /// @see [Create a timeline animation](https://www.mapbox.com/mapbox-gl-js/example/timeline-animation/) - external MapboxMap setFilter(String layerId, dynamic filter, [StyleSetterOptions options]); + MapboxMap setFilter(String layerId, dynamic filter, + [StyleSetterOptions options]) => + MapboxMap.fromJsObject(jsObject.setFilter(layerId, filter)); /// Returns the filter applied to the specified style layer. /// /// @param {string} layerId The ID of the style layer whose filter to get. /// @returns {Array} The layer's filter. - external List getFilter(String layerId); + List getFilter(String layerId) => jsObject.getFilter(layerId); /// Sets the value of a paint property in the specified style layer. /// @@ -784,14 +828,17 @@ class MapboxMap extends Camera { /// @see [Change a layer's color with buttons](https://www.mapbox.com/mapbox-gl-js/example/color-switcher/) /// @see [Adjust a layer's opacity](https://www.mapbox.com/mapbox-gl-js/example/adjust-layer-opacity/) /// @see [Create a draggable point](https://www.mapbox.com/mapbox-gl-js/example/drag-a-point/) - external setPaintProperty(String layerId, String name, dynamic value, [StyleSetterOptions options]); + setPaintProperty(String layerId, String name, dynamic value, + [StyleSetterOptions options]) => + jsObject.setPaintProperty(layerId, name, jsify(value)); /// Returns the value of a paint property in the specified style layer. /// /// @param {string} layerId The ID of the layer to get the paint property from. /// @param {string} name The name of a paint property to get. /// @returns {*} The value of the specified paint property. - external dynamic getPaintProperty(String layerId, String name); + dynamic getPaintProperty(String layerId, String name) => + jsObject.getPaintProperty(layerId, name); /// Sets the value of a layout property in the specified style layer. /// @@ -803,14 +850,17 @@ class MapboxMap extends Camera { /// @returns {MapboxMap} `this` /// @example /// map.setLayoutProperty('my-layer', 'visibility', 'none'); - external MapboxMap setLayoutProperty(String layerId, String name, dynamic value, [StyleSetterOptions options]); + MapboxMap setLayoutProperty(String layerId, String name, dynamic value, + [StyleSetterOptions options]) => + MapboxMap.fromJsObject(jsObject.setLayoutProperty(layerId, name, value)); /// Returns the value of a layout property in the specified style layer. /// /// @param {string} layerId The ID of the layer to get the layout property from. /// @param {string} name The name of the layout property to get. /// @returns {*} The value of the specified layout property. - external dynamic getLayoutProperty(String layerId, String name); + dynamic getLayoutProperty(String layerId, String name) => + jsObject.getLayoutProperty(layerId, name); /// Sets the any combination of light values. /// @@ -818,12 +868,13 @@ class MapboxMap extends Camera { /// @param {Object} [options] /// @param {boolean} [options.validate=true] Whether to check if the filter conforms to the Mapbox GL Style Specification. Disabling validation is a performance optimization that should only be used if you have previously validated the values you will be passing to this function. /// @returns {MapboxMap} `this` - external MapboxMap setLight(dynamic light, StyleSetterOptions options); + MapboxMap setLight(dynamic light, StyleSetterOptions options) => + MapboxMap.fromJsObject(jsObject.setLight(light, options.jsObject)); /// Returns the value of the light object. /// /// @returns {Object} light Light properties of the style. - external dynamic getLight(); + dynamic getLight() => jsObject.getLight(); /// Sets the state of a feature. The `state` object is merged in with the existing state of the feature. /// Features are identified by their `id` attribute, which must be an integer or a string that can be @@ -841,7 +892,8 @@ class MapboxMap extends Camera { /// feature ids, set the `generateId` option in the `GeoJSONSourceSpecification` to auto-assign them. This /// option assigns ids based on a feature's index in the source data. If you change feature data using /// `map.getSource('some id').setData(..)`, you may need to re-apply state taking into account updated `id` values. - external setFeatureState(dynamic feature, dynamic state); + setFeatureState(dynamic feature, dynamic state) => + jsObject.setFeatureState(feature, state); /// Removes feature state, setting it back to the default behavior. If only /// source is specified, removes all states of that source. If @@ -856,7 +908,8 @@ class MapboxMap extends Camera { /// @param {string} `target.sourceLayer` (optional) /// For vector tile sources, the sourceLayer is /// required.* /// @param {string} key (optional) The key in the feature state to reset. - external removeFeatureState(dynamic target, [String key]); + removeFeatureState(dynamic target, [String key]) => + jsObject.removeFeatureState(target); /// Gets the state of a feature. /// Features are identified by their `id` attribute, which must be an integer or a string that can be @@ -870,12 +923,12 @@ class MapboxMap extends Camera { /// required.* /// /// @returns {Object} The state of the feature. - external dynamic getFeatureState(dynamic feature); + dynamic getFeatureState(dynamic feature) => jsObject.getFeatureState(feature); /// Returns the map's containing HTML element. /// /// @returns {HTMLElement} The map's container. - external HtmlElement getContainer(); + HtmlElement getContainer() => jsObject.getContainer(); /// Returns the HTML element containing the map's `` element. /// @@ -888,7 +941,7 @@ class MapboxMap extends Camera { /// @returns {HTMLElement} The container of the map's ``. /// @see [Create a draggable point](https://www.mapbox.com/mapbox-gl-js/example/drag-a-point/) /// @see [Highlight features within a bounding box](https://www.mapbox.com/mapbox-gl-js/example/using-box-queryrenderedfeatures/) - external HtmlElement getCanvasContainer(); + HtmlElement getCanvasContainer() => jsObject.getCanvasContainer(); /// Returns the map's `` element. /// @@ -896,7 +949,7 @@ class MapboxMap extends Camera { /// @see [Measure distances](https://www.mapbox.com/mapbox-gl-js/example/measure/) /// @see [Display a popup on hover](https://www.mapbox.com/mapbox-gl-js/example/popup-on-hover/) /// @see [Center the map on a clicked symbol](https://www.mapbox.com/mapbox-gl-js/example/center-on-symbol/) - external CanvasElement getCanvas(); + CanvasElement getCanvas() => jsObject.getCanvas(); /// Returns a Boolean indicating whether the map is fully loaded. /// @@ -905,7 +958,7 @@ class MapboxMap extends Camera { /// has not yet fully loaded. /// /// @returns {boolean} A Boolean indicating whether the map is fully loaded. - external bool loaded(); + bool loaded() => jsObject.loaded(); /// Clean up and release all internal resources associated with this map. /// @@ -914,12 +967,12 @@ class MapboxMap extends Camera { /// Use this method when you are done using the map and wish to ensure that it no /// longer consumes browser resources. Afterwards, you must not call any other /// methods on the map. - external remove(); + remove() => jsObject.remove(); /// Trigger the rendering of a single frame. Use this method with custom layers to /// repaint the map when the layer changes. Calling this multiple times before the /// next frame is rendered will still result in only a single frame being rendered. - external triggerRepaint(); + triggerRepaint() => jsObject.triggerRepaint(); /// Gets and sets a Boolean indicating whether the map will render an outline /// around each tile and the tile ID. These tile boundaries are useful for @@ -932,8 +985,8 @@ class MapboxMap extends Camera { /// @type {boolean} /// @instance /// @memberof MapboxMap - external bool get showTileBoundaries; - external set showTileBoundaries(bool value); + bool get showTileBoundaries => jsObject.showTileBoundaries; + set showTileBoundaries(bool value) => jsObject.showTileBoundaries; /// Gets and sets a Boolean indicating whether the map will render boxes /// around all symbols in the data source, revealing which symbols @@ -944,8 +997,8 @@ class MapboxMap extends Camera { /// @type {boolean} /// @instance /// @memberof MapboxMap - external bool get showCollisionBoxes; - external set showCollisionBoxes(bool value); + bool get showCollisionBoxes => jsObject.showCollisionBoxes; + set showCollisionBoxes(bool value) => jsObject.showCollisionBoxes; /// Gets and sets a Boolean indicating whether the map should color-code /// each fragment to show how many times it has been shaded. @@ -957,8 +1010,8 @@ class MapboxMap extends Camera { /// @type {boolean} /// @instance /// @memberof MapboxMap - external bool get showOverdrawInspector; - external set showOverdrawInspector(bool value); + bool get showOverdrawInspector => jsObject.showOverdrawInspector; + set showOverdrawInspector(bool value) => jsObject.showOverdrawInspector; /// Gets and sets a Boolean indicating whether the map will /// continuously repaint. This information is useful for analyzing performance. @@ -967,12 +1020,12 @@ class MapboxMap extends Camera { /// @type {boolean} /// @instance /// @memberof MapboxMap - external bool get repaint; - external set repaint(bool value); + bool get repaint => jsObject.repaint; + set repaint(bool value) => jsObject.repaint; /// show vertices - external bool get vertices; - external set vertices(bool value); + bool get vertices => jsObject.vertices; + set vertices(bool value) => jsObject.vertices; /// The version of Mapbox GL JS in use as specified in package.json, CHANGELOG.md, and the GitHub release. /// @@ -980,78 +1033,80 @@ class MapboxMap extends Camera { /// @instance /// @memberof MapboxMap /// @var {string} version - external String get version; + String get version => jsObject.version; + + /// Creates a new MapboxMap from a [jsObject]. + MapboxMap.fromJsObject(this.jsObject) : super.fromJsObject(jsObject); } -@JS() -@anonymous -class MapOptions { +class MapOptions extends JsObjectWrapper { /// If `true`, the map's position (zoom, center latitude, center longitude, bearing, and pitch) will be synced with the hash fragment of the page's URL. /// For example, `http://path/to/my/page.html#2.59/39.26/53.07/-24.1/60`. /// An additional string may optionally be provided to indicate a parameter-styled hash, /// e.g. http://path/to/my/page.html#map=2.59/39.26/53.07/-24.1/60&foo=bar, where foo /// is a custom parameter and bar is an arbitrary hash distinct from the map hash. /// `bool` or `String` - external dynamic get hash; + dynamic get hash => jsObject.hash; /// If `false`, no mouse, touch, or keyboard listeners will be attached to the map, so it will not respond to interaction. - external bool get interactive; + bool get interactive => jsObject.interactive; /// The HTML element in which Mapbox GL JS will render the map, or the element's string `id`. The specified element must have no children. /// `HTMLElement` or `String` - external dynamic get container; + dynamic get container => jsObject.container; /// The threshold, measured in degrees, that determines when the map's /// bearing will snap to north. For example, with a `bearingSnap` of 7, if the user rotates /// the map within 7 degrees of north, the map will automatically snap to exact north. - external num get bearingSnap; + num get bearingSnap => jsObject.bearingSnap; /// If `false`, the map's pitch (tilt) control with "drag to rotate" interaction will be disabled. - external bool get pitchWithRotate; + bool get pitchWithRotate => jsObject.pitchWithRotate; /// The max number of pixels a user can shift the mouse pointer during a click for it to be considered a valid click (as opposed to a mouse drag). - external num get clickTolerance; + num get clickTolerance => jsObject.clickTolerance; /// If `true`, an {@link AttributionControl} will be added to the map. - external bool get attributionControl; + bool get attributionControl => jsObject.attributionControl; /// String or strings to show in an {@link AttributionControl}. Only applicable if `options.attributionControl` is `true`. /// `String` or `List` - external dynamic get customAttribution; + dynamic get customAttribution => jsObject.customAttribution; /// A string representing the position of the Mapbox wordmark on the map. Valid options are `top-left`,`top-right`, `bottom-left`, `bottom-right`. - external String get logoPosition; + String get logoPosition => jsObject.logoPosition; /// If `true`, map creation will fail if the performance of Mapbox /// GL JS would be dramatically worse than expected (i.e. a software renderer would be used). - external bool get failIfMajorPerformanceCaveat; + bool get failIfMajorPerformanceCaveat => + jsObject.failIfMajorPerformanceCaveat; /// If `true`, the map's canvas can be exported to a PNG using `map.getCanvas().toDataURL()`. This is `false` by default as a performance optimization. - external bool get preserveDrawingBuffer; + bool get preserveDrawingBuffer => jsObject.preserveDrawingBuffer; /// If `true`, the gl context will be created with MSAA antialiasing, which can be useful for antialiasing custom layers. this is `false` by default as a performance optimization. - external bool get antialias; + bool get antialias => jsObject.antialias; /// If `false`, the map won't attempt to re-request tiles once they expire per their HTTP `cacheControl`/`expires` headers. - external bool get refreshExpiredTiles; + bool get refreshExpiredTiles => jsObject.refreshExpiredTiles; /// If set, the map will be constrained to the given bounds. - external LngLatBounds get maxBounds; + LngLatBounds get maxBounds => LngLatBounds.fromJsObject(jsObject.maxBounds); /// If `true`, the "scroll to zoom" interaction is enabled. An `Object` value is passed as options to {@link ScrollZoomHandler#enable}. - external bool get scrollZoom; + bool get scrollZoom => jsObject.scrollZoom; /// The minimum zoom level of the map (0-24). - external num get minZoom; + num get minZoom => jsObject.minZoom; /// The maximum zoom level of the map (0-24). - external num get maxZoom; + num get maxZoom => jsObject.maxZoom; /// The minimum pitch of the map (0-60). - external num get minPitch; + num get minPitch => jsObject.minPitch; /// The maximum pitch of the map (0-60). - external num get maxPitch; + num get maxPitch => jsObject.maxPitch; /// The map's Mapbox style. This must be an a JSON object conforming to /// the schema described in the [Mapbox Style Specification](https://mapbox.com/mapbox-gl-style-spec/), or a URL to @@ -1074,84 +1129,85 @@ class MapOptions { /// /// Tilesets hosted with Mapbox can be style-optimized if you append `?optimize=true` to the end of your style URL, like `mapbox://styles/mapbox/streets-v11?optimize=true`. /// Learn more about style-optimized vector tiles in our [API documentation](https://www.mapbox.com/api-documentation/maps/#retrieve-tiles). - external dynamic get style; + dynamic get style => jsObject.style; /// If `true`, the "box zoom" interaction is enabled (see {@link BoxZoomHandler}). - external bool get boxZoom; + bool get boxZoom => jsObject.boxZoom; /// If `true`, the "drag to rotate" interaction is enabled (see {@link DragRotateHandler}). - external bool get dragRotate; + bool get dragRotate => jsObject.dragRotate; /// If `true`, the "drag to pan" interaction is enabled. An `Object` value is passed as options to {@link DragPanHandler#enable}. - external dynamic get dragPan; + dynamic get dragPan => jsObject.dragPan; /// If `true`, keyboard shortcuts are enabled (see {@link KeyboardHandler}). - external bool get keyboard; + bool get keyboard => jsObject.keyboard; /// If `true`, the "double click to zoom" interaction is enabled (see {@link DoubleClickZoomHandler}). - external bool get doubleClickZoom; + bool get doubleClickZoom => jsObject.doubleClickZoom; /// If `true`, the "pinch to rotate and zoom" interaction is enabled. An `Object` value is passed as options to {@link TouchZoomRotateHandler#enable}. - external bool get touchZoomRotate; + bool get touchZoomRotate => jsObject.touchZoomRotate; /// If `true`, the map will automatically resize when the browser window resizes. - external bool get trackResize; + bool get trackResize => jsObject.trackResize; /// The inital geographical centerpoint of the map. If `center` is not specified in the constructor options, Mapbox GL JS will look for it in the map's style object. If it is not specified in the style, either, it will default to `[0, 0]` Note: Mapbox GL uses longitude, latitude coordinate order (as opposed to latitude, longitude) to match GeoJSON. - external LngLat get center; + LngLat get center => LngLat.fromJsObject(jsObject.center); /// The initial zoom level of the map. If `zoom` is not specified in the constructor options, Mapbox GL JS will look for it in the map's style object. If it is not specified in the style, either, it will default to `0`. - external num get zoom; + num get zoom => jsObject.zoom; /// The initial bearing (rotation) of the map, measured in degrees counter-clockwise from north. If `bearing` is not specified in the constructor options, Mapbox GL JS will look for it in the map's style object. If it is not specified in the style, either, it will default to `0`. - external num get bearing; + num get bearing => jsObject.bearing; /// The initial pitch (tilt) of the map, measured in degrees away from the plane of the screen (0-60). If `pitch` is not specified in the constructor options, Mapbox GL JS will look for it in the map's style object. If it is not specified in the style, either, it will default to `0`. - external num get pitch; + num get pitch => jsObject.pitch; /// The initial bounds of the map. If `bounds` is specified, it overrides `center` and `zoom` constructor options. - external LngLatBounds get bounds; + LngLatBounds get bounds => LngLatBounds.fromJsObject(jsObject.bounds); /// A [`fitBounds`](#map#fitbounds) options object to use _only_ when fitting the initial `bounds` provided above. - external dynamic get fitBoundsOptions; + dynamic get fitBoundsOptions => jsObject.fitBoundsOptions; /// If `true`, multiple copies of the world will be rendered side by side beyond -180 and 180 degrees longitude. If set to `false`: /// - When the map is zoomed out far enough that a single representation of the world does not fill the map's entire /// container, there will be blank space beyond 180 and -180 degrees longitude. /// - Features that cross 180 and -180 degrees longitude will be cut in two (with one portion on the right edge of the /// map and the other on the left edge of the map) at every zoom level. - external bool get renderWorldCopies; + bool get renderWorldCopies => jsObject.renderWorldCopies; /// The maximum number of tiles stored in the tile cache for a given source. If omitted, the cache will be dynamically sized based on the current viewport. - external num get maxTileCacheSize; + num get maxTileCacheSize => jsObject.maxTileCacheSize; /// Defines a CSS /// font-family for locally overriding generation of glyphs in the 'CJK Unified Ideographs', 'Hiragana', 'Katakana' and 'Hangul Syllables' ranges. /// In these ranges, font settings from the map's style will be ignored, except for font-weight keywords (light/regular/medium/bold). /// Set to `false`, to enable font settings from the map's style for these glyph ranges. Note that [Mapbox Studio](https://studio.mapbox.com/) sets this value to `false` by default. /// The purpose of this option is to avoid bandwidth-intensive glyph server requests. (See [Use locally generated ideographs](https://www.mapbox.com/mapbox-gl-js/example/local-ideographs).) - external String get localIdeographFontFamily; + String get localIdeographFontFamily => jsObject.localIdeographFontFamily; /// A callback run before the MapboxMap makes a request for an external URL. The callback can be used to modify the url, set headers, or set the credentials property for cross-origin requests. /// Expected to return an object with a `url` property and optionally `headers` and `credentials` properties. - external RequestTransformFunction get transformRequest; + RequestTransformFunctionJsImpl get transformRequest => + jsObject.transformRequest; //TODO: Remove JsImpl /// If `true`, Resource Timing API information will be collected for requests made by GeoJSON and Vector Tile web workers (this information is normally inaccessible from the main Javascript thread). Information will be returned in a `resourceTiming` property of relevant `data` events. - external bool get collectResourceTiming; + bool get collectResourceTiming => jsObject.collectResourceTiming; /// Controls the duration of the fade-in/fade-out animation for label collisions, in milliseconds. This setting affects all symbol layers. This setting does not affect the duration of runtime styling transitions or raster tile cross-fading. - external num get fadeDuration; + num get fadeDuration => jsObject.fadeDuration; /// If `true`, symbols from multiple sources can collide with each other during collision detection. If `false`, collision detection is run separately for the symbols in each source. - external bool get crossSourceCollisions; + bool get crossSourceCollisions => jsObject.crossSourceCollisions; /// If specified, map will use this token instead of the one defined in accessToken. - external String get accessToken; + String get accessToken => jsObject.accessToken; /// A patch to apply to the default localization table for UI strings, e.g. control tooltips. The `locale` object maps namespaced UI string IDs to translated strings in the target language; see `src/ui/default_locale.js` for an example with all supported string IDs. The object may specify all UI strings (thereby adding support for a new translation) or only a subset of strings (thereby patching the default translation table). - external dynamic get locale; + dynamic get locale => jsObject.locale; - external factory MapOptions({ + factory MapOptions({ dynamic hash, bool interactive, dynamic container, @@ -1188,33 +1244,88 @@ class MapOptions { bool renderWorldCopies, num maxTileCacheSize, String localIdeographFontFamily, - RequestTransformFunction transformRequest, + RequestTransformFunctionJsImpl transformRequest, //TODO: Remove JsImpl bool collectResourceTiming, num fadeDuration, bool crossSourceCollisions, String accessToken, dynamic locale, - }); + }) => + MapOptions.fromJsObject(MapOptionsJsImpl( + //hash: hash, + interactive: interactive ?? true, + container: container, + bearingSnap: bearingSnap, + pitchWithRotate: pitchWithRotate ?? true, + clickTolerance: clickTolerance ?? true, + attributionControl: attributionControl ?? true, + customAttribution: customAttribution, + logoPosition: logoPosition ?? 'bottom-left', + failIfMajorPerformanceCaveat: failIfMajorPerformanceCaveat, + preserveDrawingBuffer: preserveDrawingBuffer, + antialias: antialias, + refreshExpiredTiles: refreshExpiredTiles, + maxBounds: maxBounds?.jsObject, + scrollZoom: scrollZoom ?? true, + minZoom: minZoom, + maxZoom: maxZoom, + minPitch: minPitch, + maxPitch: maxPitch, + style: style, + boxZoom: boxZoom, + dragRotate: dragRotate, + dragPan: dragPan ?? true, + keyboard: keyboard ?? true, + doubleClickZoom: doubleClickZoom ?? true, + touchZoomRotate: touchZoomRotate ?? true, + trackResize: trackResize ?? true, + center: center?.jsObject, + zoom: zoom, + bearing: bearing, + pitch: pitch, + bounds: bounds?.jsObject, + fitBoundsOptions: fitBoundsOptions, + renderWorldCopies: renderWorldCopies, + maxTileCacheSize: maxTileCacheSize, + localIdeographFontFamily: localIdeographFontFamily, + transformRequest: transformRequest, + collectResourceTiming: collectResourceTiming, + fadeDuration: fadeDuration, + crossSourceCollisions: crossSourceCollisions, + accessToken: accessToken, + locale: locale, + )); + + /// Creates a new MapOptions from a [jsObject]. + MapOptions.fromJsObject(MapOptionsJsImpl jsObject) + : super.fromJsObject(jsObject); } -typedef RequestTransformFunction = RequestParameters Function(String url, String resourceType); +class RequestParameters extends JsObjectWrapper { + String get url => jsObject.url; + String get credentials => jsObject.credentials; + dynamic get headers => jsObject.headers; + String get method => jsObject.method; + bool get collectResourceTiming => jsObject.collectResourceTiming; -@JS() -@anonymous -class RequestParameters { - String url; - String credentials; - dynamic headers; - String method; - bool collectResourceTiming; - - external factory RequestParameters({ + factory RequestParameters({ String url, String credentials, dynamic headers, String method, bool collectResourceTiming, - }); + }) => + RequestParameters.fromJsObject(RequestParametersJsImpl( + url: url, + credentials: credentials, + headers: headers, + method: method, + collectResourceTiming: collectResourceTiming, + )); + + /// Creates a new RequestParameters from a [jsObject]. + RequestParameters.fromJsObject(RequestParametersJsImpl jsObject) + : super.fromJsObject(jsObject); } /// Interface for interactive controls added to the map. This is a @@ -1247,22 +1358,23 @@ class RequestParameters { /// } /// } /// ``` -@JS() -@anonymous -abstract class IControl { +class IControl extends JsObjectWrapper { /// Register a control on the map and give it a chance to register event listeners /// and resources. This method is called by {@link MapboxMap#addControl} /// internally. - external HtmlElement onAdd(MapboxMap map); + HtmlElement onAdd(MapboxMap map) => jsObject.onRemove(map.jsObject); /// Unregister a control on the map and give it a chance to detach event listeners /// and resources. This method is called by {@link MapboxMap#removeControl} /// internally. - external onRemove(MapboxMap map); + onRemove(MapboxMap map) => jsObject.onRemove(map.jsObject); /// Optionally provide a default position for this control. If this method /// is implemented and {@link MapboxMap#addControl} is called without the `position` /// parameter, the value returned by getDefaultPosition will be used as the /// control's position. - external String getDefaultPosition(); + String getDefaultPosition() => jsObject.getDefaultPosition(); + + /// Creates a new IControl from a [jsObject]. + IControl.fromJsObject(IControlJsImpl jsObject) : super.fromJsObject(jsObject); } diff --git a/lib/src/ui/marker.dart b/lib/src/ui/marker.dart index bf618c9..bfeffcd 100644 --- a/lib/src/ui/marker.dart +++ b/lib/src/ui/marker.dart @@ -1,9 +1,8 @@ -@JS('mapboxgl') library mapboxgl.ui.marker; import 'dart:html'; -import 'package:js/js.dart'; import 'package:mapbox_gl_dart/mapbox_gl_dart.dart'; +import 'package:mapbox_gl_dart/src/interop/interop.dart'; /// Creates a marker component /// @param {HTMLElement} [element] DOM element to use as a marker. The default is a light blue, droplet-shaped SVG marker. @@ -22,23 +21,23 @@ import 'package:mapbox_gl_dart/mapbox_gl_dart.dart'; /// ``` /// @see [Add custom icons with Markers](https://www.mapbox.com/mapbox-gl-js/example/custom-marker-icons/) /// @see [Create a draggable Marker](https://www.mapbox.com/mapbox-gl-js/example/drag-a-marker/) -@JS() class Marker extends Evented { - external factory Marker([MarkerOptions options]); + final MarkerJsImpl jsObject; + factory Marker([MarkerOptions options]) => + Marker.fromJsObject(MarkerJsImpl(options.jsObject)); /// Attaches the marker to a map /// @param {MapboxMap} map /// @returns {Marker} `this` - - external Marker addTo(MapboxMap map); + Marker addTo(MapboxMap map) => + Marker.fromJsObject(jsObject.addTo(map.jsObject)); /// Removes the marker from a map /// @example /// var marker = new mapboxgl.Marker().addTo(map); /// marker.remove(); /// @returns {Marker} `this` - - external Marker remove(); + Marker remove() => Marker.fromJsObject(jsObject.remove()); /// Get the marker's geographical location. /// @@ -47,89 +46,88 @@ class Marker extends Evented { /// the marker on screen. /// /// @returns {LngLat} - - external LngLat getLngLat(); + LngLat getLngLat() => LngLat.fromJsObject(jsObject.getLngLat()); /// Set the marker's geographical position and move it. /// @returns {Marker} `this` - - external Marker setLngLat(LngLat lnglat); + Marker setLngLat(LngLat lnglat) => + Marker.fromJsObject(jsObject.setLngLat(lnglat.jsObject)); /// Returns the `Marker`'s HTML element. /// @returns {HtmlElement} element - - external HtmlElement getElement(); + HtmlElement getElement() => jsObject.getElement(); /// Binds a Popup to the Marker /// @param popup an instance of the `Popup` class. If undefined or null, any popup /// set on this `Marker` instance is unset /// @returns {Marker} `this` - - external Marker setPopup(Popup popup); + Marker setPopup(Popup popup) => + Marker.fromJsObject(jsObject.setPopup(popup.jsObject)); /// Returns the Popup instance that is bound to the Marker /// @returns {Popup} popup - - external Popup getPopup(); + Popup getPopup() => Popup.fromJsObject(jsObject.getPopup()); /// Opens or closes the bound popup, depending on the current state /// @returns {Marker} `this` - - external Marker togglePopup(); + Marker togglePopup() => Marker.fromJsObject(jsObject.togglePopup()); /// Get the marker's offset. /// @returns {Point} - - external Point getOffset(); + Point getOffset() => jsObject.getOffset(); /// Sets the offset of the marker /// @param {PointLike} offset The offset in pixels as a {@link PointLike} object to apply relative to the element's center. Negatives indicate left and up. /// @returns {Marker} `this` - - external Marker setOffset(Point offset); + Marker setOffset(Point offset) => + Marker.fromJsObject(jsObject.setOffset(offset)); /// Sets the `draggable` property and functionality of the marker /// @param {boolean} [shouldBeDraggable=false] Turns drag functionality on/off /// @returns {Marker} `this` - - external Marker setDraggable(bool shouldBeDraggable); + Marker setDraggable(bool shouldBeDraggable) => + Marker.fromJsObject(jsObject.setDraggable(shouldBeDraggable)); /// Returns true if the marker can be dragged /// @returns {boolean} - external bool isDraggable(); + bool isDraggable() => jsObject.isDraggable(); /// Sets the `rotation` property of the marker. /// @param {number} [rotation=0] The rotation angle of the marker (clockwise, in degrees), relative to its respective {@link Marker#rotationAlignment} setting. /// @returns {Marker} `this` - external Marker setRotation(num rotation); + Marker setRotation(num rotation) => + Marker.fromJsObject(jsObject.setRotation(rotation)); /// Returns the current rotation angle of the marker (in degrees). /// @returns {number} - external num getRotation(); + num getRotation() => jsObject.getRotation(); /// Sets the `rotationAlignment` property of the marker. /// @param {string} [alignment='auto'] Sets the `rotationAlignment` property of the marker. /// @returns {Marker} `this` - external Marker setRotationAlignment(String alignment); + Marker setRotationAlignment(String alignment) => + Marker.fromJsObject(jsObject.setRotationAlignment(alignment)); /// Returns the current `rotationAlignment` property of the marker. /// @returns {string} - external String getRotationAlignment(); + String getRotationAlignment() => jsObject.getRotationAlignment(); /// Sets the `pitchAlignment` property of the marker. /// @param {string} [alignment] Sets the `pitchAlignment` property of the marker. If alignment is 'auto', it will automatically match `rotationAlignment`. /// @returns {Marker} `this` - external Marker setPitchAlignment(String alignment); + Marker setPitchAlignment(String alignment) => + Marker.fromJsObject(jsObject.setPitchAlignment(alignment)); /// Returns the current `pitchAlignment` property of the marker. /// @returns {string} - external String getPitchAlignment(); + String getPitchAlignment() => jsObject.getPitchAlignment(); + + /// Creates a new Marker from a [jsObject]. + Marker.fromJsObject(this.jsObject) : super.fromJsObject(jsObject); } -@JS() -@anonymous -class MarkerOptions { - external factory MarkerOptions({ +class MarkerOptions extends JsObjectWrapper { + factory MarkerOptions({ HtmlElement element, Point offset, String anchor, @@ -138,5 +136,19 @@ class MarkerOptions { num rotation, String rotationAlignment, String pitchAlignment, - }); + }) => + MarkerOptions.fromJsObject(MarkerOptionsJsImpl( + element: element, + offset: offset, + anchor: anchor, + color: color, + draggable: draggable, + rotation: rotation, + rotationAlignment: rotationAlignment, + pitchAlignment: pitchAlignment, + )); + + /// Creates a new MarkerOptions from a [jsObject]. + MarkerOptions.fromJsObject(MarkerOptionsJsImpl jsObject) + : super.fromJsObject(jsObject); } diff --git a/lib/src/ui/popup.dart b/lib/src/ui/popup.dart index 7922e75..07191f0 100644 --- a/lib/src/ui/popup.dart +++ b/lib/src/ui/popup.dart @@ -1,219 +1,196 @@ -@JS('mapboxgl') library mapboxgl.ui.popup; import 'dart:html'; -import 'package:js/js.dart'; import 'package:mapbox_gl_dart/mapbox_gl_dart.dart'; - -/** - * A popup component. - * - * @param {Object} [options] - * @param {boolean} [options.closeButton=true] If `true`, a close button will appear in the - * top right corner of the popup. - * @param {boolean} [options.closeOnClick=true] If `true`, the popup will closed when the - * map is clicked. - * @param {string} [options.anchor] - A string indicating the part of the Popup that should - * be positioned closest to the coordinate set via {@link Popup#setLngLat}. - * Options are `'center'`, `'top'`, `'bottom'`, `'left'`, `'right'`, `'top-left'`, - * `'top-right'`, `'bottom-left'`, and `'bottom-right'`. If unset the anchor will be - * dynamically set to ensure the popup falls within the map container with a preference - * for `'bottom'`. - * @param {number|PointLike|Object} [options.offset] - - * A pixel offset applied to the popup's location specified as: - * - a single number specifying a distance from the popup's location - * - a {@link PointLike} specifying a constant offset - * - an object of {@link Point}s specifing an offset for each anchor position - * Negative offsets indicate left and up. - * @param {string} [options.className] Space-separated CSS class names to add to popup container - * @param {string} [options.maxWidth='240px'] - - * A string that sets the CSS property of the popup's maximum width, eg `'300px'`. - * To ensure the popup resizes to fit its content, set this property to `'none'`. - * Available values can be found here: https://developer.mozilla.org/en-US/docs/Web/CSS/max-width - * @example - * var markerHeight = 50, markerRadius = 10, linearOffset = 25; - * var popupOffsets = { - * 'top': [0, 0], - * 'top-left': [0,0], - * 'top-right': [0,0], - * 'bottom': [0, -markerHeight], - * 'bottom-left': [linearOffset, (markerHeight - markerRadius + linearOffset) * -1], - * 'bottom-right': [-linearOffset, (markerHeight - markerRadius + linearOffset) * -1], - * 'left': [markerRadius, (markerHeight - markerRadius) * -1], - * 'right': [-markerRadius, (markerHeight - markerRadius) * -1] - * }; - * var popup = new mapboxgl.Popup({offset: popupOffsets, className: 'my-class'}) - * .setLngLat(e.lngLat) - * .setHTML("

Hello World!

") - * .setMaxWidth("300px") - * .addTo(map); - * @see [Display a popup](https://www.mapbox.com/mapbox-gl-js/example/popup/) - * @see [Display a popup on hover](https://www.mapbox.com/mapbox-gl-js/example/popup-on-hover/) - * @see [Display a popup on click](https://www.mapbox.com/mapbox-gl-js/example/popup-on-click/) - * @see [Attach a popup to a marker instance](https://www.mapbox.com/mapbox-gl-js/example/set-popup/) - */ -@JS() +import 'package:mapbox_gl_dart/src/interop/interop.dart'; + +/// A popup component. +/// +/// @param {Object} [options] +/// @param {boolean} [options.closeButton=true] If `true`, a close button will appear in the +/// top right corner of the popup. +/// @param {boolean} [options.closeOnClick=true] If `true`, the popup will closed when the +/// map is clicked. +/// @param {string} [options.anchor] - A string indicating the part of the Popup that should +/// be positioned closest to the coordinate set via {@link Popup#setLngLat}. +/// Options are `'center'`, `'top'`, `'bottom'`, `'left'`, `'right'`, `'top-left'`, +/// `'top-right'`, `'bottom-left'`, and `'bottom-right'`. If unset the anchor will be +/// dynamically set to ensure the popup falls within the map container with a preference +/// for `'bottom'`. +/// @param {number|PointLike|Object} [options.offset] - +/// A pixel offset applied to the popup's location specified as: +/// - a single number specifying a distance from the popup's location +/// - a {@link PointLike} specifying a constant offset +/// - an object of {@link Point}s specifing an offset for each anchor position +/// Negative offsets indicate left and up. +/// @param {string} [options.className] Space-separated CSS class names to add to popup container +/// @param {string} [options.maxWidth='240px'] - +/// A string that sets the CSS property of the popup's maximum width, eg `'300px'`. +/// To ensure the popup resizes to fit its content, set this property to `'none'`. +/// Available values can be found here: https://developer.mozilla.org/en-US/docs/Web/CSS/max-width +/// @example +/// var markerHeight = 50, markerRadius = 10, linearOffset = 25; +/// var popupOffsets = { +/// 'top': [0, 0], +/// 'top-left': [0,0], +/// 'top-right': [0,0], +/// 'bottom': [0, -markerHeight], +/// 'bottom-left': [linearOffset, (markerHeight - markerRadius + linearOffset)/// -1], +/// 'bottom-right': [-linearOffset, (markerHeight - markerRadius + linearOffset)/// -1], +/// 'left': [markerRadius, (markerHeight - markerRadius)/// -1], +/// 'right': [-markerRadius, (markerHeight - markerRadius)/// -1] +/// }; +/// var popup = new mapboxgl.Popup({offset: popupOffsets, className: 'my-class'}) +/// .setLngLat(e.lngLat) +/// .setHTML("

Hello World!

") +/// .setMaxWidth("300px") +/// .addTo(map); +/// @see [Display a popup](https://www.mapbox.com/mapbox-gl-js/example/popup/) +/// @see [Display a popup on hover](https://www.mapbox.com/mapbox-gl-js/example/popup-on-hover/) +/// @see [Display a popup on click](https://www.mapbox.com/mapbox-gl-js/example/popup-on-click/) +/// @see [Attach a popup to a marker instance](https://www.mapbox.com/mapbox-gl-js/example/set-popup/) class Popup extends Evented { - external dynamic get options; - - external factory Popup([PopupOptions options]); - - /** - * Adds the popup to a map. - * - * @param {MapboxMap} map The Mapbox GL JS map to add the popup to. - * @returns {Popup} `this` - */ - external Popup addTo(MapboxMap map); - - /** - * @returns {boolean} `true` if the popup is open, `false` if it is closed. - */ - external bool isOpen(); - - /** - * Removes the popup from the map it has been added to. - * - * @example - * var popup = new mapboxgl.Popup().addTo(map); - * popup.remove(); - * @returns {Popup} `this` - */ - external Popup remove(); - - /** - * Returns the geographical location of the popup's anchor. - * - * The longitude of the result may differ by a multiple of 360 degrees from the longitude previously - * set by `setLngLat` because `Popup` wraps the anchor longitude across copies of the world to keep - * the popup on screen. - * - * @returns {LngLat} The geographical location of the popup's anchor. - */ - external LngLat getLngLat(); - - /** - * Sets the geographical location of the popup's anchor, and moves the popup to it. Replaces trackPointer() behavior. - * - * @param lnglat The geographical location to set as the popup's anchor. - * @returns {Popup} `this` - */ - external Popup setLngLat(LngLat lnglat); - - /** - * Tracks the popup anchor to the cursor position, on screens with a pointer device (will be hidden on touchscreens). Replaces the setLngLat behavior. - * For most use cases, `closeOnClick` and `closeButton` should also be set to `false` here. - * @returns {Popup} `this` - */ - external Popup trackPointer(); - - /** - * Returns the `Popup`'s HTML element. - * @returns {HtmlElement} element - */ - external HtmlElement getElement(); - - /** - * Sets the popup's content to a string of text. - * - * This function creates a [Text](https://developer.mozilla.org/en-US/docs/Web/API/Text) node in the DOM, - * so it cannot insert raw HTML. Use this method for security against XSS - * if the popup content is user-provided. - * - * @param text Textual content for the popup. - * @returns {Popup} `this` - * @example - * var popup = new mapboxgl.Popup() - * .setLngLat(e.lngLat) - * .setText('Hello, world!') - * .addTo(map); - */ - external Popup setText(String text); - - /** - * Sets the popup's content to the HTML provided as a string. - * - * This method does not perform HTML filtering or sanitization, and must be - * used only with trusted content. Consider {@link Popup#setText} if - * the content is an untrusted text string. - * - * @param html A string representing HTML content for the popup. - * @returns {Popup} `this` - */ - external Popup setHTML(String html); - - /** - * Returns the popup's maximum width. - * - * @returns {string} The maximum width of the popup. - */ - external String getMaxWidth(); - - /** - * Sets the popup's maximum width. This is setting the CSS property `max-width`. - * Available values can be found here: https://developer.mozilla.org/en-US/docs/Web/CSS/max-width - * - * @param maxWidth A string representing the value for the maximum width. - * @returns {Popup} `this` - */ - external Popup setMaxWidth(String maxWidth); - - /** - * Sets the popup's content to the element provided as a DOM node. - * - * @param htmlNode A DOM node to be used as content for the popup. - * @returns {Popup} `this` - * @example - * // create an element with the popup content - * var div = window.document.createElement('div'); - * div.innerHTML = 'Hello, world!'; - * var popup = new mapboxgl.Popup() - * .setLngLat(e.lngLat) - * .setDOMContent(div) - * .addTo(map); - */ - external Popup setDOMContent(Node htmlNode); - - /** - * Adds a CSS class to the popup container element. - * - * @param {string} className Non-empty string with CSS class name to add to popup container - * - * @example - * let popup = new mapboxgl.Popup() - * popup.addClassName('some-class') - */ - external addClassName(String className); - - /** - * Removes a CSS class from the popup container element. - * - * @param {string} className Non-empty string with CSS class name to remove from popup container - * - * @example - * let popup = new mapboxgl.Popup() - * popup.removeClassName('some-class') - */ - external removeClassName(String className); - - /** - * Add or remove the given CSS class on the popup container, depending on whether the container currently has that class. - * - * @param {string} className Non-empty string with CSS class name to add/remove - * - * @returns {boolean} if the class was removed return false, if class was added, then return true - * - * @example - * let popup = new mapboxgl.Popup() - * popup.toggleClassName('toggleClass') - */ - external bool toggleClassName(String className); + dynamic get options => jsObject.options; + + final PopupJsImpl jsObject; + factory Popup([PopupOptions options]) { + if (options != null) + return Popup.fromJsObject(PopupJsImpl(options.jsObject)); + return Popup.fromJsObject(PopupJsImpl()); + } + + /// Adds the popup to a map. + /// + /// @param {MapboxMap} map The Mapbox GL JS map to add the popup to. + /// @returns {Popup} `this` +//// + Popup addTo(MapboxMap map) => + Popup.fromJsObject(jsObject.addTo(map.jsObject)); + + /// @returns {boolean} `true` if the popup is open, `false` if it is closed. + bool isOpen() => jsObject.isOpen(); + + /// Removes the popup from the map it has been added to. + /// + /// @example + /// var popup = new mapboxgl.Popup().addTo(map); + /// popup.remove(); + /// @returns {Popup} `this` + Popup remove() => Popup.fromJsObject(jsObject.remove()); + + /// Returns the geographical location of the popup's anchor. + /// + /// The longitude of the result may differ by a multiple of 360 degrees from the longitude previously + /// set by `setLngLat` because `Popup` wraps the anchor longitude across copies of the world to keep + /// the popup on screen. + /// + /// @returns {LngLat} The geographical location of the popup's anchor. + LngLat getLngLat() => LngLat.fromJsObject(jsObject.getLngLat()); + + /// Sets the geographical location of the popup's anchor, and moves the popup to it. Replaces trackPointer() behavior. + /// + /// @param lnglat The geographical location to set as the popup's anchor. + /// @returns {Popup} `this` + Popup setLngLat(LngLat lnglat) => + Popup.fromJsObject(jsObject.setLngLat(lnglat.jsObject)); + + /// Tracks the popup anchor to the cursor position, on screens with a pointer device (will be hidden on touchscreens). Replaces the setLngLat behavior. + /// For most use cases, `closeOnClick` and `closeButton` should also be set to `false` here. + /// @returns {Popup} `this` + Popup trackPointer() => Popup.fromJsObject(jsObject.trackPointer()); + + /// Returns the `Popup`'s HTML element. + /// @returns {HtmlElement} element + HtmlElement getElement() => jsObject.getElement(); + + /// Sets the popup's content to a string of text. + /// + /// This function creates a [Text](https://developer.mozilla.org/en-US/docs/Web/API/Text) node in the DOM, + /// so it cannot insert raw HTML. Use this method for security against XSS + /// if the popup content is user-provided. + /// + /// @param text Textual content for the popup. + /// @returns {Popup} `this` + /// @example + /// var popup = new mapboxgl.Popup() + /// .setLngLat(e.lngLat) + /// .setText('Hello, world!') + /// .addTo(map); + Popup setText(String text) => Popup.fromJsObject(jsObject.setText(text)); + + /// Sets the popup's content to the HTML provided as a string. + /// + /// This method does not perform HTML filtering or sanitization, and must be + /// used only with trusted content. Consider {@link Popup#setText} if + /// the content is an untrusted text string. + /// + /// @param html A string representing HTML content for the popup. + /// @returns {Popup} `this` + Popup setHTML(String html) => Popup.fromJsObject(jsObject.setHTML(html)); + + /// Returns the popup's maximum width. + /// + /// @returns {string} The maximum width of the popup. + String getMaxWidth() => jsObject.getMaxWidth(); + + /// Sets the popup's maximum width. This is setting the CSS property `max-width`. + /// Available values can be found here: https://developer.mozilla.org/en-US/docs/Web/CSS/max-width + /// + /// @param maxWidth A string representing the value for the maximum width. + /// @returns {Popup} `this` + Popup setMaxWidth(String maxWidth) => + Popup.fromJsObject(jsObject.setMaxWidth(maxWidth)); + + /// Sets the popup's content to the element provided as a DOM node. + /// + /// @param htmlNode A DOM node to be used as content for the popup. + /// @returns {Popup} `this` + /// @example + /// // create an element with the popup content + /// var div = window.document.createElement('div'); + /// div.innerHTML = 'Hello, world!'; + /// var popup = new mapboxgl.Popup() + /// .setLngLat(e.lngLat) + /// .setDOMContent(div) + /// .addTo(map); + Popup setDOMContent(Node htmlNode) => + Popup.fromJsObject(jsObject.setDOMContent(htmlNode)); + + /// Adds a CSS class to the popup container element. + /// + /// @param {string} className Non-empty string with CSS class name to add to popup container + /// + /// @example + /// let popup = new mapboxgl.Popup() + /// popup.addClassName('some-class') + addClassName(String className) => jsObject.addClassName(className); + + /// Removes a CSS class from the popup container element. + /// + /// @param {string} className Non-empty string with CSS class name to remove from popup container + /// + /// @example + /// let popup = new mapboxgl.Popup() + /// popup.removeClassName('some-class') + removeClassName(String className) => jsObject.removeClassName(className); + + /// Add or remove the given CSS class on the popup container, depending on whether the container currently has that class. + /// + /// @param {string} className Non-empty string with CSS class name to add/remove + /// + /// @returns {boolean} if the class was removed return false, if class was added, then return true + /// + /// @example + /// let popup = new mapboxgl.Popup() + /// popup.toggleClassName('toggleClass') + bool toggleClassName(String className) => jsObject.toggleClassName(className); + + /// Creates a new Popup from a [jsObject]. + Popup.fromJsObject(this.jsObject) : super.fromJsObject(jsObject); } -@JS() -@anonymous -class PopupOptions { - external factory PopupOptions({ +class PopupOptions extends JsObjectWrapper { + factory PopupOptions({ bool loseButton, bool closeButton, bool closeOnClick, @@ -221,5 +198,18 @@ class PopupOptions { dynamic offset, String className, String maxWidth, - }); + }) => + PopupOptions.fromJsObject(PopupOptionsJsImpl( + loseButton: loseButton, + closeButton: closeButton, + closeOnClick: closeOnClick, + anchor: anchor, + offset: offset, + className: className, + maxWidth: maxWidth, + )); + + /// Creates a new PopupOptions from a [jsObject]. + PopupOptions.fromJsObject(PopupOptionsJsImpl jsObject) + : super.fromJsObject(jsObject); } diff --git a/lib/src/util/evented.dart b/lib/src/util/evented.dart index c43eb1f..36a4f79 100644 --- a/lib/src/util/evented.dart +++ b/lib/src/util/evented.dart @@ -1,24 +1,38 @@ -@JS('mapboxgl') library mapboxgl.util.evented; -import 'package:js/js.dart'; +import 'dart:html'; +import 'dart:js'; + import 'package:mapbox_gl_dart/mapbox_gl_dart.dart'; +import 'package:mapbox_gl_dart/src/interop/interop.dart'; typedef Listener = dynamic Function(Event object); -@JS() -@anonymous -class Event { - String type; - LngLat lngLat; - List features; +class Event extends JsObjectWrapper { + String get type => jsObject.type; + LngLat get lngLat => LngLat.fromJsObject(jsObject.lngLat); + List get features => + jsObject.features.map((dynamic f) => Feature.fromJsObject(f)).toList(); + Point get point => jsObject.point; + + factory Event({ + String type, + LngLat lngLat, + List features, + Point point, + }) => + Event.fromJsObject(EventJsImpl( + type: type, + lngLat: lngLat.jsObject, + features: features.map((dynamic f) => f.jsObject).toList(), + point: point, + )); - external factory Event( - {String type, LngLat lngLat, List features}); + /// Creates a new Event from a [jsObject]. + Event.fromJsObject(EventJsImpl jsObject) : super.fromJsObject(jsObject); } -@JS() -abstract class Evented { +class Evented extends JsObjectWrapper { /// Adds a listener to a specified event type. /// /// @param {string} type The event type to add a listen for. @@ -26,18 +40,46 @@ abstract class Evented { /// The listener function is called with the data object passed to `fire`, /// extended with `target` and `type` properties. /// @returns {Object} `this` - //external on(String type, Listener listener); - external MapboxMap on(String type, - [dynamic layerIdOrListener, Listener listener]); + MapboxMap on(String type, [dynamic layerIdOrListener, Listener listener]) { + if (layerIdOrListener is Listener) { + return MapboxMap.fromJsObject( + jsObject.on(type, allowInterop( + (EventJsImpl object) { + layerIdOrListener(Event.fromJsObject(object)); + }, + )), + ); + } + return MapboxMap.fromJsObject( + jsObject.on(type, layerIdOrListener, allowInterop( + (EventJsImpl object) { + listener(Event.fromJsObject(object)); + }, + ))); + } /// Removes a previously registered event listener. /// /// @param {string} type The event type to remove listeners for. /// @param {Function} listener The listener function to remove. /// @returns {Object} `this` - //external off(String type, Listener listener); - external MapboxMap off(String type, - [dynamic layerIdOrListener, Listener listener]); + MapboxMap off(String type, [dynamic layerIdOrListener, Listener listener]) { + if (layerIdOrListener is Listener) { + return MapboxMap.fromJsObject( + jsObject.off(type, allowInterop( + (EventJsImpl object) { + layerIdOrListener(Event.fromJsObject(object)); + }, + )), + ); + } + return MapboxMap.fromJsObject( + jsObject.off(type, layerIdOrListener, allowInterop( + (EventJsImpl object) { + listener(Event.fromJsObject(object)); + }, + ))); + } /// Adds a listener that will be called only once to a specified event type. /// @@ -46,21 +88,31 @@ abstract class Evented { /// @param {string} type The event type to listen for. /// @param {Function} listener The function to be called when the event is fired the first time. /// @returns {Object} `this` - external once(String type, Listener listener); + MapboxMap once(String type, Listener listener) => + MapboxMap.fromJsObject(jsObject.once(type, allowInterop( + (EventJsImpl object) { + listener(Event.fromJsObject(object)); + }, + ))); - external fire(Event event, [dynamic properties]); + fire(Event event, [dynamic properties]) => + jsObject.fire(event.jsObject, properties); /// Returns a true if this instance of Evented or any forwardeed instances of Evented have a listener for the specified type. /// /// @param {string} type The event type /// @returns {boolean} `true` if there is at least one registered listener for specified event type, `false` otherwise /// @private - external listens(String type); + listens(String type) => jsObject.listens(type); /// Bubble all events fired by this instance of Evented to this parent instance of Evented. /// /// @private /// @returns {Object} `this` /// @private - external setEventedParent([Evented parent, dynamic data]); + setEventedParent([Evented parent, dynamic data]) => + jsObject.setEventedParent(parent.jsObject, data); + + /// Creates a new Evented from a [jsObject]. + Evented.fromJsObject(EventedJsImpl jsObject) : super.fromJsObject(jsObject); } diff --git a/lib/src/utils.dart b/lib/src/utils.dart new file mode 100644 index 0000000..a9f74ab --- /dev/null +++ b/lib/src/utils.dart @@ -0,0 +1,35 @@ +import 'package:js/js_util.dart' as util; +import 'interop/js.dart' as js; + +/// Returns Dart representation from JS Object. +dynamic dartify(Object jsObject) { + if (_isBasicType(jsObject)) { + return jsObject; + } + + // Handle list + if (jsObject is Iterable) { + return jsObject.map(dartify).toList(); + } + + // Assume a map then... + return dartifyMap(jsObject); +} + +/// Returns `true` if the [value] is a very basic built-in type - e.g. +/// `null`, [num], [bool] or [String]. It returns `false` in the other case. +bool _isBasicType(Object value) { + if (value == null || value is num || value is bool || value is String) { + return true; + } + return false; +} + +Map dartifyMap(Object jsObject) { + var keys = js.objectKeys(jsObject); + var map = {}; + for (var key in keys) { + map[key] = dartify(util.getProperty(jsObject, key)); + } + return map; +}