buildFills function
List<Widget>
buildFills(
- BaseNode node, {
- Map<
int, TypedBytes> imageBytes = const {}, - double? imageOpacity,
- double? imageRotation,
- ImageFillBuilder? imageFillBuilder,
- bool useInk = true,
- bool obscureImages = false,
- required WidgetBuildSettings settings,
- required ScopedValues scopedValues,
Implementation
List<Widget> buildFills(
BaseNode node, {
Map<int, TypedBytes> imageBytes = const {},
double? imageOpacity,
double? imageRotation,
ImageFillBuilder? imageFillBuilder,
bool useInk = true,
bool obscureImages = false,
required WidgetBuildSettings settings,
required ScopedValues scopedValues,
}) {
if (node is! GeometryMixin) return [];
final BorderRadius? borderRadius = getBorderRadius(node);
return [
...node.fills.where((paint) => paint.visible).mapIndexed((index, paint) {
switch (paint.type) {
case PaintType.solid:
final propertyValue =
PropertyValueDelegate.getPropertyValue<PaintModel>(
node,
'fill-${paint.id}',
scopedValues: scopedValues,
);
final decoration = BoxDecoration(
borderRadius: borderRadius,
color: (propertyValue ?? paint).toFlutterColor()!,
);
return Positioned.fill(
child: useInk
? Ink(decoration: decoration)
: DecoratedBox(decoration: decoration),
);
case PaintType.gradientLinear:
case PaintType.gradientRadial:
case PaintType.gradientAngular:
case PaintType.gradientDiamond:
final decoration = BoxDecoration(
borderRadius: borderRadius,
gradient: retrieveGradient(paint),
);
return Positioned.fill(
child: useInk
? Ink(decoration: decoration)
: DecoratedBox(decoration: decoration),
);
case PaintType.image:
final TypedBytes? bytes = imageBytes[index];
final double modifiedOpacity = (imageOpacity ?? 1) * paint.opacity;
// Substitute URL value from [CodelesslyContext]'s [data] map if
// [imageURL] represents a JSON path.
String? imageURL = paint.croppedImageURL ?? paint.downloadUrl!;
final imageURLValue = PropertyValueDelegate.getPropertyValue<String>(
node,
'fill-image-${paint.id}',
scopedValues: scopedValues,
) ??
imageURL;
imageURL = PropertyValueDelegate.substituteVariables(
imageURLValue,
nullSubstitutionMode: settings.nullSubstitutionMode,
scopedValues: scopedValues,
);
Widget child;
if (imageFillBuilder != null) {
child = imageFillBuilder(
imageURL,
node.basicBoxLocal.width,
node.basicBoxLocal.height,
paint,
bytes,
useInk,
obscureImages,
);
} else {
if (obscureImages) {
child = SizedBox(
width: node.basicBoxLocal.width,
height: node.basicBoxLocal.height,
child: const Placeholder(),
);
} else {
child = UltimateImageBuilder(
url: imageURL,
width: (node.horizontalFit == SizeFit.shrinkWrap)
? null
: (node.horizontalFit == SizeFit.expanded)
? double.infinity
: node.basicBoxLocal.width,
height: (node.verticalFit == SizeFit.shrinkWrap)
? null
: (node.verticalFit == SizeFit.expanded)
? double.infinity
: node.basicBoxLocal.height,
paint: paint,
node: node,
bytes: bytes,
useInk: useInk,
);
}
}
if (modifiedOpacity != 1) {
child = Opacity(
opacity: modifiedOpacity,
child: child,
);
}
if (imageRotation != null) {
child = Transform.rotate(
angle: imageRotation,
child: child,
);
}
if (node.isHorizontalWrap || node.isVerticalWrap) {
// if the node is shrink-wrapping on one or both axes, then we
// need to wrap the image in a Positioned widget so that it
// doesn't expand to the size of the parent.
return Positioned(child: child);
}
return Positioned.fill(child: child);
// if (node.childrenOrEmpty.isEmpty) {
// // If we don't do this then shrink-wrapping images will not work.
// // They will expand to the size of the parent.
// return child;
// } else {
// // This was Positioned.fill before. If this is breaking something,
// // then we need to figure out a way to make it work with
// // Positioned.fill and Positioned because Positioned.fill breaks
// // shrink-wrapping.
// return Positioned(child: child);
// }
case PaintType.emoji:
return const SizedBox.shrink();
}
}),
];
}