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
2 changes: 1 addition & 1 deletion android/local.properties
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
sdk.dir=/Users/bensonarafat/Library/Android/sdk
flutter.sdk=/Users/bensonarafat/fvm/versions/3.39.0-0.1.pre
flutter.sdk=/Users/bensonarafat/fvm/versions/3.39.0-0.1.pre
40 changes: 30 additions & 10 deletions example/.metadata
Original file line number Diff line number Diff line change
@@ -1,10 +1,30 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.

version:
revision: adc9dde3ba8563eebb824feb689f95eb947ab745
channel: master

project_type: app
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.

version:
revision: "adc901062556672b4138e18a4dc62a4be8f4b3c2"
channel: "stable"

project_type: app

# Tracks metadata for the flutter migrate command
migration:
platforms:
- platform: root
create_revision: adc901062556672b4138e18a4dc62a4be8f4b3c2
base_revision: adc901062556672b4138e18a4dc62a4be8f4b3c2
- platform: web
create_revision: adc901062556672b4138e18a4dc62a4be8f4b3c2
base_revision: adc901062556672b4138e18a4dc62a4be8f4b3c2

# User provided section

# List of Local paths (relative to this file) that should be
# ignored by the migrate tool.
#
# Files that are not part of the templates will be ignored by default.
unmanaged_files:
- 'lib/main.dart'
- 'ios/Runner.xcodeproj/project.pbxproj'
1 change: 1 addition & 0 deletions example/analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

26 changes: 15 additions & 11 deletions example/android/app/build.gradle
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
plugins {
id "com.android.application"
id "kotlin-android"
id "org.jetbrains.kotlin.android"
id "dev.flutter.flutter-gradle-plugin"
}

def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}

def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
Expand All @@ -20,12 +22,9 @@ if (flutterVersionName == null) {
flutterVersionName = '1.0'
}

// apply plugin: 'com.android.application'
// apply plugin: 'kotlin-android'
// apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"

