Conversation
|
It looks like this pull request may not have tests. Please make sure to add tests before merging. While there are exceptions to this rule, if this patch modifies code it is probably not an exception. Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing. |
4a9fef5 to
346bd20
Compare
346bd20 to
2cc3813
Compare
0afdd9d to
5d534ee
Compare
d1abc7b to
96e9f0c
Compare
88e574e to
4f75892
Compare
867363b to
45fd739
Compare
171b77a to
d5ddf75
Compare
3c16d3d to
904447f
Compare
|
@HansMuller @LongCatIsLooong Ready for re-review. I've renamed to CupertinoContextMenu, changed One question I had: Is there a callback type that I can reuse instead of defining the PreviewBuilder and _PreviewBuilderChildless types ? |
HansMuller
left a comment
There was a problem hiding this comment.
This looks good; just some small feedback plus: need to document/test ModalRoute.filter
| /// A function that produces the preview when the CupertinoContextMenu is open. | ||
| /// | ||
| /// Called every time the animation value changes. | ||
| typedef PreviewBuilder = Widget Function( |
There was a problem hiding this comment.
This should have a name that's a little more specific because inadvertant collisions. Maybe ContextMenuPreviewBuilder
| /// Widget build(BuildContext context) { | ||
| /// return Scaffold( | ||
| /// key: scaffoldKey, | ||
| /// body: Center( |
There was a problem hiding this comment.
My mistake, what you had is fine.
| /// The widget that can be "opened" with the [CupertinoContextMenu]. | ||
| /// | ||
| /// When the [CupertinoContextMenu] is long-pressed, the menu will open and | ||
| /// this widget (or the widget returned by [previewBuilder], if provided) will |
There was a problem hiding this comment.
I think this may be revealing a detail that's not important: that the child/previewBuilder will be moved to the overlay. Can we explain what it means to "open" the menu just in terms of the route we're going to push? That approach jibes with using Navigator.pop() to close the menu.
|
|
||
| /// The actions that are shown in the menu. | ||
| /// | ||
| /// This parameter cannot be null, and items in the List must be |
| /// sharp corners when in the page. | ||
| /// | ||
| /// In addition to the current [BuildContext], the function is also called | ||
| /// with an [Animation] and the [child]. The animation is used internally to |
There was a problem hiding this comment.
instead of "is used internally", you could explain that the animation goes from 0-1 when the menu opens, 1-0 when it closes.
| /// // it's closed. It uses the given animation to animate the corners | ||
| /// // in sync with the opening animation. | ||
| /// child: ClipRRect( | ||
| /// borderRadius: BorderRadius.circular(64.0 * animation.value), |
| // child in the screen. | ||
| _ContextMenuOrientation get _contextMenuOrientation { | ||
| final Rect childRect = _getRect(_childGlobalKey); | ||
| final double screenWidth = MediaQuery.of(context).size.width; |
There was a problem hiding this comment.
What's the answer here?
|
|
||
| // A floating copy of the CupertinoContextMenu's child. | ||
| // | ||
| // When the child is pressed, but before the CupertinoContextMenu opens, it does |
There was a problem hiding this comment.
Thanks for the explanation!
| }) : _filter = filter, | ||
| super(settings: settings); | ||
|
|
||
| final ui.ImageFilter _filter; |
There was a problem hiding this comment.
Doc needed
This new route feature should also get its own test.
There was a problem hiding this comment.
I added a test to check that CupertinoContextMenu is able to add a BackdropFilter using this filter param, which was easiest since ModalRoute is abstract. Let me know if you had something else in mind.
| /// Below is an example of using `previewBuilder` to show an image tile that's | ||
| /// similar to each tile in the iOS iPhoto app's context menu. Several of | ||
| /// these could be used in a GridView for a similar effect. | ||
|
|
There was a problem hiding this comment.
| /// |
|
|
||
| class _CupertinoContextMenuState extends State<CupertinoContextMenu> with TickerProviderStateMixin { | ||
| final GlobalKey _childGlobalKey = GlobalKey(); | ||
| double _childOpacity = 1.0; |
There was a problem hiding this comment.
I wonder if we can use an Offstage and a TickerMode instead, like the Hero widget does?
There was a problem hiding this comment.
I'm trying this out.
Actually @goderbauer I got this code from you awhile back. I was asking about animating to a final laid out state, and you suggested rendering the first frame offstage and sent me this gist: https://gist.github.com/goderbauer/b136e871fac33960dbd539ea1930ff97
Any idea if there is an advantage to Offstage and TickerMode instead?
There was a problem hiding this comment.
Ah I think it's because PopupRoute is already using Offstage internally, and so this widget is just managing the offstage variable.
There was a problem hiding this comment.
What I originally meant was to use Offstage + TickerMode to hide the original child instead of Opacity. Should we stop the animation in the original child when it's hidden, by adding a TickerMode parent? As for Offstage vs Opacity they seem interchangeable?
There was a problem hiding this comment.
Oh I see, sorry! That makes more sense and is probably more performant. I'll change it.
There was a problem hiding this comment.
Actually after changing it something broke. I was getting the size of the Opacity widget using a GlobalKey, and I couldn't do that with an Offstage widget (even when it was onstage). It gave me weird values and broke the tests.
My compromise is to use a TickerMode and an Opacity widget together, but let me know if you know why getting the size wasn't working.
| /// | ||
| /// This parameter cannot be null, and items in the List must be | ||
| /// [CupertinoContextMenuAction]s. | ||
| final List<CupertinoContextMenuAction> actions; |
There was a problem hiding this comment.
Might have overlooked something, but CupertinoContextMenu's implementation does not seem to make use of the fact that actions are CupertinoContextMenuActions. Is it possible to relax the type constraint to List<Widget>? According to the sketch file the actions can be grouped, and group separators look quite different from regular ones, so I wonder if we can make this a list of Widgets.
There was a problem hiding this comment.
Yeah there is nothing preventing us from using List<Widget> here. I did it just to encourage users to always use CupertinoContextMenuActions, but I also didn't realize there were group separators. Does Flutter usually allow any type of widget when it can?
There was a problem hiding this comment.
There's an issue for this: #12078. Also I tried adding a context menu to a UISegmentedControl, and it turns out other than group separators there can also be headers (similar to action sheet headers)
There was a problem hiding this comment.
If that's more in line with how we usually do it then changing it sounds good to me.
There was a problem hiding this comment.
Oh sorry I posted my last comment before Github updated to show yours. That issue definitely confirms that this should be agnostic so I'm changing it now 👍
| flex: 2, | ||
| child: IntrinsicHeight( | ||
| child: ClipRRect( | ||
| borderRadius: BorderRadius.circular(16.0), |
There was a problem hiding this comment.
Per xcode the value is 13.
Codecov Report
@@ Coverage Diff @@
## master #37778 +/- ##
==========================================
- Coverage 61.77% 61.62% -0.15%
==========================================
Files 199 195 -4
Lines 19276 19016 -260
==========================================
- Hits 11907 11718 -189
+ Misses 7369 7298 -71
Continue to review full report at Codecov.
|
| final Widget child; | ||
|
|
||
| /// The actions that are shown in the menu. | ||
| /// |
There was a problem hiding this comment.
This would be a good place to say that typically the actions are [CupertinoContextMenuAction]s.
|
Closing in favor of: #43918 |
Description
This PR implements the
ContextMenuwidget.Related Issues
Closes #34728
Tests