diff --git a/CHANGELOG.md b/CHANGELOG.md index 8380bcc4..74fbd516 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,13 +1,15 @@ ## [4.0.0] (unreleased) - [BREAKING] Fixed [#457](https://github.com/SimformSolutionsPvtLtd/flutter_showcaseview/issues/457) titleAlignment property does not work -- Feature ✨: Added Action widget for tooltip +- Feature [#466](https://github.com/SimformSolutionsPvtLtd/flutter_showcaseview/pull/466): Added Action widget for tooltip - Feature [#475](https://github.com/SimformSolutionsPvtLtd/flutter_showcaseview/issues/475) - Add feasibility to change margin of tooltip with `toolTipMargin`. - Feature [#478](https://github.com/SimformSolutionsPvtLtd/flutter_showcaseview/issues/478) - Added feasibility to change auto scroll widget alignment `scrollAlignment`. -- Feature ✨: Added `enableAutoScroll` to `showcase`. +- Feature [#386](https://github.com/SimformSolutionsPvtLtd/flutter_showcaseview/pull/386): Added `enableAutoScroll` to `showcase`. - Feature [#395](https://github.com/SimformSolutionsPvtLtd/flutter_showcaseview/issues/395) - Added `floatingActionWidget` to give a static fixed widget at any place on the screen. +- Feature [#396](https://github.com/SimformSolutionsPvtLtd/flutter_showcaseview/pull/396): Added `globalFloatingActionWidget` and `hideFloatingActionWidgetForShowcase` for global + static fixed widget ## [3.0.0] - [BREAKING] Fixed [#434](https://github.com/SimformSolutionsPvtLtd/flutter_showcaseview/issues/434) removed deprecated text style after Flutter 3.22 follow [migration guide](https://docs.flutter.dev/release/breaking-changes/3-19-deprecations#texttheme) diff --git a/README.md b/README.md index f7b606b8..9c0553f5 100644 --- a/README.md +++ b/README.md @@ -136,27 +136,28 @@ WidgetsBinding.instance.addPostFrameCallback((_) => ## Properties of `ShowCaseWidget`: -| Name | Type | Default Behaviour | Description | -|---------------------------|----------------------------|------------------------------|--------------------------------------------------------------------------------| -| builder | Builder | | | -| blurValue | double | 0 | Provides blur effect on overlay | -| autoPlay | bool | false | Automatically display Next showcase | -| autoPlayDelay | Duration | Duration(milliseconds: 2000) | Visibility time of showcase when `autoplay` is enabled | -| enableAutoPlayLock | bool | false | Block the user interaction on overlay when autoPlay is enabled. | -| enableAutoScroll | bool | false | Allows to auto scroll to next showcase so as to make the given target visible. | -| scrollDuration | Duration | Duration(milliseconds: 300) | Time duration for auto scrolling | -| disableBarrierInteraction | bool | false | Disable barrier interaction | -| disableScaleAnimation | bool | false | Disable scale transition for all showcases | -| disableMovingAnimation | bool | false | Disable bouncing/moving transition for all showcases | -| onStart | Function(int?, GlobalKey)? | | Triggered on start of each showcase. | -| onComplete | Function(int?, GlobalKey)? | | Triggered on completion of each showcase. | -| onFinish | VoidCallback? | | Triggered when all the showcases are completed | -| enableShowcase | bool | true | Enable or disable showcase globally. | -| toolTipMargin | double | 14 | For tooltip margin | -| globalTooltipActionConfig | TooltipActionConfig? | | Global tooltip actionbar config | -| globalTooltipActions | List? | | Global list of tooltip actions | -| scrollAlignment | double | 0.5 | For Auto scroll widget alignment | -| globalTooltipActionConfig | FloatingActionWidget | | Global Config for tooltip action to auto apply for all the toolTip | +| Name | Type | Default Behaviour | Description | +|-------------------------------------|----------------------------------------------|------------------------------|--------------------------------------------------------------------------------| +| builder | Builder | | | +| blurValue | double | 0 | Provides blur effect on overlay. | +| autoPlay | bool | false | Automatically display Next showcase. | +| autoPlayDelay | Duration | Duration(milliseconds: 2000) | Visibility time of showcase when `autoplay` is enabled. | +| enableAutoPlayLock | bool | false | Block the user interaction on overlay when autoPlay is enabled. | +| enableAutoScroll | bool | false | Allows to auto scroll to next showcase so as to make the given target visible. | +| scrollDuration | Duration | Duration(milliseconds: 300) | Time duration for auto scrolling. | +| disableBarrierInteraction | bool | false | Disable barrier interaction. | +| disableScaleAnimation | bool | false | Disable scale transition for all showcases. | +| disableMovingAnimation | bool | false | Disable bouncing/moving transition for all showcases. | +| onStart | Function(int?, GlobalKey)? | | Triggered on start of each showcase. | +| onComplete | Function(int?, GlobalKey)? | | Triggered on completion of each showcase. | +| onFinish | VoidCallback? | | Triggered when all the showcases are completed. | +| enableShowcase | bool | true | Enable or disable showcase globally. | +| toolTipMargin | double | 14 | For tooltip margin. | +| globalTooltipActionConfig | TooltipActionConfig? | | Global tooltip actionbar config. | +| globalTooltipActions | List? | | Global list of tooltip actions . | +| scrollAlignment | double | 0.5 | For Auto scroll widget alignment. | +| globalFloatingActionWidget | FloatingActionWidget Function(BuildContext)? | | Global Config for tooltip action to auto apply for all the toolTip . | +| hideFloatingActionWidgetForShowcase | List | [] | Hides globalFloatingActionWidget for the provided showcase widget keys. | ## Properties of `Showcase` and `Showcase.withWidget`: diff --git a/example/lib/main.dart b/example/lib/main.dart index f369ed49..67c4c07a 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -26,6 +26,27 @@ class MyApp extends StatelessWidget { debugShowCheckedModeBanner: false, home: Scaffold( body: ShowCaseWidget( + hideFloatingActionWidgetForShowcase: [_lastShowcaseWidget], + globalFloatingActionWidget: (showcaseContext) => FloatingActionWidget( + left: 16, + bottom: 16, + child: Padding( + padding: const EdgeInsets.all(16.0), + child: ElevatedButton( + onPressed: ShowCaseWidget.of(showcaseContext).dismiss, + style: ElevatedButton.styleFrom( + backgroundColor: const Color(0xffEE5366), + ), + child: const Text( + 'Skip', + style: TextStyle( + color: Colors.white, + fontSize: 15, + ), + ), + ), + ), + ), onStart: (index, key) { log('onStart: $index, $key'); }, @@ -262,15 +283,17 @@ class _MailPageState extends State { child: Padding( padding: const EdgeInsets.all(16.0), child: ElevatedButton( + style: ElevatedButton.styleFrom( + backgroundColor: const Color(0xffEE5366), + ), + onPressed: ShowCaseWidget.of(context).dismiss, child: const Text( - 'Skip Showcase', + 'Close Showcase', style: TextStyle( - color: Colors.pink, + color: Colors.white, fontSize: 15, ), ), - onPressed: () => - ShowCaseWidget.of(context).dismiss(), ), ), ), @@ -582,38 +605,6 @@ class MailTile extends StatelessWidget { targetBorderRadius: const BorderRadius.all( Radius.circular(150), ), - floatingActionWidget: FloatingActionWidget.directional( - textDirection: Directionality.of(context), - start: 0, - bottom: 0, - child: Padding( - padding: const EdgeInsets.all(16.0), - child: ElevatedButton( - style: ButtonStyle( - backgroundColor: MaterialStateProperty.all( - Theme.of(context).primaryColor), - shape: MaterialStateProperty.all< - RoundedRectangleBorder>( - RoundedRectangleBorder( - borderRadius: BorderRadius.circular(18.0), - side: BorderSide( - color: Theme.of(context).primaryColor, - width: 2.0, - ), - ), - ), - ), - child: const Text( - 'Skip Showcase', - style: TextStyle( - color: Colors.white, - fontSize: 15, - ), - ), - onPressed: () => ShowCaseWidget.of(context).dismiss(), - ), - ), - ), container: Container( padding: const EdgeInsets.all(10), decoration: const BoxDecoration( diff --git a/lib/src/showcase.dart b/lib/src/showcase.dart index 32789995..e38a8ef8 100644 --- a/lib/src/showcase.dart +++ b/lib/src/showcase.dart @@ -562,6 +562,7 @@ class _ShowcaseState extends State { RenderBox? rootRenderObject; late final showCaseWidgetState = ShowCaseWidget.of(context); + FloatingActionWidget? _globalFloatingActionWidget; @override void initState() { @@ -577,6 +578,8 @@ class _ShowcaseState extends State { recalculateRootWidgetSize(); if (_enableShowcase) { + _globalFloatingActionWidget = + showCaseWidgetState.globalFloatingActionWidget?.call(context); final size = MediaQuery.of(context).size; position ??= GetPosition( rootRenderObject: rootRenderObject, @@ -794,8 +797,8 @@ class _ShowcaseState extends State { titleTextStyle: widget.titleTextStyle, descTextStyle: widget.descTextStyle, container: widget.container, - floatingActionWidget: widget.floatingActionWidget ?? - showCaseWidgetState.widget.globalFloatingActionWidget, + floatingActionWidget: + widget.floatingActionWidget ?? _globalFloatingActionWidget, tooltipBackgroundColor: widget.tooltipBackgroundColor, textColor: widget.textColor, showArrow: widget.showArrow, diff --git a/lib/src/showcase_widget.dart b/lib/src/showcase_widget.dart index 7204ec2d..337cfada 100644 --- a/lib/src/showcase_widget.dart +++ b/lib/src/showcase_widget.dart @@ -20,10 +20,14 @@ * SOFTWARE. */ +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import '../showcaseview.dart'; +typedef FloatingActionBuilderCallback = FloatingActionWidget Function( + BuildContext); + class ShowCaseWidget extends StatefulWidget { final WidgetBuilder builder; @@ -85,7 +89,9 @@ class ShowCaseWidget extends StatefulWidget { /// Custom static floating action widget to show a static widget anywhere /// on the screen for all the showcase widget - final FloatingActionWidget? globalFloatingActionWidget; + /// Use this context to access showcaseWidget operation otherwise it will + /// throw error. + final FloatingActionBuilderCallback? globalFloatingActionWidget; /// Global action to apply on every tooltip widget final List? globalTooltipActions; @@ -93,6 +99,11 @@ class ShowCaseWidget extends StatefulWidget { /// Global Config for tooltip action to auto apply for all the toolTip. final TooltipActionConfig? globalTooltipActionConfig; + /// Hides [globalFloatingActionWidget] for the provided showcase widgets. Add key of + /// showcase in which [globalFloatingActionWidget] should be hidden this list. + /// Defaults to []. + final List hideFloatingActionWidgetForShowcase; + /// A widget that manages multiple Showcase widgets. /// /// This widget provides a way to sequentially showcase multiple widgets @@ -119,7 +130,8 @@ class ShowCaseWidget extends StatefulWidget { /// - `enableShowcase`: Enables or disables the showcase functionality globally (defaults to `true`). /// - `globalTooltipActions`: A list of custom actions to be added to all tooltips. /// - `globalTooltipActionConfig`: Configuration options for the global tooltip actions. - /// - `floatingActionWidget`: Custom static floating action widget to show a static widget anywhere for all the showcase widgets + /// - `globalFloatingActionWidget`: Custom static floating action widget to show a static widget anywhere for all the showcase widgets. + /// - `hideFloatingActionWidgetForShowcase`: Hides a [globalFloatingActionWidget] for the provided showcase keys. const ShowCaseWidget({ required this.builder, this.onFinish, @@ -138,6 +150,7 @@ class ShowCaseWidget extends StatefulWidget { this.globalTooltipActionConfig, this.globalTooltipActions, this.globalFloatingActionWidget, + this.hideFloatingActionWidgetForShowcase = const [], }); static GlobalKey? activeTargetWidget(BuildContext context) { @@ -190,9 +203,35 @@ class ShowCaseWidgetState extends State { bool get isShowCaseCompleted => ids == null && activeWidgetId == null; + List get hideFloatingActionWidgetForShowcase => + _hideFloatingWidgetKeys; + + /// This Stores keys of showcase for which we will hide the + /// [globalFloatingActionWidget]. + late var _hideFloatingWidgetKeys = widget.hideFloatingActionWidgetForShowcase; + /// Returns value of [ShowCaseWidget.blurValue] double get blurValue => widget.blurValue; + /// Returns current active showcase key + GlobalKey? get getCurrentActiveShowcaseKey { + if (ids == null || activeWidgetId == null) return null; + + if (activeWidgetId! < ids!.length && activeWidgetId! >= 0) { + return ids![activeWidgetId!]; + } else { + return null; + } + } + + /// Return a [widget.globalFloatingActionWidget] if not need to hide this for + /// current showcase. + FloatingActionWidget Function(BuildContext context)? + get globalFloatingActionWidget => + _hideFloatingWidgetKeys.contains(getCurrentActiveShowcaseKey) + ? null + : widget.globalFloatingActionWidget; + @override void initState() { super.initState(); @@ -300,6 +339,12 @@ class ShowCaseWidgetState extends State { activeWidgetId = null; } + /// Updated the list of showcase keys for which we need to + /// hide the [globalFloatingActionWidget]. + void updateHideFloatingActionWidgetForShowcaseList( + List updatedList) => + _hideFloatingWidgetKeys = updatedList; + @override Widget build(BuildContext context) { return _InheritedShowCaseView( diff --git a/lib/src/tooltip_widget.dart b/lib/src/tooltip_widget.dart index e634e316..b6812dae 100644 --- a/lib/src/tooltip_widget.dart +++ b/lib/src/tooltip_widget.dart @@ -655,7 +655,9 @@ class _ToolTipWidgetState extends State ), ); - if (widget.floatingActionWidget != null) { + if (widget.floatingActionWidget == null) { + return defaultToolTipWidget; + } else { return Stack( fit: StackFit.expand, children: [ @@ -663,8 +665,6 @@ class _ToolTipWidgetState extends State widget.floatingActionWidget!, ], ); - } else { - return defaultToolTipWidget; } }