android {
compileSdkVersion flutter.compileSdkVersion
compileSdkVersion 34
namespace "com.example.super_tooltip_example"

sourceSets {
main.java.srcDirs += 'src/main/kotlin'
Expand All @@ -39,7 +38,7 @@ android {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.example.super_tooltip_example"
minSdkVersion flutter.minSdkVersion
targetSdkVersion 28
targetSdkVersion 34
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
Expand All @@ -51,12 +50,17 @@ android {
signingConfig signingConfigs.debug
}
}

kotlinOptions {
jvmTarget = "1.8"
}

compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
}

flutter {
source '../..'
}

dependencies {
// implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}
4 changes: 3 additions & 1 deletion example/android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
android:exported="true"
android:windowSoftInputMode="adjustResize"
>
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
Expand Down
3 changes: 1 addition & 2 deletions example/android/build.gradle
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@

allprojects {
repositories {
google()
jcenter()
mavenCentral()
}
}

Expand Down
4 changes: 2 additions & 2 deletions example/android/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-all.zip
9 changes: 4 additions & 5 deletions example/android/settings.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@


pluginManagement {
def flutterSdkPath = {
def properties = new Properties()
Expand All @@ -20,7 +18,8 @@ pluginManagement {

plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version "7.3.0" apply false
id "org.jetbrains.kotlin.android" version "1.7.10" apply false
id "com.android.application" version "8.6.0" apply false
id "org.jetbrains.kotlin.android" version "2.1.0" apply false
}
include ':app'

include ":app"
2 changes: 2 additions & 0 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ class _TargetWidgetState extends State<TargetWidget> {
},
backgroundColor: Color(0xff2f2d2f),
showCloseButton: true,
showOnHover: true,
hideOnHoverExit: false,
left: 30,
right: 30,
bottom: 200,
Expand Down
Binary file added example/web/favicon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added example/web/icons/Icon-192.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added example/web/icons/Icon-512.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added example/web/icons/Icon-maskable-192.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added example/web/icons/Icon-maskable-512.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
38 changes: 38 additions & 0 deletions example/web/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<!DOCTYPE html>
<html>
<head>
<!--
If you are serving your web app in a path other than the root, change the
href value below to reflect the base path you are serving from.

The path provided below has to start and end with a slash "/" in order for
it to work correctly.

For more details:
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base

This is a placeholder for base href that will be replaced by the value of
the `--base-href` argument provided to `flutter build`.
-->
<base href="$FLUTTER_BASE_HREF">

<meta charset="UTF-8">
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
<meta name="description" content="A new Flutter project.">

<!-- iOS meta tags & icons -->
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-title" content="super_tooltip_example">
<link rel="apple-touch-icon" href="icons/Icon-192.png">

<!-- Favicon -->
<link rel="icon" type="image/png" href="favicon.png"/>

<title>super_tooltip_example</title>
<link rel="manifest" href="manifest.json">
</head>
<body>
<script src="flutter_bootstrap.js" async></script>
</body>
</html>
35 changes: 35 additions & 0 deletions example/web/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"name": "super_tooltip_example",
"short_name": "super_tooltip_example",
"start_url": ".",
"display": "standalone",
"background_color": "#0175C2",
"theme_color": "#0175C2",
"description": "A new Flutter project.",
"orientation": "portrait-primary",
"prefer_related_applications": false,
"icons": [
{
"src": "icons/Icon-192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "icons/Icon-512.png",
"sizes": "512x512",
"type": "image/png"
},
{
"src": "icons/Icon-maskable-192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "maskable"
},
{
"src": "icons/Icon-maskable-512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "maskable"
}
]
}
82 changes: 69 additions & 13 deletions lib/src/super_tooltip.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import 'dart:ui';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:super_tooltip/src/utils.dart';

Expand Down Expand Up @@ -325,6 +326,25 @@ class SuperTooltip extends StatefulWidget {
/// Defaults to `false`.
final bool clickThrough;

/// Whether to automatically show the tooltip when the mouse pointer hovers over the [child].
///
/// This feature utilizes [MouseRegion] and is primarily intended for Web and Desktop platforms.
/// On touch-based mobile devices, this parameter is generally ignored unless a mouse is connected.
///
/// Defaults to `false`.
final bool showOnHover;

/// Whether to automatically hide the tooltip when the mouse pointer leaves the [child]'s bounds.
///
/// This is primarily intended for Web and Desktop platforms.
///
/// **Note:** On Web/Desktop, enabling this will automatically disable the modal barrier
/// (regardless of [showBarrier]) to ensure the mouse can exit the widget area without
/// being blocked by the overlay.
///
/// Defaults to `false`.
final bool hideOnHoverExit;

SuperTooltip({
Key? key,
required this.content,
Expand Down Expand Up @@ -399,6 +419,8 @@ class SuperTooltip extends StatefulWidget {
this.showOnTap = true,
this.boxShadows,
this.clickThrough = false,
this.showOnHover = false,
this.hideOnHoverExit = false,
}) : assert(showDropBoxFilter ? showBarrier ?? false : true,
'showDropBoxFilter or showBarrier can\'t be false | null'),
super(key: key);
Expand Down Expand Up @@ -486,7 +508,6 @@ class _SuperTooltipState extends State<SuperTooltip>
closeButtonType = widget.closeButtonType;
closeButtonColor = widget.closeButtonColor ?? Colors.black;
closeButtonSize = widget.closeButtonSize ?? 30.0;
showBarrier = widget.showBarrier ?? true;
barrierColor = widget.barrierColor ?? Colors.black54;
hasShadow = widget.hasShadow ?? true;
shadowColor = widget.shadowColor ?? Colors.black54;
Expand All @@ -495,20 +516,55 @@ class _SuperTooltipState extends State<SuperTooltip>
shadowOffset = widget.shadowOffset ?? Offset.zero;
showBlur = widget.showDropBoxFilter;

return CompositedTransformTarget(
link: _layerLink,
child: GestureDetector(
onTap: () {
if (widget.toggleOnTap && _superTooltipController!.isVisible) {
/// On native mobile platforms, this parameter is ignored as hover events are not supported.
/// The widget reverts to standard barrier behavior (tap-to-dismiss) to prevent the
/// tooltip from becoming unresponsive.
var isNativeMobile = !kIsWeb &&
(defaultTargetPlatform == TargetPlatform.iOS ||
defaultTargetPlatform == TargetPlatform.android);

if (isNativeMobile) {
/// On native mobile platforms, this parameter is ignored as hover events are not supported.
/// The widget reverts to standard barrier behavior (tap-to-dismiss) to prevent the
/// tooltip from becoming unresponsive.
showBarrier = widget.showBarrier ?? true;
} else {
/// On Web and Desktop, if [hideOnHoverExit] is true, the barrier is
/// automatically disabled regardless of this value. This ensures that
/// the barrier does not obstruct the mouse cursor from triggering the exit event.
showBarrier = widget.hideOnHoverExit ? false : widget.showBarrier ?? true;
}
return MouseRegion(
hitTestBehavior: HitTestBehavior.translucent,
onEnter: (_) {
if (widget.showOnHover) {
if (!_superTooltipController!.isVisible) {
_superTooltipController!.showTooltip();
}
}
},
onExit: (_) {
if (widget.hideOnHoverExit) {
if (_superTooltipController!.isVisible) {
_superTooltipController!.hideTooltip();
} else {
if (widget.showOnTap) {
_superTooltipController!.showTooltip();
}
}
},
onLongPress: widget.onLongPress,
child: widget.child,
}
},
child: CompositedTransformTarget(
link: _layerLink,
child: GestureDetector(
onTap: () {
if (widget.toggleOnTap && _superTooltipController!.isVisible) {
_superTooltipController!.hideTooltip();
} else {
if (widget.showOnTap) {
_superTooltipController!.showTooltip();
}
}
},
onLongPress: widget.onLongPress,
child: widget.child,
),
),
);
}
Expand Down
Loading