Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 1 addition & 29 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,6 @@ class _TargetWidgetState extends State<TargetWidget> {
return true;
}

TooltipDirection _tooltipDirection = TooltipDirection.left;

@override
Widget build(BuildContext context) {
return PopScope(
Expand All @@ -69,10 +67,7 @@ class _TargetWidgetState extends State<TargetWidget> {
children: [
SuperTooltip(
controller: _controller,
popupDirection: TooltipDirection.left,
popupDirectionBuilder: () {
return _tooltipDirection;
},
popupDirection: TooltipDirection.auto,
backgroundColor: Color(0xff2f2d2f),
showCloseButton: true,
left: 30,
Expand Down Expand Up @@ -113,29 +108,6 @@ class _TargetWidgetState extends State<TargetWidget> {
),
),
),
Center(
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
IconButton(
onPressed: () {
_tooltipDirection = TooltipDirection.left;
},
icon: Icon(
Icons.arrow_left,
),
),
IconButton(
onPressed: () {
_tooltipDirection = TooltipDirection.right;
},
icon: Icon(
Icons.arrow_right,
),
),
],
),
)
],
),
);
Expand Down
2 changes: 1 addition & 1 deletion lib/src/enums.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
enum TooltipDirection { up, down, left, right }
enum TooltipDirection { up, down, left, right, auto }

enum CloseButtonType { inside, outside }

Expand Down
52 changes: 50 additions & 2 deletions lib/src/super_tooltip.dart
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,10 @@ class SuperTooltip extends StatefulWidget {
this.mouseCursor,
}) : assert(showDropBoxFilter ? showBarrier ?? false : true,
'showDropBoxFilter or showBarrier can\'t be false | null'),
assert(
popupDirectionBuilder == null ||
popupDirection != TooltipDirection.auto,
'popupDirectionBuilder cannot be used with TooltipDirection.auto'),
super(key: key);

/// Key used to identify the inside close button.
Expand Down Expand Up @@ -480,6 +484,8 @@ class _SuperTooltipState extends State<SuperTooltip>
late Offset shadowOffset;
late bool showBlur;

late TooltipDirection _resolvedDirection;

Timer? _showTimer;
Timer? _hideTimer;
Timer? _showDurationTimer;
Expand Down Expand Up @@ -667,6 +673,47 @@ class _SuperTooltipState extends State<SuperTooltip>
var right = widget.right;
var top = widget.top;
var bottom = widget.bottom;
_resolvedDirection = preferredDirection;
// When [TooltipDirection.auto] is specified, the tooltip direction is
// dynamically resolved based on available space around the target widget.
if (preferredDirection == TooltipDirection.auto && overlay != null) {
final estimatedTooltipSize = Size(
constraints.maxWidth.isFinite
? constraints.maxWidth
: overlay.size.width * 0.8,
constraints.maxHeight.isFinite
? constraints.maxHeight
: overlay.size.height * 0.4,
);

final screen = overlay.size;

final spaceAbove = target.dy - widget.minimumOutsideMargin;
final spaceBelow =
screen.height - target.dy - widget.minimumOutsideMargin;
final spaceLeft = target.dx - widget.minimumOutsideMargin;
final spaceRight = screen.width - target.dx - widget.minimumOutsideMargin;

if (spaceBelow >= estimatedTooltipSize.height) {
preferredDirection = TooltipDirection.down;
} else if (spaceAbove >= estimatedTooltipSize.height) {
preferredDirection = TooltipDirection.up;
} else if (spaceRight >= estimatedTooltipSize.width) {
preferredDirection = TooltipDirection.right;
} else if (spaceLeft >= estimatedTooltipSize.width) {
preferredDirection = TooltipDirection.left;
} else {
final candidates = <TooltipDirection, double>{
TooltipDirection.down: spaceBelow,
TooltipDirection.up: spaceAbove,
TooltipDirection.right: spaceRight,
TooltipDirection.left: spaceLeft,
};

preferredDirection =
candidates.entries.reduce((a, b) => a.value > b.value ? a : b).key;
}
}

if (widget.snapsFarAwayVertically) {
constraints = constraints.copyWith(maxHeight: null);
Expand Down Expand Up @@ -704,6 +751,7 @@ class _SuperTooltipState extends State<SuperTooltip>
left = 0.0;
}
}
_resolvedDirection = preferredDirection;

_barrierEntry = showBarrier
? OverlayEntry(
Expand Down Expand Up @@ -793,7 +841,7 @@ class _SuperTooltipState extends State<SuperTooltip>
arrowLength: widget.arrowLength,
arrowTipDistance: widget.arrowTipDistance,
closeButtonSize: closeButtonSize,
preferredDirection: preferredDirection,
preferredDirection: _resolvedDirection,
closeButtonType: closeButtonType,
showCloseButton: showCloseButton,
),
Expand Down Expand Up @@ -959,7 +1007,7 @@ class _SuperTooltipState extends State<SuperTooltip>
double right;
double top;

switch (widget.popupDirectionBuilder?.call() ?? widget.popupDirection) {
switch (_resolvedDirection) {
//
// LEFT: -------------------------------------
case TooltipDirection.left:
Expand Down
12 changes: 12 additions & 0 deletions lib/src/super_tooltip_position_delegate.dart
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,18 @@ class SuperToolTipPositionDelegate extends SingleChildLayoutDelegate {
right: right,
);
break;
case TooltipDirection.auto:
availableConstraints = SuperUtils.verticalConstraints(
constraints: availableConstraints,
margin: margin,
bottom: bottom,
isUp: false,
target: target,
top: top,
left: left,
right: right,
);
break;
}

// Now we merge the calculated "Available Space" with the User's "Desired Constraints".
Expand Down
34 changes: 34 additions & 0 deletions lib/src/utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -232,4 +232,38 @@ class SuperUtils {
maxWidth: maxWidth,
);
}

/// This method determines the most suitable direction for displaying
/// the tooltip relative to the target widget.
static TooltipDirection resolve({
required RenderBox overlay,
required Offset target,
required Size estimatedTooltipSize,
required double margin,
}) {
final screen = overlay.size;

final spaceAbove = target.dy - margin;
final spaceBelow = screen.height - target.dy - margin;
final spaceLeft = target.dx - margin;
final spaceRight = screen.width - target.dx - margin;

final requiredHeight = estimatedTooltipSize.height;
final requiredWidth = estimatedTooltipSize.width;

if (spaceBelow >= requiredHeight) return TooltipDirection.down;
if (spaceAbove >= requiredHeight) return TooltipDirection.up;

if (spaceRight >= requiredWidth) return TooltipDirection.right;
if (spaceLeft >= requiredWidth) return TooltipDirection.left;

final candidates = <TooltipDirection, double>{
TooltipDirection.down: spaceBelow,
TooltipDirection.up: spaceAbove,
TooltipDirection.right: spaceRight,
TooltipDirection.left: spaceLeft,
};

return candidates.entries.reduce((a, b) => a.value > b.value ? a : b).key;
}
}
1 change: 0 additions & 1 deletion makedoc.bat

This file was deleted.