From 01673881c9dea8c07ce10080c7b137a197a8c060 Mon Sep 17 00:00:00 2001 From: JaffaKetchup Date: Thu, 6 Jun 2024 09:44:59 +0100 Subject: [PATCH 1/2] Initial implementation (based off #1853) Replaced `TileBuilder` with `TileOverlayPainter` Updated examples --- example/lib/pages/retina.dart | 17 ++- example/lib/pages/tile_builder.dart | 134 +++++++++++------- lib/flutter_map.dart | 2 +- lib/src/layer/tile_layer/tile.dart | 95 ------------- lib/src/layer/tile_layer/tile_builder.dart | 132 ----------------- lib/src/layer/tile_layer/tile_layer.dart | 115 +++++++++++---- lib/src/layer/tile_layer/tile_model.dart | 36 +++++ .../tile_layer/tile_overlay_painter.dart | 13 ++ lib/src/layer/tile_layer/tile_painter.dart | 65 +++++++++ test/full_coverage_test.dart | 5 +- 10 files changed, 301 insertions(+), 313 deletions(-) delete mode 100644 lib/src/layer/tile_layer/tile.dart delete mode 100644 lib/src/layer/tile_layer/tile_builder.dart create mode 100644 lib/src/layer/tile_layer/tile_model.dart create mode 100644 lib/src/layer/tile_layer/tile_overlay_painter.dart create mode 100644 lib/src/layer/tile_layer/tile_painter.dart diff --git a/example/lib/pages/retina.dart b/example/lib/pages/retina.dart index 24158423c..3ddfc77ec 100644 --- a/example/lib/pages/retina.dart +++ b/example/lib/pages/retina.dart @@ -43,12 +43,17 @@ class _RetinaPageState extends State { null => RetinaMode.isHighDensity(context), _ => retinaMode!, }, - tileBuilder: (context, tileWidget, _) => DecoratedBox( - decoration: BoxDecoration( - border: Border.all(width: 2, color: Colors.white), - ), - position: DecorationPosition.foreground, - child: tileWidget, + tileOverlayPainter: ({ + required canvas, + required origin, + required size, + required tile, + }) => + canvas.drawRect( + origin & size, + Paint() + ..color = Colors.white + ..style = PaintingStyle.stroke, ), ); diff --git a/example/lib/pages/tile_builder.dart b/example/lib/pages/tile_builder.dart index 25ddf4dc4..81199bdf9 100644 --- a/example/lib/pages/tile_builder.dart +++ b/example/lib/pages/tile_builder.dart @@ -10,51 +10,37 @@ class TileBuilderPage extends StatefulWidget { const TileBuilderPage({super.key}); @override - TileBuilderPageState createState() => TileBuilderPageState(); + State createState() => _TileBuilderPageState(); } -class TileBuilderPageState extends State { +class _TileBuilderPageState extends State { bool enableGrid = true; bool showCoordinates = true; bool showLoadingTime = true; - bool darkMode = true; + bool enableDarkMode = true; - // mix of [coordinateDebugTileBuilder] and [loadingTimeDebugTileBuilder] from tile_builder.dart - Widget tileBuilder(BuildContext context, Widget tileWidget, TileImage tile) { - final coords = tile.coordinates; - - return DecoratedBox( - decoration: BoxDecoration( - border: enableGrid ? Border.all(width: 2, color: Colors.white) : null, - ), - position: DecorationPosition.foreground, - child: Stack( - fit: StackFit.passthrough, - children: [ - tileWidget, - if (showLoadingTime || showCoordinates) - Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - if (showCoordinates) - Text( - '${coords.x} : ${coords.y} : ${coords.z}', - style: Theme.of(context).textTheme.headlineSmall, - ), - if (showLoadingTime) - Text( - tile.loadFinishedAt == null - ? 'Loading' - // sometimes result is negative which shouldn't happen, abs() corrects it - : '${(tile.loadFinishedAt!.millisecond - tile.loadStarted!.millisecond).abs()} ms', - style: Theme.of(context).textTheme.headlineSmall, - ), - ], - ), - ], - ), - ); - } + final _darkModeColorFilter = const ColorFilter.matrix([ + -1, + 0, + 0, + 0, + 255, + 0, + -1, + 0, + 0, + 255, + 0, + 0, + -1, + 0, + 255, + 0, + 0, + 0, + 1, + 0, + ]); @override Widget build(BuildContext context) { @@ -101,8 +87,8 @@ class TileBuilderPageState extends State { child: Icon(Icons.dark_mode), ), Switch.adaptive( - value: darkMode, - onChanged: (v) => setState(() => darkMode = v), + value: enableDarkMode, + onChanged: (v) => setState(() => enableDarkMode = v), ), ], ), @@ -115,14 +101,14 @@ class TileBuilderPageState extends State { initialZoom: 5, ), children: [ - _darkModeContainerIfEnabled( - TileLayer( - urlTemplate: - 'https://tile.openstreetmap.org/{z}/{x}/{y}.png', - userAgentPackageName: 'dev.fleaflet.flutter_map.example', - tileProvider: CancellableNetworkTileProvider(), - tileBuilder: tileBuilder, - ), + TileLayer( + urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png', + userAgentPackageName: 'dev.fleaflet.flutter_map.example', + tileProvider: CancellableNetworkTileProvider(), + tilePaint: enableDarkMode + ? (Paint()..colorFilter = _darkModeColorFilter) + : null, + tileOverlayPainter: tileOverlayPainter, ), const MarkerLayer( markers: [ @@ -144,9 +130,53 @@ class TileBuilderPageState extends State { ); } - Widget _darkModeContainerIfEnabled(Widget child) { - if (!darkMode) return child; + void tileOverlayPainter({ + required Canvas canvas, + required Offset origin, + required Size size, + required TileImage tile, + }) { + final rect = origin & size; + + if (enableGrid) { + canvas.drawRect( + rect, + Paint() + ..color = enableDarkMode ? Colors.white : Colors.black + ..style = PaintingStyle.stroke, + ); + } + + if (showCoordinates || showLoadingTime) { + final textStyle = TextStyle( + color: enableDarkMode ? Colors.white : Colors.black, + fontSize: 18, + ); + + final textSpan = TextSpan( + text: (showCoordinates ? tile.coordinates.toString() : '') + + (showCoordinates && showLoadingTime ? '\n' : '') + + (showLoadingTime + ? tile.loadFinishedAt == null + ? 'Loading' + // sometimes result is negative which shouldn't happen, abs() corrects it + : '${(tile.loadFinishedAt!.millisecond - tile.loadStarted!.millisecond).abs()} ms' + : ''), + style: textStyle, + ); + final textPainter = TextPainter( + text: textSpan, + textDirection: TextDirection.ltr, + textAlign: TextAlign.center, + ); + textPainter.layout( + minWidth: 0, + maxWidth: size.width, + ); + final xCenter = (size.width - textPainter.width) / 2; + final yCenter = (size.height - textPainter.height) / 2; - return darkModeTilesContainerBuilder(context, child); + textPainter.paint(canvas, origin + Offset(xCenter, yCenter)); + } } } diff --git a/lib/flutter_map.dart b/lib/flutter_map.dart index 8e7d1dd3f..7a7336342 100644 --- a/lib/flutter_map.dart +++ b/lib/flutter_map.dart @@ -38,11 +38,11 @@ export 'package:flutter_map/src/layer/shared/layer_interactivity/layer_hit_resul export 'package:flutter_map/src/layer/shared/line_patterns/stroke_pattern.dart'; export 'package:flutter_map/src/layer/shared/mobile_layer_transformer.dart'; export 'package:flutter_map/src/layer/shared/translucent_pointer.dart'; -export 'package:flutter_map/src/layer/tile_layer/tile_builder.dart'; export 'package:flutter_map/src/layer/tile_layer/tile_coordinates.dart'; export 'package:flutter_map/src/layer/tile_layer/tile_display.dart'; export 'package:flutter_map/src/layer/tile_layer/tile_image.dart'; export 'package:flutter_map/src/layer/tile_layer/tile_layer.dart'; +export 'package:flutter_map/src/layer/tile_layer/tile_overlay_painter.dart'; export 'package:flutter_map/src/layer/tile_layer/tile_provider/asset_tile_provider.dart'; export 'package:flutter_map/src/layer/tile_layer/tile_provider/base_tile_provider.dart'; export 'package:flutter_map/src/layer/tile_layer/tile_provider/file_providers/tile_provider_stub.dart' diff --git a/lib/src/layer/tile_layer/tile.dart b/lib/src/layer/tile_layer/tile.dart deleted file mode 100644 index b438380a5..000000000 --- a/lib/src/layer/tile_layer/tile.dart +++ /dev/null @@ -1,95 +0,0 @@ -import 'dart:math'; - -import 'package:flutter/widgets.dart'; -import 'package:flutter_map/flutter_map.dart'; - -/// The widget for a single tile used for the [TileLayer]. -@immutable -class Tile extends StatefulWidget { - /// [TileImage] is the model class that contains meta data for the Tile image. - final TileImage tileImage; - - /// The [TileBuilder] is a reference to the [TileLayer]'s - /// [TileLayer.tileBuilder]. - final TileBuilder? tileBuilder; - - /// The tile size for the given scale of the map. - final double scaledTileSize; - - /// Reference to the offset of the top-left corner of the bounding rectangle - /// of the [MapCamera]. The origin will not equal the offset of the top-left - /// visible pixel when the map is rotated. - final Point currentPixelOrigin; - - /// Creates a new instance of [Tile]. - const Tile({ - super.key, - required this.scaledTileSize, - required this.currentPixelOrigin, - required this.tileImage, - required this.tileBuilder, - }); - - @override - State createState() => _TileState(); -} - -class _TileState extends State { - @override - void initState() { - super.initState(); - widget.tileImage.addListener(_onTileImageChange); - } - - @override - void dispose() { - widget.tileImage.removeListener(_onTileImageChange); - super.dispose(); - } - - void _onTileImageChange() { - if (mounted) setState(() {}); - } - - @override - Widget build(BuildContext context) { - return Positioned( - left: widget.tileImage.coordinates.x * widget.scaledTileSize - - widget.currentPixelOrigin.x, - top: widget.tileImage.coordinates.y * widget.scaledTileSize - - widget.currentPixelOrigin.y, - width: widget.scaledTileSize, - height: widget.scaledTileSize, - child: widget.tileBuilder?.call(context, _tileImage, widget.tileImage) ?? - _tileImage, - ); - } - - Widget get _tileImage { - if (widget.tileImage.loadError && widget.tileImage.errorImage != null) { - return Image( - image: widget.tileImage.errorImage!, - opacity: widget.tileImage.opacity == 1 - ? null - : AlwaysStoppedAnimation(widget.tileImage.opacity), - ); - } else if (widget.tileImage.animation == null) { - return RawImage( - image: widget.tileImage.imageInfo?.image, - fit: BoxFit.fill, - opacity: widget.tileImage.opacity == 1 - ? null - : AlwaysStoppedAnimation(widget.tileImage.opacity), - ); - } else { - return AnimatedBuilder( - animation: widget.tileImage.animation!, - builder: (context, child) => RawImage( - image: widget.tileImage.imageInfo?.image, - fit: BoxFit.fill, - opacity: widget.tileImage.animation, - ), - ); - } - } -} diff --git a/lib/src/layer/tile_layer/tile_builder.dart b/lib/src/layer/tile_layer/tile_builder.dart deleted file mode 100644 index 2854748cd..000000000 --- a/lib/src/layer/tile_layer/tile_builder.dart +++ /dev/null @@ -1,132 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_map/flutter_map.dart'; - -/// Builder function that returns a [TileBuilder] instance. -typedef TileBuilder = Widget Function( - BuildContext context, Widget tileWidget, TileImage tile); - -/// Applies inversion color matrix on Tiles container which may simulate Dark mode. -Widget darkModeTilesContainerBuilder( - BuildContext context, - Widget tilesContainer, -) { - return ColorFiltered( - colorFilter: const ColorFilter.matrix([ - -1, - 0, - 0, - 0, - 255, - 0, - -1, - 0, - 0, - 255, - 0, - 0, - -1, - 0, - 255, - 0, - 0, - 0, - 1, - 0, - ]), - child: tilesContainer, - ); -} - -/// Applies inversion color matrix on Tiles which may simulate Dark mode. -/// [darkModeTilesContainerBuilder] is better at performance because it applies color matrix on the container instead of on every Tile -Widget darkModeTileBuilder( - BuildContext context, - Widget tileWidget, - TileImage tile, -) { - return ColorFiltered( - colorFilter: const ColorFilter.matrix([ - -1, - 0, - 0, - 0, - 255, - 0, - -1, - 0, - 0, - 255, - 0, - 0, - -1, - 0, - 255, - 0, - 0, - 0, - 1, - 0, - ]), - child: tileWidget, - ); -} - -/// Shows coordinates over Tiles -Widget coordinateDebugTileBuilder( - BuildContext context, - Widget tileWidget, - TileImage tile, -) { - final coordinates = tile.coordinates; - final readableKey = '${coordinates.x} : ${coordinates.y} : ${coordinates.z}'; - - return DecoratedBox( - decoration: BoxDecoration( - border: Border.all(), - ), - child: Stack( - fit: StackFit.passthrough, - children: [ - tileWidget, - Center( - child: Text( - readableKey, - style: Theme.of(context).textTheme.headlineSmall, - ), - ), - ], - ), - ); -} - -/// Shows the Tile loading time in ms -Widget loadingTimeDebugTileBuilder( - BuildContext context, - Widget tileWidget, - TileImage tile, -) { - final loadStarted = tile.loadStarted; - final loaded = tile.loadFinishedAt; - - final time = loaded == null - ? 'Loading' - : '${(loaded.millisecond - loadStarted!.millisecond).abs()} ms'; - - return DecoratedBox( - decoration: BoxDecoration( - border: Border.all(), - ), - child: Stack( - fit: StackFit.passthrough, - children: [ - tileWidget, - Center( - child: Text( - time, - style: Theme.of(context).textTheme.headlineSmall, - ), - ), - ], - ), - ); -} diff --git a/lib/src/layer/tile_layer/tile_layer.dart b/lib/src/layer/tile_layer/tile_layer.dart index c0b8e19e2..603e89456 100644 --- a/lib/src/layer/tile_layer/tile_layer.dart +++ b/lib/src/layer/tile_layer/tile_layer.dart @@ -5,10 +5,11 @@ import 'package:collection/collection.dart' show MapEquality; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_map/flutter_map.dart'; -import 'package:flutter_map/src/layer/tile_layer/tile.dart'; import 'package:flutter_map/src/layer/tile_layer/tile_bounds/tile_bounds.dart'; import 'package:flutter_map/src/layer/tile_layer/tile_bounds/tile_bounds_at_zoom.dart'; import 'package:flutter_map/src/layer/tile_layer/tile_image_manager.dart'; +import 'package:flutter_map/src/layer/tile_layer/tile_model.dart'; +import 'package:flutter_map/src/layer/tile_layer/tile_painter.dart'; import 'package:flutter_map/src/layer/tile_layer/tile_range.dart'; import 'package:flutter_map/src/layer/tile_layer/tile_range_calculator.dart'; import 'package:flutter_map/src/layer/tile_layer/tile_scale_calculator.dart'; @@ -179,10 +180,6 @@ class TileLayer extends StatefulWidget { /// This callback will be executed if an error occurs when fetching tiles. final ErrorTileCallBack? errorTileCallback; - /// Function which may Wrap Tile with custom Widget - /// There are predefined examples in 'tile_builder.dart' - final TileBuilder? tileBuilder; - /// If a Tile was loaded with error and if strategy isn't `none` then TileProvider /// will be asked to evict Image based on current strategy /// (see #576 - even Error Images are cached in flutter) @@ -211,6 +208,67 @@ class TileLayer extends StatefulWidget { /// the [key]. final TileUpdateTransformer tileUpdateTransformer; + /// The style to use when rendering each tile's image on the internal canvas + /// + /// Note that [Paint.filterQuality] is forced [FilterQuality.high] to maintain + /// quality when zooming, and [Paint.isAntiAlias] to `false` to prevent 'ghost + /// lines' from being introduced. The opacity of any specified [Paint.color] + /// may also be modified to provide an animation. + /// + /// Example: setting a color filter to draw tiles in grayscale: + /// ```dart + /// tilePaint: Paint() + /// ..colorFilter = const ColorFilter.mode(Colors.grey, BlendMode.saturation), + /// ``` + /// + /// Example: inverting the colors of the tiles: + /// ```dart + /// tilePaint: Paint() + /// ..invertColors = true, + /// ``` + /// + /// Example: toning map with sepia color: + /// ```dart + /// tilePaint: Paint() + /// ..colorFilter = const ColorFilter.matrix([ + /// 0.393, 0.769, 0.189, 0, 0, + /// 0.349, 0.686, 0.168, 0, 0, + /// 0.272, 0.534, 0.131, 0, 0, + /// 0, 0, 0, 1, 0, + /// ]), + /// ``` + /// + /// See also: + /// * [tileOverlayPainter]: to paint over the tile onto the canvas directly + final Paint? tilePaint; + + /// Callback invoked for every tile, which enables painting over it, directly + /// onto the canvas + /// + /// All draw methods should be called offsetted/relative to the supplied + /// `origin`, and should remain within the constraints given by `size`. A + /// helpful tip is to construct a [Rect] using the following snippet: + /// ```dart + /// final rect = offset & size; + /// ``` + /// + /// Example: overlay a black border around each tile: + /// ```dart + /// tileOverlayPainter: ({ + /// required canvas, + /// required origin, + /// required size, + /// required tile, + /// }) => + /// canvas.drawRect( + /// origin & size, + /// Paint() + /// ..color = Colors.black + /// ..style = PaintingStyle.stroke, + /// ), + /// ``` + final TileOverlayPainter tileOverlayPainter; + /// Create a new [TileLayer] for the [FlutterMap] widget. TileLayer({ super.key, @@ -238,10 +296,11 @@ class TileLayer extends StatefulWidget { /// Defaults to `false` when `null`. final bool? retinaMode, this.errorTileCallback, - this.tileBuilder, this.evictErrorTileStrategy = EvictErrorTileStrategy.none, this.reset, this.tileBounds, + this.tilePaint, + this.tileOverlayPainter, TileUpdateTransformer? tileUpdateTransformer, String userAgentPackageName = 'unknown', }) : assert( @@ -504,26 +563,24 @@ class _TileLayerState extends State with TickerProviderStateMixin { // cycles saved later on in the render pipeline. final tiles = _tileImageManager .getTilesToRender(visibleRange: visibleTileRange) - .map((tileImage) => Tile( - // Must be an ObjectKey, not a ValueKey using the coordinates, in - // case we remove and replace the TileImage with a different one. - key: ObjectKey(tileImage), - scaledTileSize: _tileScaleCalculator.scaledTileSize( - map.zoom, - tileImage.coordinates.z, - ), - currentPixelOrigin: map.pixelOrigin, - tileImage: tileImage, - tileBuilder: widget.tileBuilder, - )) + .map( + (tileImage) => TileModel( + scaledTileSize: _tileScaleCalculator.scaledTileSize( + map.zoom, + tileImage.coordinates.z, + ), + currentPixelOrigin: map.pixelOrigin, + tileImage: tileImage, + ), + ) .toList(); - // Sort in render order. In reverse: - // 1. Tiles at the current zoom. - // 2. Tiles at the current zoom +/- 1. - // 3. Tiles at the current zoom +/- 2. - // 4. ...etc - int renderOrder(Tile a, Tile b) { + /// Sort in render order. In reverse: + /// 1. Tiles at the current zoom. + /// 2. Tiles at the current zoom +/- 1. + /// 3. Tiles at the current zoom +/- 2. + /// 4. ...etc + int renderOrder(TileModel a, TileModel b) { final (za, zb) = (a.tileImage.coordinates.z, b.tileImage.coordinates.z); final cmp = (zb - tileZoom).abs().compareTo((za - tileZoom).abs()); if (cmp == 0) { @@ -534,7 +591,15 @@ class _TileLayerState extends State with TickerProviderStateMixin { } return MobileLayerTransformer( - child: Stack(children: tiles..sort(renderOrder)), + child: CustomPaint( + size: Size.infinite, + willChange: true, + painter: TilePainter( + tiles: tiles..sort(renderOrder), + tilePaint: widget.tilePaint, + tileOverlayPainter: widget.tileOverlayPainter, + ), + ), ); } diff --git a/lib/src/layer/tile_layer/tile_model.dart b/lib/src/layer/tile_layer/tile_model.dart new file mode 100644 index 000000000..500310872 --- /dev/null +++ b/lib/src/layer/tile_layer/tile_model.dart @@ -0,0 +1,36 @@ +import 'dart:math'; +import 'package:flutter_map/flutter_map.dart'; +import 'package:flutter_map/src/layer/tile_layer/tile_painter.dart'; + +/// Model for tiles displayed by [TileLayer] and [TilePainter] +class TileModel { + /// [TileImage] is the model class that contains meta data for the Tile image. + final TileImage tileImage; + + /// The tile size for the given scale of the map. + final double scaledTileSize; + + /// Reference to the offset of the top-left corner of the bounding rectangle + /// of the [MapCamera]. The origin will not equal the offset of the top-left + /// visible pixel when the map is rotated. + final Point currentPixelOrigin; + + /// Creates a new instance of TileModel. + const TileModel({ + required this.scaledTileSize, + required this.currentPixelOrigin, + required this.tileImage, + }); + + @override + bool operator ==(Object other) => + identical(this, other) || + (other is TileModel && + tileImage == other.tileImage && + scaledTileSize == other.scaledTileSize && + currentPixelOrigin == other.currentPixelOrigin); + + @override + int get hashCode => + Object.hash(tileImage, scaledTileSize, currentPixelOrigin); +} diff --git a/lib/src/layer/tile_layer/tile_overlay_painter.dart b/lib/src/layer/tile_layer/tile_overlay_painter.dart new file mode 100644 index 000000000..7f2fa4bff --- /dev/null +++ b/lib/src/layer/tile_layer/tile_overlay_painter.dart @@ -0,0 +1,13 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_map/src/layer/tile_layer/tile_image.dart'; +import 'package:flutter_map/src/layer/tile_layer/tile_layer.dart'; + +/// A callback that can draw directly on the canvas, over a tile +/// +/// See [TileLayer.tileOverlayPainter] for more information. +typedef TileOverlayPainter = void Function({ + required Canvas canvas, + required Offset origin, + required Size size, + required TileImage tile, +})?; diff --git a/lib/src/layer/tile_layer/tile_painter.dart b/lib/src/layer/tile_layer/tile_painter.dart new file mode 100644 index 000000000..3ef2d783e --- /dev/null +++ b/lib/src/layer/tile_layer/tile_painter.dart @@ -0,0 +1,65 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_map/src/layer/tile_layer/tile_model.dart'; +import 'package:flutter_map/src/layer/tile_layer/tile_overlay_painter.dart'; +import 'package:meta/meta.dart'; + +/// Draws [TileModel]s onto a canvas at the correct position +@internal +class TilePainter extends CustomPainter { + final List tiles; + final Paint? tilePaint; + final TileOverlayPainter tileOverlayPainter; + final Paint _basePaint; + + TilePainter({ + required this.tiles, + required this.tilePaint, + required this.tileOverlayPainter, + }) : _basePaint = (tilePaint ?? Paint()) + ..filterQuality = FilterQuality.high + ..isAntiAlias = true, + super( + repaint: Listenable.merge(tiles + .map((t) => t.tileImage.animation) + .followedBy(tiles.map((t) => t.tileImage))), + ); + + @override + void paint(Canvas canvas, Size size) { + for (final tile in tiles) { + if (tile.tileImage.imageInfo != null) { + final image = tile.tileImage.imageInfo!.image; + + final origin = Offset( + tile.tileImage.coordinates.x * tile.scaledTileSize - + tile.currentPixelOrigin.x, + tile.tileImage.coordinates.y * tile.scaledTileSize - + tile.currentPixelOrigin.y, + ); + final destSize = Size.square(tile.scaledTileSize); + + final paint = _basePaint + ..color = (tilePaint?.color.withOpacity(tile.tileImage.opacity) ?? + Color.fromRGBO(0, 0, 0, tile.tileImage.opacity)); + + canvas.drawImageRect( + image, + Offset.zero & + Size(image.width.toDouble(), image.height.toDouble()), // src + origin & destSize, // dest + paint, + ); + + tileOverlayPainter?.call( + canvas: canvas, + origin: origin, + size: destSize, + tile: tile.tileImage, + ); + } + } + } + + @override + bool shouldRepaint(covariant TilePainter oldDelegate) => true; +} diff --git a/test/full_coverage_test.dart b/test/full_coverage_test.dart index 3e1f687bd..888d21e39 100644 --- a/test/full_coverage_test.dart +++ b/test/full_coverage_test.dart @@ -20,16 +20,17 @@ import 'package:flutter_map/src/layer/polyline_layer/polyline_layer.dart'; import 'package:flutter_map/src/layer/shared/layer_interactivity/internal_hit_detectable.dart'; import 'package:flutter_map/src/layer/shared/mobile_layer_transformer.dart'; import 'package:flutter_map/src/layer/shared/translucent_pointer.dart'; -import 'package:flutter_map/src/layer/tile_layer/tile.dart'; import 'package:flutter_map/src/layer/tile_layer/tile_bounds/tile_bounds.dart'; import 'package:flutter_map/src/layer/tile_layer/tile_bounds/tile_bounds_at_zoom.dart'; -import 'package:flutter_map/src/layer/tile_layer/tile_builder.dart'; import 'package:flutter_map/src/layer/tile_layer/tile_coordinates.dart'; import 'package:flutter_map/src/layer/tile_layer/tile_display.dart'; import 'package:flutter_map/src/layer/tile_layer/tile_image.dart'; import 'package:flutter_map/src/layer/tile_layer/tile_image_manager.dart'; import 'package:flutter_map/src/layer/tile_layer/tile_image_view.dart'; import 'package:flutter_map/src/layer/tile_layer/tile_layer.dart'; +import 'package:flutter_map/src/layer/tile_layer/tile_model.dart'; +import 'package:flutter_map/src/layer/tile_layer/tile_overlay_painter.dart'; +import 'package:flutter_map/src/layer/tile_layer/tile_painter.dart'; import 'package:flutter_map/src/layer/tile_layer/tile_provider/asset_tile_provider.dart'; import 'package:flutter_map/src/layer/tile_layer/tile_provider/base_tile_provider.dart'; import 'package:flutter_map/src/layer/tile_layer/tile_provider/file_providers/tile_provider_io.dart'; From 6170df99ce85126259e9caced13969309dd045cf Mon Sep 17 00:00:00 2001 From: JaffaKetchup Date: Thu, 6 Jun 2024 09:51:25 +0100 Subject: [PATCH 2/2] Updated tests --- test/flutter_map_test.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/test/flutter_map_test.dart b/test/flutter_map_test.dart index 6d9599380..31cc5bd18 100644 --- a/test/flutter_map_test.dart +++ b/test/flutter_map_test.dart @@ -25,7 +25,6 @@ void main() { await tester.pumpWidget(TestApp(markers: markers)); expect(find.byType(FlutterMap), findsOneWidget); expect(find.byType(TileLayer), findsOneWidget); - expect(find.byType(RawImage), findsWidgets); expect(find.byType(MarkerLayer), findsWidgets); expect(find.byType(FlutterLogo), findsOneWidget); });