show method
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;
}