-
Notifications
You must be signed in to change notification settings - Fork 521
feat: ✨ Multiple showcase at the same time and improvement #514
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 3 commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
67879cf
feat: ✨ Added Multi Showcase functionality and improvements
Sahil-Simform c55862f
fix: 🔨Fixed PR issue
Sahil-Simform 228af1d
fix: 🔨Fixed PR comments
Sahil-Simform b476dc8
fix: 🔨Fixed PR comments
Sahil-Simform 1aa080d
fix: 🔨Fixed PR comments
Sahil-Simform 9a94177
fix: 🔨Fixed PR comments
Sahil-Simform 5405eee
chore: 💥 Update min dart sdk to 2.19.6
Sahil-Simform 35ec3f7
fix: 🩹 Fixed the page transition issue
Sahil-Simform ec0d57c
fix: 🩹 Shifted everything to showcase controller
Sahil-Simform File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -26,29 +26,27 @@ import 'package:flutter/material.dart'; | |
|
|
||
| class GetPosition { | ||
| GetPosition({ | ||
| required this.key, | ||
| required this.renderBox, | ||
| required this.screenWidth, | ||
| required this.screenHeight, | ||
| this.padding = EdgeInsets.zero, | ||
| this.rootRenderObject, | ||
| }) { | ||
| getRenderBox(); | ||
| _getRenderBox(); | ||
| } | ||
|
|
||
| final GlobalKey key; | ||
| final RenderBox? renderBox; | ||
| final EdgeInsets padding; | ||
| final double screenWidth; | ||
| final double screenHeight; | ||
| final RenderObject? rootRenderObject; | ||
|
|
||
| late final RenderBox? _box; | ||
| late final Offset? _boxOffset; | ||
| RenderBox? _box; | ||
| Offset? _boxOffset; | ||
|
|
||
| RenderBox? get box => _box; | ||
|
|
||
| void getRenderBox() { | ||
| var renderBox = key.currentContext?.findRenderObject() as RenderBox?; | ||
|
|
||
| void _getRenderBox() { | ||
|
||
| if (renderBox == null) return; | ||
|
|
||
| _box = renderBox; | ||
|
|
@@ -72,7 +70,8 @@ class GetPosition { | |
| final topLeft = _box!.size.topLeft(_boxOffset!); | ||
| final bottomRight = _box!.size.bottomRight(_boxOffset!); | ||
| final leftDx = topLeft.dx - padding.left; | ||
| final leftDy = topLeft.dy - padding.top; | ||
| var leftDy = topLeft.dy - padding.top; | ||
| if (leftDy < 0) leftDy = 0; | ||
| final rect = Rect.fromLTRB( | ||
| leftDx.clamp(0, leftDx), | ||
| leftDy.clamp(0, leftDy), | ||
|
|
@@ -123,4 +122,18 @@ class GetPosition { | |
| double getWidth() => getRight() - getLeft(); | ||
|
|
||
| double getCenter() => (getLeft() + getRight()) * 0.5; | ||
|
|
||
| Offset topLeft() { | ||
| final box = _box; | ||
| if (box == null) return Offset.zero; | ||
|
|
||
| return box.size.topLeft( | ||
| box.localToGlobal( | ||
| Offset.zero, | ||
| ancestor: rootRenderObject, | ||
| ), | ||
| ); | ||
| } | ||
|
|
||
| Offset getOffset() => _box?.size.center(topLeft()) ?? Offset.zero; | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -24,94 +24,6 @@ import 'package:flutter/material.dart'; | |
|
|
||
| import 'showcase_widget.dart'; | ||
|
|
||
| typedef OverlayBuilderCallback = Widget Function( | ||
| BuildContext context, | ||
| Rect anchorBounds, | ||
| Offset anchor, | ||
| ); | ||
|
|
||
| /// Displays an overlay Widget anchored directly above the center of this | ||
| /// [AnchoredOverlay]. | ||
| /// | ||
| /// The overlay Widget is created by invoking the provided [overlayBuilder]. | ||
| /// | ||
| /// The [anchor] position is provided to the [overlayBuilder], but the builder | ||
| /// does not have to respect it. In other words, the [overlayBuilder] can | ||
| /// interpret the meaning of "anchor" however it wants - the overlay will not | ||
| /// be forced to be centered about the [anchor]. | ||
| /// | ||
| /// The overlay built by this [AnchoredOverlay] can be conditionally shown | ||
| /// and hidden by settings the [showOverlay] property to true or false. | ||
| /// | ||
| /// The [overlayBuilder] is invoked every time this Widget is rebuilt. | ||
| /// | ||
| class AnchoredOverlay extends StatelessWidget { | ||
| final bool showOverlay; | ||
| final OverlayBuilderCallback? overlayBuilder; | ||
| final Widget? child; | ||
| final RenderObject? rootRenderObject; | ||
|
|
||
| const AnchoredOverlay({ | ||
| super.key, | ||
| this.showOverlay = false, | ||
| this.overlayBuilder, | ||
| this.child, | ||
| this.rootRenderObject, | ||
| }); | ||
|
|
||
| @override | ||
| Widget build(BuildContext context) { | ||
| return LayoutBuilder( | ||
| builder: (context, constraints) { | ||
| return OverlayBuilder( | ||
| showOverlay: showOverlay, | ||
| overlayBuilder: (overlayContext) { | ||
| // To calculate the "anchor" point we grab the render box of | ||
| // our parent Container and then we find the center of that box. | ||
| final box = context.findRenderObject() as RenderBox?; | ||
|
|
||
| /// Handle null RenderBox safely. | ||
| final topLeft = box?.size.topLeft( | ||
| box.localToGlobal( | ||
| Offset.zero, | ||
| ancestor: rootRenderObject, | ||
| ), | ||
| ) ?? | ||
| Offset.zero; | ||
| final bottomRight = box?.size.bottomRight( | ||
| box.localToGlobal( | ||
| Offset.zero, | ||
| ancestor: rootRenderObject, | ||
| ), | ||
| ) ?? | ||
| Offset.zero; | ||
|
|
||
| /// Provide a default anchorBounds if box is null. | ||
| final anchorBounds = (topLeft.dx.isNaN || | ||
| topLeft.dy.isNaN || | ||
| bottomRight.dx.isNaN || | ||
| bottomRight.dy.isNaN) | ||
| ? const Rect.fromLTRB(0.0, 0.0, 0.0, 0.0) | ||
| : Rect.fromLTRB( | ||
| topLeft.dx, | ||
| topLeft.dy, | ||
| bottomRight.dx, | ||
| bottomRight.dy, | ||
| ); | ||
|
|
||
| /// Calculate the anchor center or default to Offset.zero. | ||
| final anchorCenter = box?.size.center(topLeft) ?? Offset.zero; | ||
|
|
||
| /// Pass the anchor details to the overlay builder. | ||
| return overlayBuilder!(overlayContext, anchorBounds, anchorCenter); | ||
| }, | ||
| child: child, | ||
| ); | ||
| }, | ||
| ); | ||
| } | ||
| } | ||
|
|
||
| /// Displays an overlay Widget as constructed by the given [overlayBuilder]. | ||
| /// | ||
| /// The overlay built by the [overlayBuilder] can be conditionally shown and | ||
|
|
@@ -125,37 +37,46 @@ class AnchoredOverlay extends StatelessWidget { | |
| /// exist in [OverlayEntry]s which are inaccessible to outside Widgets. But if | ||
| /// a better approach is found then feel free to use it. | ||
| class OverlayBuilder extends StatefulWidget { | ||
| final bool showOverlay; | ||
| final WidgetBuilder? overlayBuilder; | ||
| final Widget? child; | ||
|
|
||
| const OverlayBuilder({ | ||
| super.key, | ||
| this.showOverlay = false, | ||
| required this.child, | ||
| required this.updateOverlay, | ||
| this.overlayBuilder, | ||
| this.child, | ||
| }); | ||
|
|
||
| final WidgetBuilder? overlayBuilder; | ||
| final Widget child; | ||
| final ValueSetter<ValueSetter<bool>> updateOverlay; | ||
aditya-css marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| @override | ||
| State<OverlayBuilder> createState() => _OverlayBuilderState(); | ||
| } | ||
|
|
||
| class _OverlayBuilderState extends State<OverlayBuilder> { | ||
| OverlayEntry? _overlayEntry; | ||
|
|
||
| bool _showOverlay = false; | ||
|
|
||
| @override | ||
| void initState() { | ||
| super.initState(); | ||
|
|
||
| if (widget.showOverlay) { | ||
| if (_showOverlay) { | ||
| WidgetsBinding.instance.addPostFrameCallback((_) => showOverlay()); | ||
| } | ||
| widget.updateOverlay.call(_updateOverlay); | ||
| } | ||
|
|
||
| void _updateOverlay(bool showOverlay) { | ||
| _showOverlay = showOverlay; | ||
| buildOverlay(); | ||
| WidgetsBinding.instance.addPostFrameCallback((_) => syncWidgetAndOverlay()); | ||
| } | ||
|
|
||
| @override | ||
| void didUpdateWidget(OverlayBuilder oldWidget) { | ||
| super.didUpdateWidget(oldWidget); | ||
| WidgetsBinding.instance.addPostFrameCallback((_) => syncWidgetAndOverlay()); | ||
| WidgetsBinding.instance.addPostFrameCallback((_) => showOverlay()); | ||
| } | ||
|
|
||
| @override | ||
|
|
@@ -207,9 +128,9 @@ class _OverlayBuilderState extends State<OverlayBuilder> { | |
| } | ||
|
|
||
| void syncWidgetAndOverlay() { | ||
| if (isShowingOverlay() && !widget.showOverlay) { | ||
| if (isShowingOverlay() && !_showOverlay) { | ||
| hideOverlay(); | ||
| } else if (!isShowingOverlay() && widget.showOverlay) { | ||
| } else if (!isShowingOverlay() && _showOverlay) { | ||
| showOverlay(); | ||
| } | ||
| } | ||
|
|
@@ -221,8 +142,6 @@ class _OverlayBuilderState extends State<OverlayBuilder> { | |
|
|
||
| @override | ||
| Widget build(BuildContext context) { | ||
| buildOverlay(); | ||
|
|
||
| return widget.child!; | ||
| return widget.child; | ||
| } | ||
|
||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| import 'package:flutter/widgets.dart'; | ||
|
|
||
| /// This model is used to move linked showcase overlay data to parent | ||
| /// showcase to crop linked showcase rect | ||
| class LinkedShowcaseDataModel { | ||
| const LinkedShowcaseDataModel({ | ||
| required this.rect, | ||
| required this.radius, | ||
| required this.overlayPadding, | ||
| required this.isCircle, | ||
| }); | ||
|
|
||
| final Rect rect; | ||
| final EdgeInsets overlayPadding; | ||
| final BorderRadius? radius; | ||
| final bool isCircle; | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.