diff --git a/README.md b/README.md index 680ebbf..65e7b27 100644 --- a/README.md +++ b/README.md @@ -215,6 +215,25 @@ Create a callback function to dismiss } ``` +## MouseRegion on Desktop & Web +Based on issue [#80](https://github.com/bensonarafat/super_tooltip/issues/80) Supertooltip now support MouseEnter and Exit for Desktop for Web +### How to use +```dart +SuperTooltip( + // ... other parameters + showOnHover: true, // Tooltip appears on hover + hideOnHoverExit: true, // Tooltip disappears when mouse leaves + content: Text("Hello World"), + child: Icon(Icons.info), +); + +``` +Demo +

+ +

+Thanks [@akhil-ge0rge](https://github.com/akhil-ge0rge) + ## Example app Find the example app [here](https://github.com/bensonarafat/super_tooltip/tree/master/example). diff --git a/android/local.properties b/android/local.properties index 705b751..dbc8194 100644 --- a/android/local.properties +++ b/android/local.properties @@ -1,2 +1,2 @@ sdk.dir=/Users/bensonarafat/Library/Android/sdk -flutter.sdk=/Users/bensonarafat/development/flutter \ No newline at end of file +flutter.sdk=/Users/bensonarafat/development/flutter diff --git a/example/analysis_options.yaml b/example/analysis_options.yaml index 347d7f3..e69de29 100644 --- a/example/analysis_options.yaml +++ b/example/analysis_options.yaml @@ -1 +0,0 @@ -# No lint rules for example diff --git a/lib/src/tooltip_position_delegate.dart b/lib/src/tooltip_position_delegate.dart index 5987a69..2770d5c 100644 --- a/lib/src/tooltip_position_delegate.dart +++ b/lib/src/tooltip_position_delegate.dart @@ -34,15 +34,15 @@ class ToolTipPositionDelegate extends SingleChildLayoutDelegate { @override BoxConstraints getConstraintsForChild(BoxConstraints constraints) { - // TD: when margin is EdgeInsets, look into - // constraints.deflate(margin); - var newConstraints = this.constraints; + // We use the INCOMING constraints (screen size) to calculate available space. + // We do NOT start with this.constraints (user prefs) because that leads to negative math. + var availableConstraints = constraints; switch (preferredDirection) { case TooltipDirection.up: case TooltipDirection.down: - newConstraints = SuperUtils.verticalConstraints( - constraints: newConstraints, + availableConstraints = SuperUtils.verticalConstraints( + constraints: availableConstraints, margin: margin, bottom: bottom, isUp: preferredDirection == TooltipDirection.up, @@ -54,8 +54,8 @@ class ToolTipPositionDelegate extends SingleChildLayoutDelegate { break; case TooltipDirection.right: case TooltipDirection.left: - newConstraints = SuperUtils.horizontalConstraints( - constraints: newConstraints, + availableConstraints = SuperUtils.horizontalConstraints( + constraints: availableConstraints, margin: margin, bottom: bottom, isRight: preferredDirection == TooltipDirection.right, @@ -67,21 +67,24 @@ class ToolTipPositionDelegate extends SingleChildLayoutDelegate { break; } - // TD: This scenerio should likely be avoided in the initial functions - // Ensure constraints are valid - no negiative values - final validatedConstraints = newConstraints.copyWith( - minHeight: math.max( - 0, - newConstraints.minHeight > newConstraints.maxHeight - ? newConstraints.maxHeight - : newConstraints.minHeight), - minWidth: math.max( - 0, - newConstraints.minWidth > newConstraints.maxWidth - ? newConstraints.maxWidth - : newConstraints.minWidth), - maxHeight: math.max(0, newConstraints.maxHeight), - maxWidth: math.max(0, newConstraints.maxWidth), + // Now we merge the calculated "Available Space" with the User's "Desired Constraints". + // We take the smaller of the two max widths/heights to ensure we fit in both. + // We respect the user's min sizes unless they exceed available space. + + double finalMaxWidth = + math.min(availableConstraints.maxWidth, this.constraints.maxWidth); + double finalMaxHeight = + math.min(availableConstraints.maxHeight, this.constraints.maxHeight); + + // Ensure final max is not negative + finalMaxWidth = math.max(0.0, finalMaxWidth); + finalMaxHeight = math.max(0.0, finalMaxHeight); + + final validatedConstraints = BoxConstraints( + minWidth: math.min(this.constraints.minWidth, finalMaxWidth), + maxWidth: finalMaxWidth, + minHeight: math.min(this.constraints.minHeight, finalMaxHeight), + maxHeight: finalMaxHeight, ); return validatedConstraints; @@ -89,18 +92,6 @@ class ToolTipPositionDelegate extends SingleChildLayoutDelegate { @override Offset getPositionForChild(Size size, Size childSize) { - // TD: If there isn't enough space for the child on the preferredDirection - // use the opposite dirrection - // - // See: - // return positionDependentBox( - // size: size, - // childSize: childSize, - // target: target, - // verticalOffset: verticalOffset, - // preferBelow: preferBelow, - // ); - switch (preferredDirection) { case TooltipDirection.up: case TooltipDirection.down: diff --git a/lib/src/utils.dart b/lib/src/utils.dart index 5b43890..aae2dee 100644 --- a/lib/src/utils.dart +++ b/lib/src/utils.dart @@ -153,18 +153,25 @@ class SuperUtils { if (isRight) { if (right != null) { - minWidth = maxWidth = maxWidth - right - target.dx; + // Calculate available width based on margin + maxWidth = maxWidth - right - target.dx; + // Don't force minWidth to be equal to maxWidth (allows shrinking) } else { - maxWidth = min(maxWidth, maxWidth - target.dx) - margin; + maxWidth = (maxWidth - target.dx) - margin; } } else { if (left != null) { - minWidth = maxWidth = target.dx - left; + // Calculate available width based on margin + maxWidth = target.dx - left; } else { maxWidth = min(maxWidth, target.dx) - margin; } } + // Robustness check to prevent negative constraints + if (maxWidth < 0) maxWidth = 0; + if (minWidth > maxWidth) minWidth = maxWidth; + return constraints.copyWith( maxHeight: maxHeight, minWidth: minWidth, @@ -190,7 +197,6 @@ class SuperUtils { maxWidth = maxWidth - (left + right); } else if ((left != null && right == null) || (left == null && right != null)) { - // make sure that the sum of left, right + maxwidth isn't bigger than the screen width. final sideDelta = (left ?? 0.0) + (right ?? 0.0) + margin; if (maxWidth > maxWidth - sideDelta) { @@ -204,20 +210,22 @@ class SuperUtils { if (isUp) { if (top != null) { - minHeight = maxHeight = target.dy - top; + maxHeight = target.dy - top; } else { maxHeight = min(maxHeight, target.dy) - margin; - // TD: clamp minheight } } else { if (bottom != null) { - minHeight = maxHeight = maxHeight - bottom - target.dy; + maxHeight = maxHeight - bottom - target.dy; } else { maxHeight = min(maxHeight, maxHeight - target.dy) - margin; - // TD: clamp minheight } } + // Robustness check + if (maxHeight < 0) maxHeight = 0; + if (minHeight > maxHeight) minHeight = maxHeight; + return constraints.copyWith( minHeight: minHeight, maxHeight: maxHeight,