From 3c6f28be2d65c8fc003e38c025d53e14cd014b1b Mon Sep 17 00:00:00 2001 From: nilsreichardt Date: Sun, 7 Mar 2021 16:39:15 +0100 Subject: [PATCH 1/4] Moved all files into `src` --- example/lib/detailscreen.dart | 1 - lib/showcaseview.dart | 4 ++-- lib/{ => src}/custom_paint.dart | 0 lib/{ => src}/get_position.dart | 0 lib/{ => src}/layout_overlays.dart | 0 lib/{ => src}/measure_size.dart | 0 lib/{ => src}/showcase.dart | 4 ++-- lib/{ => src}/showcase_widget.dart | 0 lib/{ => src}/tooltip_widget.dart | 5 +++-- 9 files changed, 7 insertions(+), 7 deletions(-) rename lib/{ => src}/custom_paint.dart (100%) rename lib/{ => src}/get_position.dart (100%) rename lib/{ => src}/layout_overlays.dart (100%) rename lib/{ => src}/measure_size.dart (100%) rename lib/{ => src}/showcase.dart (98%) rename lib/{ => src}/showcase_widget.dart (100%) rename lib/{ => src}/tooltip_widget.dart (99%) diff --git a/example/lib/detailscreen.dart b/example/lib/detailscreen.dart index f88e82e6..9d43055b 100644 --- a/example/lib/detailscreen.dart +++ b/example/lib/detailscreen.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:showcaseview/showcase_widget.dart'; import 'package:showcaseview/showcaseview.dart'; class Detail extends StatefulWidget { diff --git a/lib/showcaseview.dart b/lib/showcaseview.dart index 24d569e2..fe77847f 100644 --- a/lib/showcaseview.dart +++ b/lib/showcaseview.dart @@ -26,5 +26,5 @@ library showcaseview; -export 'showcase.dart'; -export 'showcase_widget.dart'; +export 'src/showcase.dart'; +export 'src/showcase_widget.dart'; diff --git a/lib/custom_paint.dart b/lib/src/custom_paint.dart similarity index 100% rename from lib/custom_paint.dart rename to lib/src/custom_paint.dart diff --git a/lib/get_position.dart b/lib/src/get_position.dart similarity index 100% rename from lib/get_position.dart rename to lib/src/get_position.dart diff --git a/lib/layout_overlays.dart b/lib/src/layout_overlays.dart similarity index 100% rename from lib/layout_overlays.dart rename to lib/src/layout_overlays.dart diff --git a/lib/measure_size.dart b/lib/src/measure_size.dart similarity index 100% rename from lib/measure_size.dart rename to lib/src/measure_size.dart diff --git a/lib/showcase.dart b/lib/src/showcase.dart similarity index 98% rename from lib/showcase.dart rename to lib/src/showcase.dart index f54d29eb..116d9238 100644 --- a/lib/showcase.dart +++ b/lib/src/showcase.dart @@ -1,10 +1,10 @@ import 'package:flutter/material.dart'; import 'package:flutter/scheduler.dart'; import 'dart:async'; -import 'package:showcaseview/showcaseview.dart'; -import 'package:showcaseview/custom_paint.dart'; +import 'custom_paint.dart'; import 'get_position.dart'; import 'layout_overlays.dart'; +import 'showcase_widget.dart'; import 'tooltip_widget.dart'; class Showcase extends StatefulWidget { diff --git a/lib/showcase_widget.dart b/lib/src/showcase_widget.dart similarity index 100% rename from lib/showcase_widget.dart rename to lib/src/showcase_widget.dart diff --git a/lib/tooltip_widget.dart b/lib/src/tooltip_widget.dart similarity index 99% rename from lib/tooltip_widget.dart rename to lib/src/tooltip_widget.dart index 73d3d8e5..0568d673 100644 --- a/lib/tooltip_widget.dart +++ b/lib/src/tooltip_widget.dart @@ -27,8 +27,9 @@ import 'dart:math'; import 'package:flutter/material.dart'; -import 'package:showcaseview/get_position.dart'; -import 'package:showcaseview/measure_size.dart'; + +import 'get_position.dart'; +import 'measure_size.dart'; class ToolTipWidget extends StatefulWidget { final GetPosition position; From 9f3e832a626f2e31ddaf2e611987e863c0ba991d Mon Sep 17 00:00:00 2001 From: nilsreichardt Date: Sun, 7 Mar 2021 16:47:09 +0100 Subject: [PATCH 2/4] Migrated with `dart migrate` to null safety --- example/pubspec.yaml | 2 + lib/src/custom_paint.dart | 10 +-- lib/src/get_position.dart | 12 +-- lib/src/layout_overlays.dart | 36 ++++----- lib/src/measure_size.dart | 10 +-- lib/src/showcase.dart | 151 +++++++++++++++-------------------- lib/src/showcase_widget.dart | 49 ++++++------ lib/src/tooltip_widget.dart | 123 ++++++++++++++-------------- pubspec.yaml | 2 +- 9 files changed, 185 insertions(+), 210 deletions(-) diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 664b06a2..928a01c2 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -16,6 +16,8 @@ version: 1.0.0+1 environment: sdk: ">=2.1.0 <3.0.0" +publish_to: none + dependencies: flutter: sdk: flutter diff --git a/lib/src/custom_paint.dart b/lib/src/custom_paint.dart index 22424b81..979ce259 100644 --- a/lib/src/custom_paint.dart +++ b/lib/src/custom_paint.dart @@ -28,12 +28,12 @@ import 'package:flutter/material.dart'; class ShapePainter extends CustomPainter { Rect rect; - final ShapeBorder shapeBorder; - final Color color; - final double opacity; + final ShapeBorder? shapeBorder; + final Color? color; + final double? opacity; ShapePainter({ - @required this.rect, + required this.rect, this.color, this.shapeBorder, this.opacity, @@ -42,7 +42,7 @@ class ShapePainter extends CustomPainter { @override void paint(Canvas canvas, Size size) { final paint = Paint(); - paint.color = color.withOpacity(opacity); + paint.color = color!.withOpacity(opacity!); RRect outer = RRect.fromLTRBR(0, 0, size.width, size.height, Radius.circular(0)); diff --git a/lib/src/get_position.dart b/lib/src/get_position.dart index 600878ae..13dd019b 100644 --- a/lib/src/get_position.dart +++ b/lib/src/get_position.dart @@ -27,12 +27,12 @@ import 'package:flutter/material.dart'; class GetPosition { - final GlobalKey key; + final GlobalKey? key; GetPosition({this.key}); Rect getRect() { - RenderBox box = key.currentContext.findRenderObject(); + RenderBox box = key!.currentContext!.findRenderObject() as RenderBox; final topLeft = box.size.topLeft(box.localToGlobal(const Offset(0.0, 0.0))); final bottomRight = @@ -49,7 +49,7 @@ class GetPosition { ///Get the bottom position of the widget double getBottom() { - RenderBox box = key.currentContext.findRenderObject(); + RenderBox box = key!.currentContext!.findRenderObject() as RenderBox; final bottomRight = box.size.bottomRight(box.localToGlobal(const Offset(0.0, 0.0))); return bottomRight.dy; @@ -57,21 +57,21 @@ class GetPosition { ///Get the top position of the widget double getTop() { - RenderBox box = key.currentContext.findRenderObject(); + RenderBox box = key!.currentContext!.findRenderObject() as RenderBox; final topLeft = box.size.topLeft(box.localToGlobal(const Offset(0.0, 0.0))); return topLeft.dy; } ///Get the left position of the widget double getLeft() { - RenderBox box = key.currentContext.findRenderObject(); + RenderBox box = key!.currentContext!.findRenderObject() as RenderBox; final topLeft = box.size.topLeft(box.localToGlobal(const Offset(0.0, 0.0))); return topLeft.dx; } ///Get the right position of the widget double getRight() { - RenderBox box = key.currentContext.findRenderObject(); + RenderBox box = key!.currentContext!.findRenderObject() as RenderBox; final bottomRight = box.size.bottomRight(box.localToGlobal(const Offset(0.0, 0.0))); return bottomRight.dx; diff --git a/lib/src/layout_overlays.dart b/lib/src/layout_overlays.dart index e26db9d9..d7401219 100644 --- a/lib/src/layout_overlays.dart +++ b/lib/src/layout_overlays.dart @@ -43,9 +43,9 @@ import 'package:flutter/material.dart'; /// class AnchoredOverlay extends StatelessWidget { final bool showOverlay; - final Widget Function(BuildContext, Rect anchorBounds, Offset anchor) + final Widget Function(BuildContext, Rect anchorBounds, Offset anchor)? overlayBuilder; - final Widget child; + final Widget? child; AnchoredOverlay({ key, @@ -75,7 +75,7 @@ class AnchoredOverlay extends StatelessWidget { bottomRight.dy, ); final anchorCenter = box.size.center(topLeft); - return overlayBuilder(overlayContext, anchorBounds, anchorCenter); + return overlayBuilder!(overlayContext, anchorBounds, anchorCenter); }, child: child, ); @@ -99,8 +99,8 @@ class AnchoredOverlay extends StatelessWidget { // class OverlayBuilder extends StatefulWidget { final bool showOverlay; - final Widget Function(BuildContext) overlayBuilder; - final Widget child; + final Widget Function(BuildContext)? overlayBuilder; + final Widget? child; OverlayBuilder({ key, @@ -114,27 +114,29 @@ class OverlayBuilder extends StatefulWidget { } class _OverlayBuilderState extends State { - OverlayEntry _overlayEntry; + OverlayEntry? _overlayEntry; @override void initState() { super.initState(); if (widget.showOverlay) { - WidgetsBinding.instance.addPostFrameCallback((_) => showOverlay()); + WidgetsBinding.instance!.addPostFrameCallback((_) => showOverlay()); } } @override void didUpdateWidget(OverlayBuilder oldWidget) { super.didUpdateWidget(oldWidget); - WidgetsBinding.instance.addPostFrameCallback((_) => syncWidgetAndOverlay()); + WidgetsBinding.instance! + .addPostFrameCallback((_) => syncWidgetAndOverlay()); } @override void reassemble() { super.reassemble(); - WidgetsBinding.instance.addPostFrameCallback((_) => syncWidgetAndOverlay()); + WidgetsBinding.instance! + .addPostFrameCallback((_) => syncWidgetAndOverlay()); } @override @@ -152,9 +154,9 @@ class _OverlayBuilderState extends State { if (_overlayEntry == null) { // Create the overlay. _overlayEntry = OverlayEntry( - builder: widget.overlayBuilder, + builder: widget.overlayBuilder!, ); - addToOverlay(_overlayEntry); + addToOverlay(_overlayEntry!); } else { // Rebuild overlay. buildOverlay(); @@ -162,16 +164,12 @@ class _OverlayBuilderState extends State { } void addToOverlay(OverlayEntry overlayEntry) async { - Overlay.of(context).insert(overlayEntry); - final overlay = Overlay.of(context); - if (overlayEntry == null) - WidgetsBinding.instance - .addPostFrameCallback((_) => overlay.insert(overlayEntry)); + Overlay.of(context)!.insert(overlayEntry); } void hideOverlay() { if (_overlayEntry != null) { - _overlayEntry.remove(); + _overlayEntry!.remove(); _overlayEntry = null; } } @@ -185,7 +183,7 @@ class _OverlayBuilderState extends State { } void buildOverlay() async { - WidgetsBinding.instance + WidgetsBinding.instance! .addPostFrameCallback((_) => _overlayEntry?.markNeedsBuild()); } @@ -193,6 +191,6 @@ class _OverlayBuilderState extends State { Widget build(BuildContext context) { buildOverlay(); - return widget.child; + return widget.child!; } } diff --git a/lib/src/measure_size.dart b/lib/src/measure_size.dart index e0f7d88a..691d6024 100644 --- a/lib/src/measure_size.dart +++ b/lib/src/measure_size.dart @@ -1,15 +1,15 @@ import 'package:flutter/material.dart'; import 'package:flutter/scheduler.dart'; -typedef OnWidgetSizeChange = void Function(Size size); +typedef OnWidgetSizeChange = void Function(Size? size); class MeasureSize extends StatefulWidget { - final Widget child; + final Widget? child; final OnWidgetSizeChange onSizeChange; MeasureSize({ - @required this.onSizeChange, - @required this.child, + required this.onSizeChange, + required this.child, }); @override @@ -19,7 +19,7 @@ class MeasureSize extends StatefulWidget { class _MeasureSizeState extends State { @override Widget build(BuildContext context) { - SchedulerBinding.instance.addPostFrameCallback(postFrameCallback); + SchedulerBinding.instance!.addPostFrameCallback(postFrameCallback); return Container( key: widgetKey, child: widget.child, diff --git a/lib/src/showcase.dart b/lib/src/showcase.dart index 116d9238..078ad780 100644 --- a/lib/src/showcase.dart +++ b/lib/src/showcase.dart @@ -9,32 +9,32 @@ import 'tooltip_widget.dart'; class Showcase extends StatefulWidget { final Widget child; - final String title; - final String description; - final ShapeBorder shapeBorder; - final TextStyle titleTextStyle; - final TextStyle descTextStyle; + final String? title; + final String? description; + final ShapeBorder? shapeBorder; + final TextStyle? titleTextStyle; + final TextStyle? descTextStyle; final EdgeInsets contentPadding; - final GlobalKey key; + final GlobalKey? key; final Color overlayColor; final double overlayOpacity; - final Widget container; + final Widget? container; final Color showcaseBackgroundColor; final Color textColor; final bool showArrow; - final double height; - final double width; + final double? height; + final double? width; final Duration animationDuration; - final VoidCallback onToolTipClick; - final VoidCallback onTargetClick; - final bool disposeOnTap; + final VoidCallback? onToolTipClick; + final VoidCallback? onTargetClick; + final bool? disposeOnTap; final bool disableAnimation; const Showcase({ - @required this.key, - @required this.child, + required this.key, + required this.child, this.title, - @required this.description, + required this.description, this.shapeBorder, this.overlayColor = Colors.black, this.overlayOpacity = 0.75, @@ -63,57 +63,32 @@ class Showcase extends StatefulWidget { disposeOnTap == null ? true : (onTargetClick == null ? false : true), - "onTargetClick is required if you're using disposeOnTap"), - assert(key != null || - child != null || - title != null || - showArrow != null || - description != null || - shapeBorder != null || - overlayColor != null || - titleTextStyle != null || - descTextStyle != null || - showcaseBackgroundColor != null || - textColor != null || - shapeBorder != null || - animationDuration != null); + "onTargetClick is required if you're using disposeOnTap"); - const Showcase.withWidget( - {this.key, - @required this.child, - @required this.container, - @required this.height, - @required this.width, - this.title, - this.description, - this.shapeBorder, - this.overlayColor = Colors.black, - this.overlayOpacity = 0.75, - this.titleTextStyle, - this.descTextStyle, - this.showcaseBackgroundColor = Colors.white, - this.textColor = Colors.black, - this.onTargetClick, - this.disposeOnTap, - this.animationDuration = const Duration(milliseconds: 2000), - this.disableAnimation = false, - this.contentPadding = const EdgeInsets.symmetric(vertical: 8)}) - : this.showArrow = false, + const Showcase.withWidget({ + this.key, + required this.child, + required this.container, + required this.height, + required this.width, + this.title, + this.description, + this.shapeBorder, + this.overlayColor = Colors.black, + this.overlayOpacity = 0.75, + this.titleTextStyle, + this.descTextStyle, + this.showcaseBackgroundColor = Colors.white, + this.textColor = Colors.black, + this.onTargetClick, + this.disposeOnTap, + this.animationDuration = const Duration(milliseconds: 2000), + this.disableAnimation = false, + this.contentPadding = const EdgeInsets.symmetric(vertical: 8), + }) : this.showArrow = false, this.onToolTipClick = null, assert(overlayOpacity >= 0.0 && overlayOpacity <= 1.0, - "overlay opacity should be >= 0.0 and <= 1.0."), - assert(key != null || - child != null || - title != null || - description != null || - shapeBorder != null || - overlayColor != null || - titleTextStyle != null || - descTextStyle != null || - showcaseBackgroundColor != null || - textColor != null || - shapeBorder != null || - animationDuration != null); + "overlay opacity should be >= 0.0 and <= 1.0."); @override _ShowcaseState createState() => _ShowcaseState(); @@ -121,10 +96,10 @@ class Showcase extends StatefulWidget { class _ShowcaseState extends State with TickerProviderStateMixin { bool _showShowCase = false; - Animation _slideAnimation; - AnimationController _slideAnimationController; - Timer timer; - GetPosition position; + Animation? _slideAnimation; + late AnimationController _slideAnimationController; + Timer? timer; + GetPosition? position; @override void initState() { @@ -168,17 +143,17 @@ class _ShowcaseState extends State with TickerProviderStateMixin { /// show overlay if there is any target widget /// void showOverlay() { - GlobalKey activeStep = ShowCaseWidget.activeTargetWidget(context); + GlobalKey? activeStep = ShowCaseWidget.activeTargetWidget(context); setState(() { _showShowCase = activeStep == widget.key; }); if (activeStep == widget.key) { _slideAnimationController.forward(); - if (ShowCaseWidget.of(context).autoPlay) { + if (ShowCaseWidget.of(context)!.autoPlay) { timer = Timer( Duration( - seconds: ShowCaseWidget.of(context).autoPlayDelay.inSeconds), + seconds: ShowCaseWidget.of(context)!.autoPlayDelay.inSeconds), () { _nextIfAny(); }); @@ -198,15 +173,15 @@ class _ShowcaseState extends State with TickerProviderStateMixin { } void _nextIfAny() { - if (timer != null && timer.isActive) { - if (ShowCaseWidget.of(context).autoPlayLockEnable) { + if (timer != null && timer!.isActive) { + if (ShowCaseWidget.of(context)!.autoPlayLockEnable) { return; } - timer.cancel(); - } else if (timer != null && !timer.isActive) { + timer!.cancel(); + } else if (timer != null && !timer!.isActive) { timer = null; } - ShowCaseWidget.of(context).completed(widget.key); + ShowCaseWidget.of(context)!.completed(widget.key); if (!widget.disableAnimation) { _slideAnimationController.forward(); } @@ -214,16 +189,16 @@ class _ShowcaseState extends State with TickerProviderStateMixin { void _getOnTargetTap() { if (widget.disposeOnTap == true) { - ShowCaseWidget.of(context).dismiss(); - widget.onTargetClick(); + ShowCaseWidget.of(context)!.dismiss(); + widget.onTargetClick!(); } else { - (widget.onTargetClick ?? _nextIfAny)?.call(); + (widget.onTargetClick ?? _nextIfAny).call(); } } void _getOnTooltipTap() { if (widget.disposeOnTap == true) { - ShowCaseWidget.of(context).dismiss(); + ShowCaseWidget.of(context)!.dismiss(); } widget.onToolTipClick?.call(); } @@ -248,7 +223,7 @@ class _ShowcaseState extends State with TickerProviderStateMixin { child: CustomPaint( painter: ShapePainter( opacity: widget.overlayOpacity, - rect: position.getRect(), + rect: position!.getRect(), shapeBorder: widget.shapeBorder, color: widget.overlayColor), ), @@ -285,14 +260,14 @@ class _ShowcaseState extends State with TickerProviderStateMixin { class _TargetWidget extends StatelessWidget { final Offset offset; - final Size size; - final Animation widthAnimation; - final VoidCallback onTap; - final ShapeBorder shapeBorder; + final Size? size; + final Animation? widthAnimation; + final VoidCallback? onTap; + final ShapeBorder? shapeBorder; _TargetWidget({ - Key key, - @required this.offset, + Key? key, + required this.offset, this.size, this.widthAnimation, this.onTap, @@ -309,8 +284,8 @@ class _TargetWidget extends StatelessWidget { child: GestureDetector( onTap: onTap, child: Container( - height: size.height + 16, - width: size.width + 16, + height: size!.height + 16, + width: size!.width + 16, decoration: ShapeDecoration( shape: shapeBorder ?? RoundedRectangleBorder( diff --git a/lib/src/showcase_widget.dart b/lib/src/showcase_widget.dart index a8daef0e..543b6f1a 100644 --- a/lib/src/showcase_widget.dart +++ b/lib/src/showcase_widget.dart @@ -28,15 +28,15 @@ import 'package:flutter/material.dart'; class ShowCaseWidget extends StatefulWidget { final Builder builder; - final VoidCallback onFinish; - final Function(int, GlobalKey) onStart; - final Function(int, GlobalKey) onComplete; + final VoidCallback? onFinish; + final Function(int?, GlobalKey)? onStart; + final Function(int?, GlobalKey)? onComplete; final bool autoPlay; final Duration autoPlayDelay; final bool autoPlayLockEnable; const ShowCaseWidget({ - @required this.builder, + required this.builder, this.onFinish, this.onStart, this.onComplete, @@ -47,12 +47,12 @@ class ShowCaseWidget extends StatefulWidget { static activeTargetWidget(BuildContext context) { return context - .dependOnInheritedWidgetOfExactType<_InheritedShowCaseView>() + .dependOnInheritedWidgetOfExactType<_InheritedShowCaseView>()! .activeWidgetIds; } - static ShowCaseWidgetState of(BuildContext context) { - ShowCaseWidgetState state = + static ShowCaseWidgetState? of(BuildContext context) { + ShowCaseWidgetState? state = context.findAncestorStateOfType(); if (state != null) { return context.findAncestorStateOfType(); @@ -66,15 +66,14 @@ class ShowCaseWidget extends StatefulWidget { } class ShowCaseWidgetState extends State { - List ids; - int activeWidgetId; - bool autoPlay; - Duration autoPlayDelay; - bool autoPlayLockEnable; + List? ids; + int? activeWidgetId; + late bool autoPlay; + late Duration autoPlayDelay; + late bool autoPlayLockEnable; @override void initState() { - // TODO: implement initState super.initState(); this.autoPlayDelay = widget.autoPlayDelay; this.autoPlay = widget.autoPlay; @@ -89,17 +88,17 @@ class ShowCaseWidgetState extends State { }); } - void completed(GlobalKey id) { - if (ids != null && ids[activeWidgetId] == id) { + void completed(GlobalKey? id) { + if (ids != null && ids![activeWidgetId!] == id) { setState(() { _onComplete(); - ++activeWidgetId; + activeWidgetId = activeWidgetId! + 1; _onStart(); - if (activeWidgetId >= ids.length) { + if (activeWidgetId! >= ids!.length) { _cleanupAfterSteps(); if (widget.onFinish != null) { - widget.onFinish(); + widget.onFinish!(); } } }); @@ -113,13 +112,13 @@ class ShowCaseWidgetState extends State { } void _onStart() { - if (activeWidgetId < ids.length) { - widget.onStart?.call(activeWidgetId, ids[activeWidgetId]); + if (activeWidgetId! < ids!.length) { + widget.onStart?.call(activeWidgetId, ids![activeWidgetId!]); } } void _onComplete() { - widget.onComplete?.call(activeWidgetId, ids[activeWidgetId]); + widget.onComplete?.call(activeWidgetId, ids![activeWidgetId!]); } void _cleanupAfterSteps() { @@ -131,17 +130,17 @@ class ShowCaseWidgetState extends State { Widget build(BuildContext context) { return _InheritedShowCaseView( child: widget.builder, - activeWidgetIds: ids?.elementAt(activeWidgetId), + activeWidgetIds: ids?.elementAt(activeWidgetId!), ); } } class _InheritedShowCaseView extends InheritedWidget { - final GlobalKey activeWidgetIds; + final GlobalKey? activeWidgetIds; _InheritedShowCaseView({ - @required this.activeWidgetIds, - @required child, + required this.activeWidgetIds, + required child, }) : super(child: child); @override diff --git a/lib/src/tooltip_widget.dart b/lib/src/tooltip_widget.dart index 0568d673..e1db6253 100644 --- a/lib/src/tooltip_widget.dart +++ b/lib/src/tooltip_widget.dart @@ -32,23 +32,23 @@ import 'get_position.dart'; import 'measure_size.dart'; class ToolTipWidget extends StatefulWidget { - final GetPosition position; - final Offset offset; - final Size screenSize; - final String title; - final String description; - final Animation animationOffset; - final TextStyle titleTextStyle; - final TextStyle descTextStyle; - final Widget container; - final Color tooltipColor; - final Color textColor; - final bool showArrow; - final double contentHeight; - final double contentWidth; - static bool isArrowUp; - final VoidCallback onTooltipTap; - final EdgeInsets contentPadding; + final GetPosition? position; + final Offset? offset; + final Size? screenSize; + final String? title; + final String? description; + final Animation? animationOffset; + final TextStyle? titleTextStyle; + final TextStyle? descTextStyle; + final Widget? container; + final Color? tooltipColor; + final Color? textColor; + final bool? showArrow; + final double? contentHeight; + final double? contentWidth; + static late bool isArrowUp; + final VoidCallback? onTooltipTap; + final EdgeInsets? contentPadding; ToolTipWidget( {this.position, @@ -73,12 +73,12 @@ class ToolTipWidget extends StatefulWidget { } class _ToolTipWidgetState extends State { - Offset position; + Offset? position; bool isCloseToTopOrBottom(Offset position) { double height = 120; height = widget.contentHeight ?? height; - return (widget.screenSize.height - position.dy) <= height; + return (widget.screenSize!.height - position.dy) <= height; } String findPositionForContent(Offset position) { @@ -90,64 +90,64 @@ class _ToolTipWidgetState extends State { } double _getTooltipWidth() { - double titleLength = widget.title == null ? 0 : widget.title.length * 10.0; - double descriptionLength = widget.description.length * 7.0; + double titleLength = widget.title == null ? 0 : widget.title!.length * 10.0; + double descriptionLength = widget.description!.length * 7.0; var maxTextWidth = max(titleLength, descriptionLength); - if (maxTextWidth > widget.screenSize.width - 20) { - return widget.screenSize.width - 20; + if (maxTextWidth > widget.screenSize!.width - 20) { + return widget.screenSize!.width - 20; } else { return maxTextWidth + 15; } } bool _isLeft() { - double screenWidth = widget.screenSize.width / 3; - return !(screenWidth <= widget.position.getCenter()); + double screenWidth = widget.screenSize!.width / 3; + return !(screenWidth <= widget.position!.getCenter()); } bool _isRight() { - double screenWidth = widget.screenSize.width / 3; - return ((screenWidth * 2) <= widget.position.getCenter()); + double screenWidth = widget.screenSize!.width / 3; + return ((screenWidth * 2) <= widget.position!.getCenter()); } - double _getLeft() { + double? _getLeft() { if (_isLeft()) { double leftPadding = - widget.position.getCenter() - (_getTooltipWidth() * 0.1); - if (leftPadding + _getTooltipWidth() > widget.screenSize.width) { - leftPadding = (widget.screenSize.width - 20) - _getTooltipWidth(); + widget.position!.getCenter() - (_getTooltipWidth() * 0.1); + if (leftPadding + _getTooltipWidth() > widget.screenSize!.width) { + leftPadding = (widget.screenSize!.width - 20) - _getTooltipWidth(); } if (leftPadding < 20) { leftPadding = 14; } return leftPadding; } else if (!(_isRight())) { - return widget.position.getCenter() - (_getTooltipWidth() * 0.5); + return widget.position!.getCenter() - (_getTooltipWidth() * 0.5); } else { return null; } } - double _getRight() { + double? _getRight() { if (_isRight()) { double rightPadding = - widget.position.getCenter() + (_getTooltipWidth() / 2); - if (rightPadding + _getTooltipWidth() > widget.screenSize.width) { + widget.position!.getCenter() + (_getTooltipWidth() / 2); + if (rightPadding + _getTooltipWidth() > widget.screenSize!.width) { rightPadding = 14; } return rightPadding; } else if (!(_isLeft())) { - return widget.position.getCenter() - (_getTooltipWidth() * 0.5); + return widget.position!.getCenter() - (_getTooltipWidth() * 0.5); } else { return null; } } double _getSpace() { - double space = widget.position.getCenter() - (widget.contentWidth / 2); - if (space + widget.contentWidth > widget.screenSize.width) { - space = widget.screenSize.width - widget.contentWidth - 8; - } else if (space < (widget.contentWidth / 2)) { + double space = widget.position!.getCenter() - (widget.contentWidth! / 2); + if (space + widget.contentWidth! > widget.screenSize!.width) { + space = widget.screenSize!.width - widget.contentWidth! - 8; + } else if (space < (widget.contentWidth! / 2)) { space = 16; } return space; @@ -161,20 +161,21 @@ class _ToolTipWidgetState extends State { @override Widget build(BuildContext context) { - final contentOrientation = findPositionForContent(position); + final contentOrientation = findPositionForContent(position!); final contentOffsetMultiplier = contentOrientation == "BELOW" ? 1.0 : -1.0; ToolTipWidget.isArrowUp = contentOffsetMultiplier == 1.0; final contentY = ToolTipWidget.isArrowUp - ? widget.position.getBottom() + (contentOffsetMultiplier * 3) - : widget.position.getTop() + (contentOffsetMultiplier * 3); + ? widget.position!.getBottom() + (contentOffsetMultiplier * 3) + : widget.position!.getTop() + (contentOffsetMultiplier * 3); - final contentFractionalOffset = contentOffsetMultiplier.clamp(-1.0, 0.0); + final num contentFractionalOffset = + contentOffsetMultiplier.clamp(-1.0, 0.0); double paddingTop = ToolTipWidget.isArrowUp ? 22 : 0; double paddingBottom = ToolTipWidget.isArrowUp ? 0 : 27; - if (!widget.showArrow) { + if (!widget.showArrow!) { paddingTop = 10; paddingBottom = 10; } @@ -182,18 +183,18 @@ class _ToolTipWidgetState extends State { if (widget.container == null) { return Stack( children: [ - widget.showArrow ? _getArrow(contentOffsetMultiplier) : Container(), + widget.showArrow! ? _getArrow(contentOffsetMultiplier) : Container(), Positioned( top: contentY, left: _getLeft(), right: _getRight(), child: FractionalTranslation( - translation: Offset(0.0, contentFractionalOffset), + translation: Offset(0.0, contentFractionalOffset as double), child: SlideTransition( position: Tween( begin: Offset(0.0, contentFractionalOffset / 10), end: Offset(0.0, 0.100), - ).animate(widget.animationOffset), + ).animate(widget.animationOffset!), child: Material( color: Colors.transparent, child: Container( @@ -218,22 +219,22 @@ class _ToolTipWidgetState extends State { children: [ widget.title != null ? Text( - widget.title, + widget.title!, style: widget.titleTextStyle ?? Theme.of(context) .textTheme - .headline6 + .headline6! .merge(TextStyle( color: widget.textColor)), ) : Container(), Text( - widget.description, + widget.description!, style: widget.descTextStyle ?? Theme.of(context) .textTheme - .subtitle2 + .subtitle2! .merge(TextStyle( color: widget.textColor)), ), @@ -259,14 +260,14 @@ class _ToolTipWidgetState extends State { left: _getSpace(), top: contentY - 10, child: FractionalTranslation( - translation: Offset(0.0, contentFractionalOffset), + translation: Offset(0.0, contentFractionalOffset as double), child: SlideTransition( position: Tween( begin: Offset(0.0, contentFractionalOffset / 10), - end: !widget.showArrow && !ToolTipWidget.isArrowUp + end: !widget.showArrow! && !ToolTipWidget.isArrowUp ? Offset(0.0, 0.0) : Offset(0.0, 0.100), - ).animate(widget.animationOffset), + ).animate(widget.animationOffset!), child: Material( color: Colors.transparent, child: GestureDetector( @@ -280,9 +281,9 @@ class _ToolTipWidgetState extends State { child: MeasureSize( onSizeChange: (size) { setState(() { - Offset tempPos = position; + Offset? tempPos = position; tempPos = Offset( - position.dx, position.dy + size.height); + position!.dx, position!.dy + size!.height); position = tempPos; }); }, @@ -303,16 +304,16 @@ class _ToolTipWidgetState extends State { final contentFractionalOffset = contentOffsetMultiplier.clamp(-1.0, 0.0); return Positioned( top: ToolTipWidget.isArrowUp - ? widget.position.getBottom() - : widget.position.getTop() - 1, - left: widget.position.getCenter() - 24, + ? widget.position!.getBottom() + : widget.position!.getTop() - 1, + left: widget.position!.getCenter() - 24, child: FractionalTranslation( translation: Offset(0.0, contentFractionalOffset), child: SlideTransition( position: Tween( begin: Offset(0.0, contentFractionalOffset / 5), end: Offset(0.0, 0.150), - ).animate(widget.animationOffset), + ).animate(widget.animationOffset!), child: Icon( ToolTipWidget.isArrowUp ? Icons.arrow_drop_up diff --git a/pubspec.yaml b/pubspec.yaml index 0d4cf7fd..7abacc60 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -5,7 +5,7 @@ homepage: https://github.com/simformsolutions/flutter_showcaseview issue_tracker: https://github.com/simformsolutions/flutter_showcaseview/issues environment: - sdk: ">=2.1.0 <3.0.0" + sdk: '>=2.12.0 <3.0.0' dependencies: flutter: From f4498b6a7ca860d1d4155e1f576d48ace6356abe Mon Sep 17 00:00:00 2001 From: nilsreichardt Date: Sun, 7 Mar 2021 16:50:12 +0100 Subject: [PATCH 3/4] Updated version --- CHANGELOG.md | 3 +++ pubspec.yaml | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a86da44b..791ccd5b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## [0.2.0] - March 07, 2021 +- Migrated to null safety + ## [0.1.6] - August 21, 2020 - [Feature #63](https://github.com/SimformSolutionsPvtLtd/flutter_showcaseview/issues/63) method callback after individual showcase start and end diff --git a/pubspec.yaml b/pubspec.yaml index 7abacc60..791d66b8 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: showcaseview description: A Flutter package to Showcase/Highlight widgets step by step. -version: 0.1.6 +version: 0.2.0 homepage: https://github.com/simformsolutions/flutter_showcaseview issue_tracker: https://github.com/simformsolutions/flutter_showcaseview/issues From db71183c06e895afe5b5ea85719c1fdaaba34e0f Mon Sep 17 00:00:00 2001 From: Devarsh Ranpara Date: Fri, 16 Apr 2021 18:49:42 +0530 Subject: [PATCH 4/4] :sparkles: Added support for null safety in Example app. --- example/lib/detailscreen.dart | 6 +++--- example/lib/main.dart | 18 +++++++++--------- example/pubspec.yaml | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/example/lib/detailscreen.dart b/example/lib/detailscreen.dart index 9d43055b..7e7eb583 100644 --- a/example/lib/detailscreen.dart +++ b/example/lib/detailscreen.dart @@ -8,14 +8,14 @@ class Detail extends StatefulWidget { class _DetailState extends State { final GlobalKey _one = GlobalKey(); - BuildContext myContext; + BuildContext? myContext; @override void initState() { super.initState(); - WidgetsBinding.instance.addPostFrameCallback((_) { + WidgetsBinding.instance!.addPostFrameCallback((_) { Future.delayed(Duration(milliseconds: 200), - () => ShowCaseWidget.of(myContext).startShowCase([_one])); + () => ShowCaseWidget.of(myContext!)!.startShowCase([_one])); }); } diff --git a/example/lib/main.dart b/example/lib/main.dart index 53196316..39febe21 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -48,8 +48,8 @@ class _MailPageState extends State { void initState() { super.initState(); //Start showcase view after current widget frames are drawn. - WidgetsBinding.instance.addPostFrameCallback((_) => - ShowCaseWidget.of(context) + WidgetsBinding.instance!.addPostFrameCallback((_) => + ShowCaseWidget.of(context)! .startShowCase([_one, _two, _three, _four, _five])); } @@ -163,7 +163,7 @@ class _MailPageState extends State { ), ).then((_) { setState(() { - ShowCaseWidget.of(context) + ShowCaseWidget.of(context)! .startShowCase([_four, _five]); }); }); @@ -325,7 +325,7 @@ class _MailPageState extends State { backgroundColor: Colors.white, onPressed: () { setState(() { - ShowCaseWidget.of(context) + ShowCaseWidget.of(context)! .startShowCase([_one, _two, _three, _four, _five]); }); }, @@ -347,11 +347,11 @@ class Mail { bool isUnread; Mail({ - this.sender, - this.sub, - this.msg, - this.date, - this.isUnread, + required this.sender, + required this.sub, + required this.msg, + required this.date, + required this.isUnread, }); } diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 928a01c2..492fb6e3 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -14,7 +14,7 @@ description: A new Flutter application. version: 1.0.0+1 environment: - sdk: ">=2.1.0 <3.0.0" + sdk: ">=2.12.0 <3.0.0" publish_to: none