mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
migrate part of painting to nullsafety (#62951)
This commit is contained in:
parent
2c1b95b9e7
commit
e8c942104b
@ -2,7 +2,6 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// @dart = 2.8
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
@ -33,7 +32,7 @@ class NetworkImage extends image_provider.ImageProvider<image_provider.NetworkIm
|
||||
final double scale;
|
||||
|
||||
@override
|
||||
final Map<String, String> headers;
|
||||
final Map<String, String>? headers;
|
||||
|
||||
@override
|
||||
Future<NetworkImage> obtainKey(image_provider.ImageConfiguration configuration) {
|
||||
@ -71,7 +70,7 @@ class NetworkImage extends image_provider.ImageProvider<image_provider.NetworkIm
|
||||
HttpClient client = _sharedHttpClient;
|
||||
assert(() {
|
||||
if (debugNetworkImageHttpClientProvider != null)
|
||||
client = debugNetworkImageHttpClientProvider();
|
||||
client = debugNetworkImageHttpClientProvider!();
|
||||
return true;
|
||||
}());
|
||||
return client;
|
||||
@ -102,7 +101,7 @@ class NetworkImage extends image_provider.ImageProvider<image_provider.NetworkIm
|
||||
|
||||
final Uint8List bytes = await consolidateHttpClientResponseBytes(
|
||||
response,
|
||||
onBytesReceived: (int cumulative, int total) {
|
||||
onBytesReceived: (int cumulative, int? total) {
|
||||
chunkEvents.add(ImageChunkEvent(
|
||||
cumulativeBytesLoaded: cumulative,
|
||||
expectedTotalBytes: total,
|
||||
@ -118,7 +117,7 @@ class NetworkImage extends image_provider.ImageProvider<image_provider.NetworkIm
|
||||
// have had a chance to track the key in the cache at all.
|
||||
// Schedule a microtask to give the cache a chance to add the key.
|
||||
scheduleMicrotask(() {
|
||||
PaintingBinding.instance.imageCache.evict(key);
|
||||
PaintingBinding.instance!.imageCache!.evict(key);
|
||||
});
|
||||
rethrow;
|
||||
} finally {
|
||||
|
@ -2,7 +2,6 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// @dart = 2.8
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:ui' as ui;
|
||||
@ -33,7 +32,7 @@ class NetworkImage
|
||||
final double scale;
|
||||
|
||||
@override
|
||||
final Map<String, String> headers;
|
||||
final Map<String, String>? headers;
|
||||
|
||||
@override
|
||||
Future<NetworkImage> obtainKey(
|
||||
@ -58,9 +57,9 @@ class NetworkImage
|
||||
informationCollector: _imageStreamInformationCollector(key));
|
||||
}
|
||||
|
||||
InformationCollector _imageStreamInformationCollector(
|
||||
InformationCollector? _imageStreamInformationCollector(
|
||||
image_provider.NetworkImage key) {
|
||||
InformationCollector collector;
|
||||
InformationCollector? collector;
|
||||
assert(() {
|
||||
collector = () {
|
||||
return <DiagnosticsNode>[
|
||||
|
@ -2,7 +2,6 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// @dart = 2.8
|
||||
|
||||
import 'dart:math' as math;
|
||||
|
||||
@ -57,24 +56,24 @@ class BeveledRectangleBorder extends OutlinedBorder {
|
||||
}
|
||||
|
||||
@override
|
||||
ShapeBorder lerpFrom(ShapeBorder a, double t) {
|
||||
ShapeBorder? lerpFrom(ShapeBorder? a, double t) {
|
||||
assert(t != null);
|
||||
if (a is BeveledRectangleBorder) {
|
||||
return BeveledRectangleBorder(
|
||||
side: BorderSide.lerp(a.side, side, t),
|
||||
borderRadius: BorderRadiusGeometry.lerp(a.borderRadius, borderRadius, t),
|
||||
borderRadius: BorderRadiusGeometry.lerp(a.borderRadius, borderRadius, t)!,
|
||||
);
|
||||
}
|
||||
return super.lerpFrom(a, t);
|
||||
}
|
||||
|
||||
@override
|
||||
ShapeBorder lerpTo(ShapeBorder b, double t) {
|
||||
ShapeBorder? lerpTo(ShapeBorder? b, double t) {
|
||||
assert(t != null);
|
||||
if (b is BeveledRectangleBorder) {
|
||||
return BeveledRectangleBorder(
|
||||
side: BorderSide.lerp(side, b.side, t),
|
||||
borderRadius: BorderRadiusGeometry.lerp(borderRadius, b.borderRadius, t),
|
||||
borderRadius: BorderRadiusGeometry.lerp(borderRadius, b.borderRadius, t)!,
|
||||
);
|
||||
}
|
||||
return super.lerpTo(b, t);
|
||||
@ -83,7 +82,7 @@ class BeveledRectangleBorder extends OutlinedBorder {
|
||||
/// Returns a copy of this RoundedRectangleBorder with the given fields
|
||||
/// replaced with the new values.
|
||||
@override
|
||||
BeveledRectangleBorder copyWith({ BorderSide side, BorderRadius borderRadius }) {
|
||||
BeveledRectangleBorder copyWith({ BorderSide? side, BorderRadius? borderRadius }) {
|
||||
return BeveledRectangleBorder(
|
||||
side: side ?? this.side,
|
||||
borderRadius: borderRadius ?? this.borderRadius,
|
||||
@ -120,17 +119,17 @@ class BeveledRectangleBorder extends OutlinedBorder {
|
||||
}
|
||||
|
||||
@override
|
||||
Path getInnerPath(Rect rect, { TextDirection textDirection }) {
|
||||
Path getInnerPath(Rect rect, { TextDirection? textDirection }) {
|
||||
return _getPath(borderRadius.resolve(textDirection).toRRect(rect).deflate(side.width));
|
||||
}
|
||||
|
||||
@override
|
||||
Path getOuterPath(Rect rect, { TextDirection textDirection }) {
|
||||
Path getOuterPath(Rect rect, { TextDirection? textDirection }) {
|
||||
return _getPath(borderRadius.resolve(textDirection).toRRect(rect));
|
||||
}
|
||||
|
||||
@override
|
||||
void paint(Canvas canvas, Rect rect, { TextDirection textDirection }) {
|
||||
void paint(Canvas canvas, Rect rect, { TextDirection? textDirection }) {
|
||||
if (rect.isEmpty)
|
||||
return;
|
||||
switch (side.style) {
|
||||
|
@ -2,7 +2,6 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// @dart = 2.8
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
@ -130,7 +129,7 @@ abstract class BorderRadiusGeometry {
|
||||
/// into a concrete [BorderRadius] using [resolve].
|
||||
///
|
||||
/// {@macro dart.ui.shadow.lerp}
|
||||
static BorderRadiusGeometry lerp(BorderRadiusGeometry a, BorderRadiusGeometry b, double t) {
|
||||
static BorderRadiusGeometry? lerp(BorderRadiusGeometry? a, BorderRadiusGeometry? b, double t) {
|
||||
assert(t != null);
|
||||
if (a == null && b == null)
|
||||
return null;
|
||||
@ -148,11 +147,11 @@ abstract class BorderRadiusGeometry {
|
||||
/// * [BorderRadius], for which this is a no-op (returns itself).
|
||||
/// * [BorderRadiusDirectional], which flips the horizontal direction
|
||||
/// based on the `direction` argument.
|
||||
BorderRadius resolve(TextDirection direction);
|
||||
BorderRadius resolve(TextDirection? direction);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
String visual, logical;
|
||||
String? visual, logical;
|
||||
if (_topLeft == _topRight &&
|
||||
_topRight == _bottomLeft &&
|
||||
_bottomLeft == _bottomRight) {
|
||||
@ -474,24 +473,24 @@ class BorderRadius extends BorderRadiusGeometry {
|
||||
/// If either is null, this function interpolates from [BorderRadius.zero].
|
||||
///
|
||||
/// {@macro dart.ui.shadow.lerp}
|
||||
static BorderRadius lerp(BorderRadius a, BorderRadius b, double t) {
|
||||
static BorderRadius? lerp(BorderRadius? a, BorderRadius? b, double t) {
|
||||
assert(t != null);
|
||||
if (a == null && b == null)
|
||||
return null;
|
||||
if (a == null)
|
||||
return b * t;
|
||||
return b! * t;
|
||||
if (b == null)
|
||||
return a * (1.0 - t);
|
||||
return BorderRadius.only(
|
||||
topLeft: Radius.lerp(a.topLeft, b.topLeft, t),
|
||||
topRight: Radius.lerp(a.topRight, b.topRight, t),
|
||||
bottomLeft: Radius.lerp(a.bottomLeft, b.bottomLeft, t),
|
||||
bottomRight: Radius.lerp(a.bottomRight, b.bottomRight, t),
|
||||
topLeft: Radius.lerp(a.topLeft, b.topLeft, t)!,
|
||||
topRight: Radius.lerp(a.topRight, b.topRight, t)!,
|
||||
bottomLeft: Radius.lerp(a.bottomLeft, b.bottomLeft, t)!,
|
||||
bottomRight: Radius.lerp(a.bottomRight, b.bottomRight, t)!,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
BorderRadius resolve(TextDirection direction) => this;
|
||||
BorderRadius resolve(TextDirection? direction) => this;
|
||||
}
|
||||
|
||||
/// An immutable set of radii for each corner of a rectangle, but with the
|
||||
@ -691,26 +690,26 @@ class BorderRadiusDirectional extends BorderRadiusGeometry {
|
||||
/// If either is null, this function interpolates from [BorderRadiusDirectional.zero].
|
||||
///
|
||||
/// {@macro dart.ui.shadow.lerp}
|
||||
static BorderRadiusDirectional lerp(BorderRadiusDirectional a, BorderRadiusDirectional b, double t) {
|
||||
static BorderRadiusDirectional? lerp(BorderRadiusDirectional? a, BorderRadiusDirectional? b, double t) {
|
||||
assert(t != null);
|
||||
if (a == null && b == null)
|
||||
return null;
|
||||
if (a == null)
|
||||
return b * t;
|
||||
return b! * t;
|
||||
if (b == null)
|
||||
return a * (1.0 - t);
|
||||
return BorderRadiusDirectional.only(
|
||||
topStart: Radius.lerp(a.topStart, b.topStart, t),
|
||||
topEnd: Radius.lerp(a.topEnd, b.topEnd, t),
|
||||
bottomStart: Radius.lerp(a.bottomStart, b.bottomStart, t),
|
||||
bottomEnd: Radius.lerp(a.bottomEnd, b.bottomEnd, t),
|
||||
topStart: Radius.lerp(a.topStart, b.topStart, t)!,
|
||||
topEnd: Radius.lerp(a.topEnd, b.topEnd, t)!,
|
||||
bottomStart: Radius.lerp(a.bottomStart, b.bottomStart, t)!,
|
||||
bottomEnd: Radius.lerp(a.bottomEnd, b.bottomEnd, t)!,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
BorderRadius resolve(TextDirection direction) {
|
||||
BorderRadius resolve(TextDirection? direction) {
|
||||
assert(direction != null);
|
||||
switch (direction) {
|
||||
switch (direction!) {
|
||||
case TextDirection.rtl:
|
||||
return BorderRadius.only(
|
||||
topLeft: topEnd,
|
||||
@ -726,7 +725,6 @@ class BorderRadiusDirectional extends BorderRadiusGeometry {
|
||||
bottomRight: bottomEnd,
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -838,9 +836,9 @@ class _MixedBorderRadius extends BorderRadiusGeometry {
|
||||
}
|
||||
|
||||
@override
|
||||
BorderRadius resolve(TextDirection direction) {
|
||||
BorderRadius resolve(TextDirection? direction) {
|
||||
assert(direction != null);
|
||||
switch (direction) {
|
||||
switch (direction!) {
|
||||
case TextDirection.rtl:
|
||||
return BorderRadius.only(
|
||||
topLeft: _topLeft + _topEnd,
|
||||
@ -856,6 +854,5 @@ class _MixedBorderRadius extends BorderRadiusGeometry {
|
||||
bottomRight: _bottomRight + _bottomEnd,
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,6 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// @dart = 2.8
|
||||
|
||||
import 'dart:math' as math;
|
||||
import 'dart:ui' as ui show lerpDouble;
|
||||
@ -130,9 +129,9 @@ class BorderSide {
|
||||
|
||||
/// Creates a copy of this border but with the given fields replaced with the new values.
|
||||
BorderSide copyWith({
|
||||
Color color,
|
||||
double width,
|
||||
BorderStyle style,
|
||||
Color? color,
|
||||
double? width,
|
||||
BorderStyle? style,
|
||||
}) {
|
||||
assert(width == null || width >= 0.0);
|
||||
return BorderSide(
|
||||
@ -186,7 +185,6 @@ class BorderSide {
|
||||
..strokeWidth = 0.0
|
||||
..style = PaintingStyle.stroke;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// Whether the two given [BorderSide]s can be merged using [new
|
||||
@ -219,12 +217,12 @@ class BorderSide {
|
||||
return a;
|
||||
if (t == 1.0)
|
||||
return b;
|
||||
final double width = ui.lerpDouble(a.width, b.width, t);
|
||||
final double width = ui.lerpDouble(a.width, b.width, t)!;
|
||||
if (width < 0.0)
|
||||
return BorderSide.none;
|
||||
if (a.style == b.style) {
|
||||
return BorderSide(
|
||||
color: Color.lerp(a.color, b.color, t),
|
||||
color: Color.lerp(a.color, b.color, t)!,
|
||||
width: width,
|
||||
style: a.style, // == b.style
|
||||
);
|
||||
@ -247,7 +245,7 @@ class BorderSide {
|
||||
break;
|
||||
}
|
||||
return BorderSide(
|
||||
color: Color.lerp(colorA, colorB, t),
|
||||
color: Color.lerp(colorA, colorB, t)!,
|
||||
width: width,
|
||||
style: BorderStyle.solid,
|
||||
);
|
||||
@ -319,7 +317,7 @@ abstract class ShapeBorder {
|
||||
/// The `reversed` argument is true if this object was the right operand of
|
||||
/// the `+` operator, and false if it was the left operand.
|
||||
@protected
|
||||
ShapeBorder add(ShapeBorder other, { bool reversed = false }) => null;
|
||||
ShapeBorder? add(ShapeBorder other, { bool reversed = false }) => null;
|
||||
|
||||
/// Creates a new border consisting of the two borders on either side of the
|
||||
/// operator.
|
||||
@ -382,7 +380,7 @@ abstract class ShapeBorder {
|
||||
///
|
||||
/// Instead of calling this directly, use [ShapeBorder.lerp].
|
||||
@protected
|
||||
ShapeBorder lerpFrom(ShapeBorder a, double t) {
|
||||
ShapeBorder? lerpFrom(ShapeBorder? a, double t) {
|
||||
if (a == null)
|
||||
return scale(t);
|
||||
return null;
|
||||
@ -414,7 +412,7 @@ abstract class ShapeBorder {
|
||||
///
|
||||
/// Instead of calling this directly, use [ShapeBorder.lerp].
|
||||
@protected
|
||||
ShapeBorder lerpTo(ShapeBorder b, double t) {
|
||||
ShapeBorder? lerpTo(ShapeBorder? b, double t) {
|
||||
if (b == null)
|
||||
return scale(1.0 - t);
|
||||
return null;
|
||||
@ -428,9 +426,9 @@ abstract class ShapeBorder {
|
||||
/// and `b` after `t=0.5`.
|
||||
///
|
||||
/// {@macro dart.ui.shadow.lerp}
|
||||
static ShapeBorder lerp(ShapeBorder a, ShapeBorder b, double t) {
|
||||
static ShapeBorder? lerp(ShapeBorder? a, ShapeBorder? b, double t) {
|
||||
assert(t != null);
|
||||
ShapeBorder result;
|
||||
ShapeBorder? result;
|
||||
if (b != null)
|
||||
result = b.lerpFrom(a, t);
|
||||
if (result == null && a != null)
|
||||
@ -457,7 +455,7 @@ abstract class ShapeBorder {
|
||||
///
|
||||
/// * [getInnerPath], which creates the path for the inner edge.
|
||||
/// * [Path.contains], which can tell if an [Offset] is within a [Path].
|
||||
Path getOuterPath(Rect rect, { TextDirection textDirection });
|
||||
Path getOuterPath(Rect rect, { TextDirection? textDirection });
|
||||
|
||||
/// Create a [Path] that describes the inner edge of the border.
|
||||
///
|
||||
@ -478,7 +476,7 @@ abstract class ShapeBorder {
|
||||
///
|
||||
/// * [getOuterPath], which creates the path for the outer edge.
|
||||
/// * [Path.contains], which can tell if an [Offset] is within a [Path].
|
||||
Path getInnerPath(Rect rect, { TextDirection textDirection });
|
||||
Path getInnerPath(Rect rect, { TextDirection? textDirection });
|
||||
|
||||
/// Paints the border within the given [Rect] on the given [Canvas].
|
||||
///
|
||||
@ -486,7 +484,7 @@ abstract class ShapeBorder {
|
||||
/// has a text direction dependency (for example if it is expressed in terms
|
||||
/// of "start" and "end" instead of "left" and "right"). It may be null if
|
||||
/// the border will not need the text direction to paint itself.
|
||||
void paint(Canvas canvas, Rect rect, { TextDirection textDirection });
|
||||
void paint(Canvas canvas, Rect rect, { TextDirection? textDirection });
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
@ -548,7 +546,7 @@ class _CompoundBorder extends ShapeBorder {
|
||||
// border, and "merged" is the result of attempting to merge it with the
|
||||
// new border. If it's null, it couldn't be merged.
|
||||
final ShapeBorder ours = reversed ? borders.last : borders.first;
|
||||
final ShapeBorder merged = ours.add(other, reversed: reversed)
|
||||
final ShapeBorder? merged = ours.add(other, reversed: reversed)
|
||||
?? other.add(ours, reversed: !reversed);
|
||||
if (merged != null) {
|
||||
final List<ShapeBorder> result = <ShapeBorder>[...borders];
|
||||
@ -574,27 +572,27 @@ class _CompoundBorder extends ShapeBorder {
|
||||
}
|
||||
|
||||
@override
|
||||
ShapeBorder lerpFrom(ShapeBorder a, double t) {
|
||||
ShapeBorder? lerpFrom(ShapeBorder? a, double t) {
|
||||
return _CompoundBorder.lerp(a, this, t);
|
||||
}
|
||||
|
||||
@override
|
||||
ShapeBorder lerpTo(ShapeBorder b, double t) {
|
||||
ShapeBorder? lerpTo(ShapeBorder? b, double t) {
|
||||
return _CompoundBorder.lerp(this, b, t);
|
||||
}
|
||||
|
||||
static _CompoundBorder lerp(ShapeBorder a, ShapeBorder b, double t) {
|
||||
static _CompoundBorder lerp(ShapeBorder? a, ShapeBorder? b, double t) {
|
||||
assert(t != null);
|
||||
assert(a is _CompoundBorder || b is _CompoundBorder); // Not really necessary, but all call sites currently intend this.
|
||||
final List<ShapeBorder> aList = a is _CompoundBorder ? a.borders : <ShapeBorder>[a];
|
||||
final List<ShapeBorder> bList = b is _CompoundBorder ? b.borders : <ShapeBorder>[b];
|
||||
final List<ShapeBorder?> aList = a is _CompoundBorder ? a.borders : <ShapeBorder?>[a];
|
||||
final List<ShapeBorder?> bList = b is _CompoundBorder ? b.borders : <ShapeBorder?>[b];
|
||||
final List<ShapeBorder> results = <ShapeBorder>[];
|
||||
final int length = math.max(aList.length, bList.length);
|
||||
for (int index = 0; index < length; index += 1) {
|
||||
final ShapeBorder localA = index < aList.length ? aList[index] : null;
|
||||
final ShapeBorder localB = index < bList.length ? bList[index] : null;
|
||||
final ShapeBorder? localA = index < aList.length ? aList[index] : null;
|
||||
final ShapeBorder? localB = index < bList.length ? bList[index] : null;
|
||||
if (localA != null && localB != null) {
|
||||
final ShapeBorder localResult = localA.lerpTo(localB, t) ?? localB.lerpFrom(localA, t);
|
||||
final ShapeBorder? localResult = localA.lerpTo(localB, t) ?? localB.lerpFrom(localA, t);
|
||||
if (localResult != null) {
|
||||
results.add(localResult);
|
||||
continue;
|
||||
@ -613,19 +611,19 @@ class _CompoundBorder extends ShapeBorder {
|
||||
}
|
||||
|
||||
@override
|
||||
Path getInnerPath(Rect rect, { TextDirection textDirection }) {
|
||||
Path getInnerPath(Rect rect, { TextDirection? textDirection }) {
|
||||
for (int index = 0; index < borders.length - 1; index += 1)
|
||||
rect = borders[index].dimensions.resolve(textDirection).deflateRect(rect);
|
||||
return borders.last.getInnerPath(rect, textDirection: textDirection);
|
||||
}
|
||||
|
||||
@override
|
||||
Path getOuterPath(Rect rect, { TextDirection textDirection }) {
|
||||
Path getOuterPath(Rect rect, { TextDirection? textDirection }) {
|
||||
return borders.first.getOuterPath(rect, textDirection: textDirection);
|
||||
}
|
||||
|
||||
@override
|
||||
void paint(Canvas canvas, Rect rect, { TextDirection textDirection }) {
|
||||
void paint(Canvas canvas, Rect rect, { TextDirection? textDirection }) {
|
||||
for (final ShapeBorder border in borders) {
|
||||
border.paint(canvas, rect, textDirection: textDirection);
|
||||
rect = border.dimensions.resolve(textDirection).deflateRect(rect);
|
||||
|
@ -2,7 +2,6 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// @dart = 2.8
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
@ -85,7 +84,7 @@ abstract class BoxBorder extends ShapeBorder {
|
||||
// We override this to tighten the return value, so that callers can assume
|
||||
// that we'll return a [BoxBorder].
|
||||
@override
|
||||
BoxBorder add(ShapeBorder other, { bool reversed = false }) => null;
|
||||
BoxBorder? add(ShapeBorder other, { bool reversed = false }) => null;
|
||||
|
||||
/// Linearly interpolate between two borders.
|
||||
///
|
||||
@ -104,12 +103,12 @@ abstract class BoxBorder extends ShapeBorder {
|
||||
/// instead [add] the two sets of sides and interpolate them simultaneously.
|
||||
///
|
||||
/// {@macro dart.ui.shadow.lerp}
|
||||
static BoxBorder lerp(BoxBorder a, BoxBorder b, double t) {
|
||||
static BoxBorder? lerp(BoxBorder? a, BoxBorder? b, double t) {
|
||||
assert(t != null);
|
||||
if ((a is Border || a == null) && (b is Border || b == null))
|
||||
return Border.lerp(a as Border, b as Border, t);
|
||||
if ((a is BorderDirectional || a == null) && (b is BorderDirectional || b == null))
|
||||
return BorderDirectional.lerp(a as BorderDirectional, b as BorderDirectional, t);
|
||||
if ((a is Border?) && (b is Border?))
|
||||
return Border.lerp(a, b, t);
|
||||
if ((a is BorderDirectional?) && (b is BorderDirectional?))
|
||||
return BorderDirectional.lerp(a, b, t);
|
||||
if (b is Border && a is BorderDirectional) {
|
||||
final BoxBorder c = b;
|
||||
b = a;
|
||||
@ -167,14 +166,14 @@ abstract class BoxBorder extends ShapeBorder {
|
||||
}
|
||||
|
||||
@override
|
||||
Path getInnerPath(Rect rect, { @required TextDirection textDirection }) {
|
||||
Path getInnerPath(Rect rect, { TextDirection? textDirection }) {
|
||||
assert(textDirection != null, 'The textDirection argument to $runtimeType.getInnerPath must not be null.');
|
||||
return Path()
|
||||
..addRect(dimensions.resolve(textDirection).deflateRect(rect));
|
||||
}
|
||||
|
||||
@override
|
||||
Path getOuterPath(Rect rect, { @required TextDirection textDirection }) {
|
||||
Path getOuterPath(Rect rect, { TextDirection? textDirection }) {
|
||||
assert(textDirection != null, 'The textDirection argument to $runtimeType.getOuterPath must not be null.');
|
||||
return Path()
|
||||
..addRect(rect);
|
||||
@ -203,9 +202,9 @@ abstract class BoxBorder extends ShapeBorder {
|
||||
void paint(
|
||||
Canvas canvas,
|
||||
Rect rect, {
|
||||
TextDirection textDirection,
|
||||
TextDirection? textDirection,
|
||||
BoxShape shape = BoxShape.rectangle,
|
||||
BorderRadius borderRadius,
|
||||
BorderRadius? borderRadius,
|
||||
});
|
||||
|
||||
static void _paintUniformBorderWithRadius(Canvas canvas, Rect rect, BorderSide side, BorderRadius borderRadius) {
|
||||
@ -414,7 +413,7 @@ class Border extends BoxBorder {
|
||||
}
|
||||
|
||||
@override
|
||||
Border add(ShapeBorder other, { bool reversed = false }) {
|
||||
Border? add(ShapeBorder other, { bool reversed = false }) {
|
||||
if (other is Border &&
|
||||
BorderSide.canMerge(top, other.top) &&
|
||||
BorderSide.canMerge(right, other.right) &&
|
||||
@ -436,14 +435,14 @@ class Border extends BoxBorder {
|
||||
}
|
||||
|
||||
@override
|
||||
ShapeBorder lerpFrom(ShapeBorder a, double t) {
|
||||
ShapeBorder? lerpFrom(ShapeBorder? a, double t) {
|
||||
if (a is Border)
|
||||
return Border.lerp(a, this, t);
|
||||
return super.lerpFrom(a, t);
|
||||
}
|
||||
|
||||
@override
|
||||
ShapeBorder lerpTo(ShapeBorder b, double t) {
|
||||
ShapeBorder? lerpTo(ShapeBorder? b, double t) {
|
||||
if (b is Border)
|
||||
return Border.lerp(this, b, t);
|
||||
return super.lerpTo(b, t);
|
||||
@ -455,12 +454,12 @@ class Border extends BoxBorder {
|
||||
/// borders.
|
||||
///
|
||||
/// {@macro dart.ui.shadow.lerp}
|
||||
static Border lerp(Border a, Border b, double t) {
|
||||
static Border? lerp(Border? a, Border? b, double t) {
|
||||
assert(t != null);
|
||||
if (a == null && b == null)
|
||||
return null;
|
||||
if (a == null)
|
||||
return b.scale(t);
|
||||
return b!.scale(t);
|
||||
if (b == null)
|
||||
return a.scale(1.0 - t);
|
||||
return Border(
|
||||
@ -494,9 +493,9 @@ class Border extends BoxBorder {
|
||||
void paint(
|
||||
Canvas canvas,
|
||||
Rect rect, {
|
||||
TextDirection textDirection,
|
||||
TextDirection? textDirection,
|
||||
BoxShape shape = BoxShape.rectangle,
|
||||
BorderRadius borderRadius,
|
||||
BorderRadius? borderRadius,
|
||||
}) {
|
||||
if (isUniform) {
|
||||
switch (top.style) {
|
||||
@ -694,7 +693,7 @@ class BorderDirectional extends BoxBorder {
|
||||
}
|
||||
|
||||
@override
|
||||
BoxBorder add(ShapeBorder other, { bool reversed = false }) {
|
||||
BoxBorder? add(ShapeBorder other, { bool reversed = false }) {
|
||||
if (other is BorderDirectional) {
|
||||
final BorderDirectional typedOther = other;
|
||||
if (BorderSide.canMerge(top, typedOther.top) &&
|
||||
@ -747,14 +746,14 @@ class BorderDirectional extends BoxBorder {
|
||||
}
|
||||
|
||||
@override
|
||||
ShapeBorder lerpFrom(ShapeBorder a, double t) {
|
||||
ShapeBorder? lerpFrom(ShapeBorder? a, double t) {
|
||||
if (a is BorderDirectional)
|
||||
return BorderDirectional.lerp(a, this, t);
|
||||
return super.lerpFrom(a, t);
|
||||
}
|
||||
|
||||
@override
|
||||
ShapeBorder lerpTo(ShapeBorder b, double t) {
|
||||
ShapeBorder? lerpTo(ShapeBorder? b, double t) {
|
||||
if (b is BorderDirectional)
|
||||
return BorderDirectional.lerp(this, b, t);
|
||||
return super.lerpTo(b, t);
|
||||
@ -766,12 +765,12 @@ class BorderDirectional extends BoxBorder {
|
||||
/// borders.
|
||||
///
|
||||
/// {@macro dart.ui.shadow.lerp}
|
||||
static BorderDirectional lerp(BorderDirectional a, BorderDirectional b, double t) {
|
||||
static BorderDirectional? lerp(BorderDirectional? a, BorderDirectional? b, double t) {
|
||||
assert(t != null);
|
||||
if (a == null && b == null)
|
||||
return null;
|
||||
if (a == null)
|
||||
return b.scale(t);
|
||||
return b!.scale(t);
|
||||
if (b == null)
|
||||
return a.scale(1.0 - t);
|
||||
return BorderDirectional(
|
||||
@ -808,9 +807,9 @@ class BorderDirectional extends BoxBorder {
|
||||
void paint(
|
||||
Canvas canvas,
|
||||
Rect rect, {
|
||||
TextDirection textDirection,
|
||||
TextDirection? textDirection,
|
||||
BoxShape shape = BoxShape.rectangle,
|
||||
BorderRadius borderRadius,
|
||||
BorderRadius? borderRadius,
|
||||
}) {
|
||||
if (isUniform) {
|
||||
switch (top.style) {
|
||||
@ -839,7 +838,7 @@ class BorderDirectional extends BoxBorder {
|
||||
|
||||
BorderSide left, right;
|
||||
assert(textDirection != null, 'Non-uniform BorderDirectional objects require a TextDirection when painting.');
|
||||
switch (textDirection) {
|
||||
switch (textDirection!) {
|
||||
case TextDirection.rtl:
|
||||
left = end;
|
||||
right = start;
|
||||
|
@ -2,7 +2,6 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// @dart = 2.8
|
||||
|
||||
import 'dart:math' as math;
|
||||
|
||||
|
@ -2,7 +2,6 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// @dart = 2.8
|
||||
|
||||
import 'dart:math' as math;
|
||||
import 'dart:ui' as ui show Shadow, lerpDouble;
|
||||
@ -79,19 +78,19 @@ class BoxShadow extends ui.Shadow {
|
||||
/// offset and a zero blurRadius.
|
||||
///
|
||||
/// {@macro dart.ui.shadow.lerp}
|
||||
static BoxShadow lerp(BoxShadow a, BoxShadow b, double t) {
|
||||
static BoxShadow? lerp(BoxShadow? a, BoxShadow? b, double t) {
|
||||
assert(t != null);
|
||||
if (a == null && b == null)
|
||||
return null;
|
||||
if (a == null)
|
||||
return b.scale(t);
|
||||
return b!.scale(t);
|
||||
if (b == null)
|
||||
return a.scale(1.0 - t);
|
||||
return BoxShadow(
|
||||
color: Color.lerp(a.color, b.color, t),
|
||||
offset: Offset.lerp(a.offset, b.offset, t),
|
||||
blurRadius: ui.lerpDouble(a.blurRadius, b.blurRadius, t),
|
||||
spreadRadius: ui.lerpDouble(a.spreadRadius, b.spreadRadius, t),
|
||||
color: Color.lerp(a.color, b.color, t)!,
|
||||
offset: Offset.lerp(a.offset, b.offset, t)!,
|
||||
blurRadius: ui.lerpDouble(a.blurRadius, b.blurRadius, t)!,
|
||||
spreadRadius: ui.lerpDouble(a.spreadRadius, b.spreadRadius, t)!,
|
||||
);
|
||||
}
|
||||
|
||||
@ -100,7 +99,7 @@ class BoxShadow extends ui.Shadow {
|
||||
/// If the lists differ in length, excess items are lerped with null.
|
||||
///
|
||||
/// {@macro dart.ui.shadow.lerp}
|
||||
static List<BoxShadow> lerpList(List<BoxShadow> a, List<BoxShadow> b, double t) {
|
||||
static List<BoxShadow>? lerpList(List<BoxShadow>? a, List<BoxShadow>? b, double t) {
|
||||
assert(t != null);
|
||||
if (a == null && b == null)
|
||||
return null;
|
||||
@ -108,7 +107,7 @@ class BoxShadow extends ui.Shadow {
|
||||
b ??= <BoxShadow>[];
|
||||
final int commonLength = math.min(a.length, b.length);
|
||||
return <BoxShadow>[
|
||||
for (int i = 0; i < commonLength; i += 1) BoxShadow.lerp(a[i], b[i], t),
|
||||
for (int i = 0; i < commonLength; i += 1) BoxShadow.lerp(a[i], b[i], t)!,
|
||||
for (int i = commonLength; i < a.length; i += 1) a[i].scale(1.0 - t),
|
||||
for (int i = commonLength; i < b.length; i += 1) b[i].scale(t),
|
||||
];
|
||||
|
@ -2,7 +2,6 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// @dart = 2.8
|
||||
|
||||
import 'dart:ui' as ui show lerpDouble, WindowPadding;
|
||||
|
||||
@ -73,7 +72,6 @@ abstract class EdgeInsetsGeometry {
|
||||
case Axis.vertical:
|
||||
return vertical;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// The size that this [EdgeInsets] would occupy with an empty interior.
|
||||
@ -218,12 +216,12 @@ abstract class EdgeInsetsGeometry {
|
||||
/// into a concrete [EdgeInsets] using [resolve].
|
||||
///
|
||||
/// {@macro dart.ui.shadow.lerp}
|
||||
static EdgeInsetsGeometry lerp(EdgeInsetsGeometry a, EdgeInsetsGeometry b, double t) {
|
||||
static EdgeInsetsGeometry? lerp(EdgeInsetsGeometry? a, EdgeInsetsGeometry? b, double t) {
|
||||
assert(t != null);
|
||||
if (a == null && b == null)
|
||||
return null;
|
||||
if (a == null)
|
||||
return b * t;
|
||||
return b! * t;
|
||||
if (b == null)
|
||||
return a * (1.0 - t);
|
||||
if (a is EdgeInsets && b is EdgeInsets)
|
||||
@ -231,12 +229,12 @@ abstract class EdgeInsetsGeometry {
|
||||
if (a is EdgeInsetsDirectional && b is EdgeInsetsDirectional)
|
||||
return EdgeInsetsDirectional.lerp(a, b, t);
|
||||
return _MixedEdgeInsets.fromLRSETB(
|
||||
ui.lerpDouble(a._left, b._left, t),
|
||||
ui.lerpDouble(a._right, b._right, t),
|
||||
ui.lerpDouble(a._start, b._start, t),
|
||||
ui.lerpDouble(a._end, b._end, t),
|
||||
ui.lerpDouble(a._top, b._top, t),
|
||||
ui.lerpDouble(a._bottom, b._bottom, t),
|
||||
ui.lerpDouble(a._left, b._left, t)!,
|
||||
ui.lerpDouble(a._right, b._right, t)!,
|
||||
ui.lerpDouble(a._start, b._start, t)!,
|
||||
ui.lerpDouble(a._end, b._end, t)!,
|
||||
ui.lerpDouble(a._top, b._top, t)!,
|
||||
ui.lerpDouble(a._bottom, b._bottom, t)!,
|
||||
);
|
||||
}
|
||||
|
||||
@ -249,7 +247,7 @@ abstract class EdgeInsetsGeometry {
|
||||
/// * [EdgeInsets], for which this is a no-op (returns itself).
|
||||
/// * [EdgeInsetsDirectional], which flips the horizontal direction
|
||||
/// based on the `direction` argument.
|
||||
EdgeInsets resolve(TextDirection direction);
|
||||
EdgeInsets resolve(TextDirection? direction);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
@ -597,32 +595,32 @@ class EdgeInsets extends EdgeInsetsGeometry {
|
||||
/// If either is null, this function interpolates from [EdgeInsets.zero].
|
||||
///
|
||||
/// {@macro dart.ui.shadow.lerp}
|
||||
static EdgeInsets lerp(EdgeInsets a, EdgeInsets b, double t) {
|
||||
static EdgeInsets? lerp(EdgeInsets? a, EdgeInsets? b, double t) {
|
||||
assert(t != null);
|
||||
if (a == null && b == null)
|
||||
return null;
|
||||
if (a == null)
|
||||
return b * t;
|
||||
return b! * t;
|
||||
if (b == null)
|
||||
return a * (1.0 - t);
|
||||
return EdgeInsets.fromLTRB(
|
||||
ui.lerpDouble(a.left, b.left, t),
|
||||
ui.lerpDouble(a.top, b.top, t),
|
||||
ui.lerpDouble(a.right, b.right, t),
|
||||
ui.lerpDouble(a.bottom, b.bottom, t),
|
||||
ui.lerpDouble(a.left, b.left, t)!,
|
||||
ui.lerpDouble(a.top, b.top, t)!,
|
||||
ui.lerpDouble(a.right, b.right, t)!,
|
||||
ui.lerpDouble(a.bottom, b.bottom, t)!,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
EdgeInsets resolve(TextDirection direction) => this;
|
||||
EdgeInsets resolve(TextDirection? direction) => this;
|
||||
|
||||
/// Creates a copy of this EdgeInsets but with the given fields replaced
|
||||
/// with the new values.
|
||||
EdgeInsets copyWith({
|
||||
double left,
|
||||
double top,
|
||||
double right,
|
||||
double bottom,
|
||||
double? left,
|
||||
double? top,
|
||||
double? right,
|
||||
double? bottom,
|
||||
}) {
|
||||
return EdgeInsets.only(
|
||||
left: left ?? this.left,
|
||||
@ -822,32 +820,31 @@ class EdgeInsetsDirectional extends EdgeInsetsGeometry {
|
||||
/// [EdgeInsetsGeometry.lerp] static method.
|
||||
///
|
||||
/// {@macro dart.ui.shadow.lerp}
|
||||
static EdgeInsetsDirectional lerp(EdgeInsetsDirectional a, EdgeInsetsDirectional b, double t) {
|
||||
static EdgeInsetsDirectional? lerp(EdgeInsetsDirectional? a, EdgeInsetsDirectional? b, double t) {
|
||||
assert(t != null);
|
||||
if (a == null && b == null)
|
||||
return null;
|
||||
if (a == null)
|
||||
return b * t;
|
||||
return b! * t;
|
||||
if (b == null)
|
||||
return a * (1.0 - t);
|
||||
return EdgeInsetsDirectional.fromSTEB(
|
||||
ui.lerpDouble(a.start, b.start, t),
|
||||
ui.lerpDouble(a.top, b.top, t),
|
||||
ui.lerpDouble(a.end, b.end, t),
|
||||
ui.lerpDouble(a.bottom, b.bottom, t),
|
||||
ui.lerpDouble(a.start, b.start, t)!,
|
||||
ui.lerpDouble(a.top, b.top, t)!,
|
||||
ui.lerpDouble(a.end, b.end, t)!,
|
||||
ui.lerpDouble(a.bottom, b.bottom, t)!,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
EdgeInsets resolve(TextDirection direction) {
|
||||
EdgeInsets resolve(TextDirection? direction) {
|
||||
assert(direction != null);
|
||||
switch (direction) {
|
||||
switch (direction!) {
|
||||
case TextDirection.rtl:
|
||||
return EdgeInsets.fromLTRB(end, top, start, bottom);
|
||||
case TextDirection.ltr:
|
||||
return EdgeInsets.fromLTRB(start, top, end, bottom);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -943,14 +940,13 @@ class _MixedEdgeInsets extends EdgeInsetsGeometry {
|
||||
}
|
||||
|
||||
@override
|
||||
EdgeInsets resolve(TextDirection direction) {
|
||||
EdgeInsets resolve(TextDirection? direction) {
|
||||
assert(direction != null);
|
||||
switch (direction) {
|
||||
switch (direction!) {
|
||||
case TextDirection.rtl:
|
||||
return EdgeInsets.fromLTRB(_end + _left, _top, _start + _right, _bottom);
|
||||
case TextDirection.ltr:
|
||||
return EdgeInsets.fromLTRB(_start + _left, _top, _end + _right, _bottom);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,6 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// @dart = 2.8
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
@ -23,7 +22,7 @@ import 'image_stream.dart';
|
||||
typedef _KeyAndErrorHandlerCallback<T> = void Function(T key, ImageErrorListener handleError);
|
||||
|
||||
/// Signature used for error handling by [_createErrorHandlerAndKey].
|
||||
typedef _AsyncKeyErrorHandler<T> = Future<void> Function(T key, dynamic exception, StackTrace stack);
|
||||
typedef _AsyncKeyErrorHandler<T> = Future<void> Function(T key, dynamic exception, StackTrace? stack);
|
||||
|
||||
/// Configuration information passed to the [ImageProvider.resolve] method to
|
||||
/// select a specific image.
|
||||
@ -54,12 +53,12 @@ class ImageConfiguration {
|
||||
/// All the arguments are optional. Configuration information is merely
|
||||
/// advisory and best-effort.
|
||||
ImageConfiguration copyWith({
|
||||
AssetBundle bundle,
|
||||
double devicePixelRatio,
|
||||
Locale locale,
|
||||
TextDirection textDirection,
|
||||
Size size,
|
||||
TargetPlatform platform,
|
||||
AssetBundle? bundle,
|
||||
double? devicePixelRatio,
|
||||
Locale? locale,
|
||||
TextDirection? textDirection,
|
||||
Size? size,
|
||||
TargetPlatform? platform,
|
||||
}) {
|
||||
return ImageConfiguration(
|
||||
bundle: bundle ?? this.bundle,
|
||||
@ -73,25 +72,25 @@ class ImageConfiguration {
|
||||
|
||||
/// The preferred [AssetBundle] to use if the [ImageProvider] needs one and
|
||||
/// does not have one already selected.
|
||||
final AssetBundle bundle;
|
||||
final AssetBundle? bundle;
|
||||
|
||||
/// The device pixel ratio where the image will be shown.
|
||||
final double devicePixelRatio;
|
||||
final double? devicePixelRatio;
|
||||
|
||||
/// The language and region for which to select the image.
|
||||
final Locale locale;
|
||||
final Locale? locale;
|
||||
|
||||
/// The reading direction of the language for which to select the image.
|
||||
final TextDirection textDirection;
|
||||
final TextDirection? textDirection;
|
||||
|
||||
/// The size at which the image will be rendered.
|
||||
final Size size;
|
||||
final Size? size;
|
||||
|
||||
/// The [TargetPlatform] for which assets should be used. This allows images
|
||||
/// to be specified in a platform-neutral fashion yet use different assets on
|
||||
/// different platforms, to match local conventions e.g. for color matching or
|
||||
/// shadows.
|
||||
final TargetPlatform platform;
|
||||
final TargetPlatform? platform;
|
||||
|
||||
/// An image configuration that provides no additional information.
|
||||
///
|
||||
@ -128,7 +127,7 @@ class ImageConfiguration {
|
||||
if (devicePixelRatio != null) {
|
||||
if (hasArguments)
|
||||
result.write(', ');
|
||||
result.write('devicePixelRatio: ${devicePixelRatio.toStringAsFixed(1)}');
|
||||
result.write('devicePixelRatio: ${devicePixelRatio!.toStringAsFixed(1)}');
|
||||
hasArguments = true;
|
||||
}
|
||||
if (locale != null) {
|
||||
@ -152,7 +151,7 @@ class ImageConfiguration {
|
||||
if (platform != null) {
|
||||
if (hasArguments)
|
||||
result.write(', ');
|
||||
result.write('platform: ${describeEnum(platform)}');
|
||||
result.write('platform: ${describeEnum(platform!)}');
|
||||
hasArguments = true;
|
||||
}
|
||||
result.write(')');
|
||||
@ -170,7 +169,7 @@ class ImageConfiguration {
|
||||
///
|
||||
/// * [ResizeImage], which uses this to override the `cacheWidth`,
|
||||
/// `cacheHeight`, and `allowUpscaling` parameters.
|
||||
typedef DecoderCallback = Future<ui.Codec> Function(Uint8List bytes, {int cacheWidth, int cacheHeight, bool allowUpscaling});
|
||||
typedef DecoderCallback = Future<ui.Codec> Function(Uint8List bytes, {int? cacheWidth, int? cacheHeight, bool allowUpscaling});
|
||||
|
||||
/// Identifies an image without committing to the precise final asset. This
|
||||
/// allows a set of images to be identified and for the precise image to later
|
||||
@ -306,7 +305,7 @@ typedef DecoderCallback = Future<ui.Codec> Function(Uint8List bytes, {int cacheW
|
||||
/// ```
|
||||
/// {@end-tool}
|
||||
@optionalTypeArgs
|
||||
abstract class ImageProvider<T> {
|
||||
abstract class ImageProvider<T extends Object> {
|
||||
/// Abstract const constructor. This constructor enables subclasses to provide
|
||||
/// const constructors so that they can be used in const expressions.
|
||||
const ImageProvider();
|
||||
@ -333,11 +332,11 @@ abstract class ImageProvider<T> {
|
||||
(T key, ImageErrorListener errorHandler) {
|
||||
resolveStreamForKey(configuration, stream, key, errorHandler);
|
||||
},
|
||||
(T key, dynamic exception, StackTrace stack) async {
|
||||
(T? key, dynamic exception, StackTrace? stack) async {
|
||||
await null; // wait an event turn in case a listener has been added to the image stream.
|
||||
final _ErrorImageCompleter imageCompleter = _ErrorImageCompleter();
|
||||
stream.setCompleter(imageCompleter);
|
||||
InformationCollector collector;
|
||||
InformationCollector? collector;
|
||||
assert(() {
|
||||
collector = () sync* {
|
||||
yield DiagnosticsProperty<ImageProvider>('Image provider', this);
|
||||
@ -379,21 +378,21 @@ abstract class ImageProvider<T> {
|
||||
///
|
||||
/// A completed return value of null indicates that an error has occurred.
|
||||
Future<ImageCacheStatus> obtainCacheStatus({
|
||||
@required ImageConfiguration configuration,
|
||||
ImageErrorListener handleError,
|
||||
required ImageConfiguration configuration,
|
||||
ImageErrorListener? handleError,
|
||||
}) {
|
||||
assert(configuration != null);
|
||||
final Completer<ImageCacheStatus> completer = Completer<ImageCacheStatus>();
|
||||
_createErrorHandlerAndKey(
|
||||
configuration,
|
||||
(T key, ImageErrorListener innerHandleError) {
|
||||
completer.complete(PaintingBinding.instance.imageCache.statusForKey(key));
|
||||
completer.complete(PaintingBinding.instance!.imageCache!.statusForKey(key));
|
||||
},
|
||||
(T key, dynamic exception, StackTrace stack) async {
|
||||
(T? key, dynamic exception, StackTrace? stack) async {
|
||||
if (handleError != null) {
|
||||
handleError(exception, stack);
|
||||
} else {
|
||||
InformationCollector collector;
|
||||
InformationCollector? collector;
|
||||
assert(() {
|
||||
collector = () sync* {
|
||||
yield DiagnosticsProperty<ImageProvider>('Image provider', this);
|
||||
@ -402,12 +401,14 @@ abstract class ImageProvider<T> {
|
||||
};
|
||||
return true;
|
||||
}());
|
||||
FlutterError.onError(FlutterErrorDetails(
|
||||
context: ErrorDescription('while checking the cache location of an image'),
|
||||
informationCollector: collector,
|
||||
exception: exception,
|
||||
stack: stack,
|
||||
));
|
||||
if (FlutterError.onError != null) {
|
||||
FlutterError.onError!(FlutterErrorDetails(
|
||||
context: ErrorDescription('while checking the cache location of an image'),
|
||||
informationCollector: collector,
|
||||
exception: exception,
|
||||
stack: stack,
|
||||
));
|
||||
}
|
||||
completer.complete(null);
|
||||
}
|
||||
},
|
||||
@ -421,11 +422,11 @@ abstract class ImageProvider<T> {
|
||||
void _createErrorHandlerAndKey(
|
||||
ImageConfiguration configuration,
|
||||
_KeyAndErrorHandlerCallback<T> successCallback,
|
||||
_AsyncKeyErrorHandler<T> errorCallback,
|
||||
_AsyncKeyErrorHandler<T?> errorCallback,
|
||||
) {
|
||||
T obtainedKey;
|
||||
T? obtainedKey;
|
||||
bool didError = false;
|
||||
Future<void> handleError(dynamic exception, StackTrace stack) async {
|
||||
Future<void> handleError(dynamic exception, StackTrace? stack) async {
|
||||
if (didError) {
|
||||
return;
|
||||
}
|
||||
@ -492,17 +493,17 @@ abstract class ImageProvider<T> {
|
||||
// the image we want before getting to this method. We should avoid calling
|
||||
// load again, but still update the image cache with LRU information.
|
||||
if (stream.completer != null) {
|
||||
final ImageStreamCompleter completer = PaintingBinding.instance.imageCache.putIfAbsent(
|
||||
final ImageStreamCompleter? completer = PaintingBinding.instance!.imageCache!.putIfAbsent(
|
||||
key,
|
||||
() => stream.completer,
|
||||
() => stream.completer!,
|
||||
onError: handleError,
|
||||
);
|
||||
assert(identical(completer, stream.completer));
|
||||
return;
|
||||
}
|
||||
final ImageStreamCompleter completer = PaintingBinding.instance.imageCache.putIfAbsent(
|
||||
final ImageStreamCompleter? completer = PaintingBinding.instance!.imageCache!.putIfAbsent(
|
||||
key,
|
||||
() => load(key, PaintingBinding.instance.instantiateImageCodec),
|
||||
() => load(key, PaintingBinding.instance!.instantiateImageCodec),
|
||||
onError: handleError,
|
||||
);
|
||||
if (completer != null) {
|
||||
@ -548,10 +549,10 @@ abstract class ImageProvider<T> {
|
||||
/// }
|
||||
/// ```
|
||||
/// {@end-tool}
|
||||
Future<bool> evict({ ImageCache cache, ImageConfiguration configuration = ImageConfiguration.empty }) async {
|
||||
Future<bool> evict({ ImageCache? cache, ImageConfiguration configuration = ImageConfiguration.empty }) async {
|
||||
cache ??= imageCache;
|
||||
final T key = await obtainKey(configuration);
|
||||
return cache.evict(key);
|
||||
return cache!.evict(key);
|
||||
}
|
||||
|
||||
/// Converts an ImageProvider's settings plus an ImageConfiguration to a key
|
||||
@ -590,9 +591,9 @@ class AssetBundleImageKey {
|
||||
///
|
||||
/// The arguments must not be null.
|
||||
const AssetBundleImageKey({
|
||||
@required this.bundle,
|
||||
@required this.name,
|
||||
@required this.scale,
|
||||
required this.bundle,
|
||||
required this.name,
|
||||
required this.scale,
|
||||
}) : assert(bundle != null),
|
||||
assert(name != null),
|
||||
assert(scale != null);
|
||||
@ -640,7 +641,7 @@ abstract class AssetBundleImageProvider extends ImageProvider<AssetBundleImageKe
|
||||
/// image.
|
||||
@override
|
||||
ImageStreamCompleter load(AssetBundleImageKey key, DecoderCallback decode) {
|
||||
InformationCollector collector;
|
||||
InformationCollector? collector;
|
||||
assert(() {
|
||||
collector = () sync* {
|
||||
yield DiagnosticsProperty<ImageProvider>('Image provider', this);
|
||||
@ -662,17 +663,17 @@ abstract class AssetBundleImageProvider extends ImageProvider<AssetBundleImageKe
|
||||
/// This function is used by [load].
|
||||
@protected
|
||||
Future<ui.Codec> _loadAsync(AssetBundleImageKey key, DecoderCallback decode) async {
|
||||
ByteData data;
|
||||
ByteData? data;
|
||||
// Hot reload/restart could change whether an asset bundle or key in a
|
||||
// bundle are available, or if it is a network backed bundle.
|
||||
try {
|
||||
data = await key.bundle.load(key.name);
|
||||
} on FlutterError {
|
||||
PaintingBinding.instance.imageCache.evict(key);
|
||||
PaintingBinding.instance!.imageCache!.evict(key);
|
||||
rethrow;
|
||||
}
|
||||
if (data == null) {
|
||||
PaintingBinding.instance.imageCache.evict(key);
|
||||
PaintingBinding.instance!.imageCache!.evict(key);
|
||||
throw StateError('Unable to read data');
|
||||
}
|
||||
return await decode(data.buffer.asUint8List());
|
||||
@ -685,9 +686,9 @@ class _SizeAwareCacheKey {
|
||||
|
||||
final Object providerCacheKey;
|
||||
|
||||
final int width;
|
||||
final int? width;
|
||||
|
||||
final int height;
|
||||
final int? height;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
@ -729,10 +730,10 @@ class ResizeImage extends ImageProvider<_SizeAwareCacheKey> {
|
||||
final ImageProvider imageProvider;
|
||||
|
||||
/// The width the image should decode to and cache.
|
||||
final int width;
|
||||
final int? width;
|
||||
|
||||
/// The height the image should decode to and cache.
|
||||
final int height;
|
||||
final int? height;
|
||||
|
||||
/// Whether the [width] and [height] parameters should be clamped to the
|
||||
/// intrinsic width and height of the image.
|
||||
@ -748,7 +749,7 @@ class ResizeImage extends ImageProvider<_SizeAwareCacheKey> {
|
||||
///
|
||||
/// When `cacheWidth` and `cacheHeight` are both null, this will return the
|
||||
/// `provider` directly.
|
||||
static ImageProvider<dynamic> resizeIfNeeded(int cacheWidth, int cacheHeight, ImageProvider<dynamic> provider) {
|
||||
static ImageProvider<Object> resizeIfNeeded(int? cacheWidth, int? cacheHeight, ImageProvider<Object> provider) {
|
||||
if (cacheWidth != null || cacheHeight != null) {
|
||||
return ResizeImage(provider, width: cacheWidth, height: cacheHeight);
|
||||
}
|
||||
@ -757,7 +758,7 @@ class ResizeImage extends ImageProvider<_SizeAwareCacheKey> {
|
||||
|
||||
@override
|
||||
ImageStreamCompleter load(_SizeAwareCacheKey key, DecoderCallback decode) {
|
||||
final DecoderCallback decodeResize = (Uint8List bytes, {int cacheWidth, int cacheHeight, bool allowUpscaling}) {
|
||||
final DecoderCallback decodeResize = (Uint8List bytes, {int? cacheWidth, int? cacheHeight, bool? allowUpscaling}) {
|
||||
assert(
|
||||
cacheWidth == null && cacheHeight == null && allowUpscaling == null,
|
||||
'ResizeImage cannot be composed with another ImageProvider that applies '
|
||||
@ -774,10 +775,10 @@ class ResizeImage extends ImageProvider<_SizeAwareCacheKey> {
|
||||
|
||||
@override
|
||||
Future<_SizeAwareCacheKey> obtainKey(ImageConfiguration configuration) {
|
||||
Completer<_SizeAwareCacheKey> completer;
|
||||
Completer<_SizeAwareCacheKey>? completer;
|
||||
// If the imageProvider.obtainKey future is synchronous, then we will be able to fill in result with
|
||||
// a value before completer is initialized below.
|
||||
SynchronousFuture<_SizeAwareCacheKey> result;
|
||||
SynchronousFuture<_SizeAwareCacheKey>? result;
|
||||
imageProvider.obtainKey(configuration).then((Object key) {
|
||||
if (completer == null) {
|
||||
// This future has completed synchronously (completer was never assigned),
|
||||
@ -789,7 +790,7 @@ class ResizeImage extends ImageProvider<_SizeAwareCacheKey> {
|
||||
}
|
||||
});
|
||||
if (result != null) {
|
||||
return result;
|
||||
return result!;
|
||||
}
|
||||
// If the code reaches here, it means the imageProvider.obtainKey was not
|
||||
// completed sync, so we initialize the completer for completion later.
|
||||
@ -817,7 +818,7 @@ abstract class NetworkImage extends ImageProvider<NetworkImage> {
|
||||
/// Creates an object that fetches the image at the given URL.
|
||||
///
|
||||
/// The arguments [url] and [scale] must not be null.
|
||||
const factory NetworkImage(String url, { double scale, Map<String, String> headers }) = network_image.NetworkImage;
|
||||
const factory NetworkImage(String url, { double scale, Map<String, String>? headers }) = network_image.NetworkImage;
|
||||
|
||||
/// The URL from which the image will be fetched.
|
||||
String get url;
|
||||
@ -828,7 +829,7 @@ abstract class NetworkImage extends ImageProvider<NetworkImage> {
|
||||
/// The HTTP headers that will be used with [HttpClient.get] to fetch image from network.
|
||||
///
|
||||
/// When running flutter on the web, headers are not used.
|
||||
Map<String, String> get headers;
|
||||
Map<String, String>? get headers;
|
||||
|
||||
@override
|
||||
ImageStreamCompleter load(NetworkImage key, DecoderCallback decode);
|
||||
@ -870,7 +871,7 @@ class FileImage extends ImageProvider<FileImage> {
|
||||
scale: key.scale,
|
||||
debugLabel: key.file.path,
|
||||
informationCollector: () sync* {
|
||||
yield ErrorDescription('Path: ${file?.path}');
|
||||
yield ErrorDescription('Path: ${file.path}');
|
||||
},
|
||||
);
|
||||
}
|
||||
@ -882,7 +883,7 @@ class FileImage extends ImageProvider<FileImage> {
|
||||
|
||||
if (bytes.lengthInBytes == 0) {
|
||||
// The file may become available later.
|
||||
PaintingBinding.instance.imageCache.evict(key);
|
||||
PaintingBinding.instance!.imageCache!.evict(key);
|
||||
throw StateError('$file is empty and cannot be loaded as an image.');
|
||||
}
|
||||
|
||||
@ -894,15 +895,15 @@ class FileImage extends ImageProvider<FileImage> {
|
||||
if (other.runtimeType != runtimeType)
|
||||
return false;
|
||||
return other is FileImage
|
||||
&& other.file?.path == file?.path
|
||||
&& other.file.path == file.path
|
||||
&& other.scale == scale;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => hashValues(file?.path, scale);
|
||||
int get hashCode => hashValues(file.path, scale);
|
||||
|
||||
@override
|
||||
String toString() => '${objectRuntimeType(this, 'FileImage')}("${file?.path}", scale: $scale)';
|
||||
String toString() => '${objectRuntimeType(this, 'FileImage')}("${file.path}", scale: $scale)';
|
||||
}
|
||||
|
||||
/// Decodes the given [Uint8List] buffer as an image, associating it with the
|
||||
@ -1075,11 +1076,11 @@ class ExactAssetImage extends AssetBundleImageProvider {
|
||||
///
|
||||
/// The image is obtained by calling [AssetBundle.load] on the given [bundle]
|
||||
/// using the key given by [keyName].
|
||||
final AssetBundle bundle;
|
||||
final AssetBundle? bundle;
|
||||
|
||||
/// The name of the package from which the image is included. See the
|
||||
/// documentation for the [ExactAssetImage] class itself for details.
|
||||
final String package;
|
||||
final String? package;
|
||||
|
||||
@override
|
||||
Future<AssetBundleImageKey> obtainKey(ImageConfiguration configuration) {
|
||||
@ -1112,10 +1113,10 @@ class _ErrorImageCompleter extends ImageStreamCompleter {
|
||||
_ErrorImageCompleter();
|
||||
|
||||
void setError({
|
||||
DiagnosticsNode context,
|
||||
DiagnosticsNode? context,
|
||||
dynamic exception,
|
||||
StackTrace stack,
|
||||
InformationCollector informationCollector,
|
||||
StackTrace? stack,
|
||||
InformationCollector? informationCollector,
|
||||
bool silent = false,
|
||||
}) {
|
||||
reportError(
|
||||
@ -1132,7 +1133,7 @@ class _ErrorImageCompleter extends ImageStreamCompleter {
|
||||
class NetworkImageLoadException implements Exception {
|
||||
/// Creates a [NetworkImageLoadException] with the specified http [statusCode]
|
||||
/// and [uri].
|
||||
NetworkImageLoadException({@required this.statusCode, @required this.uri})
|
||||
NetworkImageLoadException({required this.statusCode, required this.uri})
|
||||
: assert(uri != null),
|
||||
assert(statusCode != null),
|
||||
_message = 'HTTP request failed, statusCode: $statusCode, $uri';
|
||||
|
Loading…
Reference in New Issue
Block a user