show method

void show(
  1. BuildContext targetContext, {
  2. OverlayState? overlay,
})

Displays the tooltip The center of targetContext is used as target of the arrow

Uses overlay to show tooltip or targetContext's overlay if overlay is null

Implementation

void show(BuildContext targetContext, {OverlayState? overlay}) {
  final renderBox = targetContext.findRenderObject() as RenderBox;
  overlay ??= Overlay.of(targetContext)!;
  final overlayRenderBox = overlay.context.findRenderObject() as RenderBox?;

  switch (targetMode) {
    case TargetMode.topLeft:
      _targetCenter = renderBox.localToGlobal(
          renderBox.size.topLeft(Offset.zero),
          ancestor: overlayRenderBox);
      break;
    case TargetMode.topCenter:
      _targetCenter = renderBox.localToGlobal(
          renderBox.size.topCenter(Offset.zero),
          ancestor: overlayRenderBox);
      break;
    case TargetMode.topRight:
      _targetCenter = renderBox.localToGlobal(
          renderBox.size.topRight(Offset.zero),
          ancestor: overlayRenderBox);
      break;
    case TargetMode.centerLeft:
      _targetCenter = renderBox.localToGlobal(
          renderBox.size.centerLeft(Offset.zero),
          ancestor: overlayRenderBox);
      break;
    case TargetMode.center:
      _targetCenter = renderBox.localToGlobal(
          renderBox.size.center(Offset.zero),
          ancestor: overlayRenderBox);
      break;
    case TargetMode.centerRight:
      _targetCenter = renderBox.localToGlobal(
          renderBox.size.centerRight(Offset.zero),
          ancestor: overlayRenderBox);
      break;
    case TargetMode.bottomLeft:
      _targetCenter = renderBox.localToGlobal(
          renderBox.size.bottomLeft(Offset.zero),
          ancestor: overlayRenderBox);
      break;
    case TargetMode.bottomCenter:
      _targetCenter = renderBox.localToGlobal(
          renderBox.size.bottomCenter(Offset.zero),
          ancestor: overlayRenderBox);
      break;
    case TargetMode.bottomRight:
      _targetCenter = renderBox.localToGlobal(
          renderBox.size.bottomRight(Offset.zero),
          ancestor: overlayRenderBox);
      break;
  }

  // Create the background below the popup including the clipArea.
  if (containsBackgroundOverlay) {
    late Widget background;

    var shapeOverlay = _ShapeOverlay(touchThrougArea, touchThroughAreaShape,
        touchThroughAreaCornerRadius, outsideBackgroundColor);
    final backgroundDecoration =
        DecoratedBox(decoration: ShapeDecoration(shape: shapeOverlay));

    if (dismissOnTapOutside && blockOutsidePointerEvents) {
      background = GestureDetector(
        onTap: () => close(),
        child: backgroundDecoration,
      );
    } else if (dismissOnTapOutside && !blockOutsidePointerEvents) {
      background = Listener(
        behavior: HitTestBehavior.translucent,
        onPointerDown: (event) {
          if (!(shapeOverlay._getExclusion()?.contains(event.localPosition) ??
              false)) {
            close();
          }
        },
        child: IgnorePointer(child: backgroundDecoration),
      );
    } else if (!dismissOnTapOutside && blockOutsidePointerEvents) {
      background = backgroundDecoration;
    } else if (!dismissOnTapOutside && !blockOutsidePointerEvents) {
      background = IgnorePointer(child: backgroundDecoration);
    } else {
      background = backgroundDecoration;
    }

    _backGroundOverlay = OverlayEntry(
        builder: (context) => _AnimationWrapper(
              builder: (context, opacity) => AnimatedOpacity(
                opacity: opacity,
                duration: const Duration(milliseconds: 600),
                child: background,
              ),
            ));
  }

  /// Handling snap far away feature.
  if (snapsFarAwayVertically) {
    maxHeight = null;
    left = 0.0;
    right = 0.0;
    if (_targetCenter!.dy > overlayRenderBox!.size.center(Offset.zero).dy) {
      popupDirection = TooltipDirection.up;
      top = 0.0;
    } else {
      popupDirection = TooltipDirection.down;
      bottom = 0.0;
    }
  } // Only one of of them is possible, and vertical has higher priority.
  else if (snapsFarAwayHorizontally) {
    maxWidth = null;
    top = 0.0;
    bottom = 0.0;
    if (_targetCenter!.dx < overlayRenderBox!.size.center(Offset.zero).dx) {
      popupDirection = TooltipDirection.right;
      right = 0.0;
    } else {
      popupDirection = TooltipDirection.left;
      left = 0.0;
    }
  }

  _ballonOverlay = OverlayEntry(
    builder: (context) {
      return targetLink != null
          ? CompositedTransformFollower(
              link: targetLink!,
              showWhenUnlinked: false,
              offset: tooltipOffset ?? Offset.zero,
              child: _AnimationWrapper(
                builder: (context, opacity) => AnimatedOpacity(
                  duration: Duration(
                    milliseconds: animationDuration,
                  ),
                  opacity: opacity,
                  child: Center(
                    child: CustomSingleChildLayout(
                      delegate: _PopupBallonLayoutDelegate(
                        popupDirection: popupDirection,
                        targetCenter: _targetCenter,
                        minWidth: minWidth,
                        maxWidth: maxWidth,
                        minHeight: minHeight,
                        maxHeight: maxHeight,
                        outSidePadding: minimumOutSidePadding,
                        top: top,
                        bottom: bottom,
                        left: left,
                        right: right,
                      ),
                      child: Stack(
                        fit: StackFit.passthrough,
                        children: [_buildPopUp(), _buildCloseButton()],
                      ),
                    ),
                  ),
                ),
              ),
            )
          : _AnimationWrapper(
              builder: (context, opacity) => AnimatedOpacity(
                duration: Duration(
                  milliseconds: animationDuration,
                ),
                opacity: opacity,
                child: Center(
                  child: CustomSingleChildLayout(
                    delegate: _PopupBallonLayoutDelegate(
                      popupDirection: popupDirection,
                      targetCenter: _targetCenter,
                      minWidth: minWidth,
                      maxWidth: maxWidth,
                      minHeight: minHeight,
                      maxHeight: maxHeight,
                      outSidePadding: minimumOutSidePadding,
                      top: top,
                      bottom: bottom,
                      left: left,
                      right: right,
                    ),
                    child: Stack(
                      fit: StackFit.passthrough,
                      children: [_buildPopUp(), _buildCloseButton()],
                    ),
                  ),
                ),
              ),
            );
    },
  );

  var overlays = <OverlayEntry>[];

  if (containsBackgroundOverlay) {
    overlays.add(_backGroundOverlay!);
  }
  overlays.add(_ballonOverlay!);

  overlay.insertAll(overlays);
  isOpen = true;
}