buildFills function

List<Widget> buildFills(
  1. BaseNode node, {
  2. Map<int, TypedBytes> imageBytes = const {},
  3. double? imageOpacity,
  4. double? imageRotation,
  5. ImageFillBuilder? imageFillBuilder,
  6. bool useInk = true,
  7. bool obscureImages = false,
  8. required WidgetBuildSettings settings,
  9. 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();
      }
    }),
  ];
}