-
Notifications
You must be signed in to change notification settings - Fork 28.7k
Add transform flip #116705
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
Add transform flip #116705
Conversation
Great first PR, @saminarp!! 👏 👏 👏 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just some nits and questions/discussions here before I approve.
I think I'm on board with adding this constructor, it makes sense to me to have a simple way to do this.
this.transformHitTests = true, | ||
this.filterQuality, | ||
super.child, | ||
}) : transform = Matrix4.diagonal3Values(flipX ? -1.0 : 1.0, flipY ? -1.0 : 1.0, flipX ^ flipY ? -1.0 : 1.0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think my gut says this is ok as-is, but I think we should discuss: What if we added an assert enforcing that flipX and flipY can't both be false?
On one hand it's somewhat confusing to have a widget called Transform.flip
that doesn't flip anything. Users may try it without knowing about flipX/flipY and be confused that nothing flips.
On the other hand, it may be convenient to be able to use a Transform.flip that flips based on some state without having to exclude it from the widget tree.
What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could use a List and fill it with the axes needed, empty list would mean no flip, but there would need to be a list and we could assert that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rereading this now, I think the best option is probably to keep it as-is.
I think a list is going to have the same problem by defaulting to an empty list plus more possibilities for invalid configuration.
We could default flipX and flipY to true, but I think it's okay to trust the user here and default them to false.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree: I don't think we should assert here, precisely because it might be used in a situation where two variables are both false, and the suggestion to use a List would make it more complicated than it needs to be.
bool flipX = false, | ||
bool flipY = false, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another thing to think about: Is there a better way to represent this? For example, an enum with values like x, y, both, and none. Kind of similar to Axis.
I'm not saying that flipX/flipY aren't the best way to do this already, just starting a discussion again.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think two bools here is probably fine, given that it's a specialized constructor already. I can't think of any other ways that "flip" might be interpreted here, unless we also want to incorporate 90 degree rotations (which I don't think we do), and making it an enum makes it harder to write a call to the constructor using a boolean (which is probably the main use case here).
|
||
await tester.tapAt(topRight); | ||
|
||
expect(tappedRed, true, reason: 'Transform.flip cannot flipX'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"true" => "isTrue"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have just done this in my recent commit
this.transformHitTests = true, | ||
this.filterQuality, | ||
super.child, | ||
}) : transform = Matrix4.diagonal3Values(flipX ? -1.0 : 1.0, flipY ? -1.0 : 1.0, flipX ^ flipY ? -1.0 : 1.0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What effect does the -1 z value have?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah I see, ok let's keep it 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You shouldn't need to supply -1 in Z, you're just doing a 2D flip. I'd just always set it to 1.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Making Z constant to reduce unnecessary computation 👍
@@ -786,6 +786,101 @@ void main() { | |||
|
|||
expect(tester.getBottomRight(find.byType(Container)), target.bottomRight(tester.getTopLeft(find.byType(Container)))); | |||
}); | |||
|
|||
testWidgets( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: I would usually turn this test into a group
and then turn each pumpWidget
below into a separate test. That way you give each feature tested a chance to fail during one run and give a bit more info. Up to you if you think it's useful or not here, though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just bumping this to make sure you saw it, though it's fine if you want to keep it as-is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's keep it as-is.
|
||
expect( | ||
tappedRed, | ||
true, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: One small thing that might make this test somewhat fragile is that we're always expecting tappedRed to be true, so this test would pass for a big gesture detector that didn't flip at all. It would be more reassuring if you could test that the tap did not cause tappedRed to become true when nothing is flipped. Maybe do something like test that tapping topRight, bottomLeft, and bottomRight don't set tappedRed to true when there is no flip?
Up to you though, maybe it's not worth it to add that complexity.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am a little behind schedule in a few of my college assignments. So, in my opinion, it is not worth adding the complexity at this time.
Let me know your thoughts :)
Thank you so much! |
This pull request executed golden file tests, but it has not been updated in a while (20+ days). Test results from Gold expire after as many days, so this pull request will need to be updated with a fresh commit in order to get results from Gold. For more guidance, visit Writing a golden file test for Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 👍 assuming that the tests pass.
I restarted a few that were canceled, but it seems like you'll need to push a new commit to get the gold tests to re-run. Can you push a merge commit?
CC @gspencergoog for secondary review
this.transformHitTests = true, | ||
this.filterQuality, | ||
super.child, | ||
}) : transform = Matrix4.diagonal3Values(flipX ? -1.0 : 1.0, flipY ? -1.0 : 1.0, flipX ^ flipY ? -1.0 : 1.0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rereading this now, I think the best option is probably to keep it as-is.
I think a list is going to have the same problem by defaulting to an empty list plus more possibilities for invalid configuration.
We could default flipX and flipY to true, but I think it's okay to trust the user here and default them to false.
this.transformHitTests = true, | ||
this.filterQuality, | ||
super.child, | ||
}) : transform = Matrix4.diagonal3Values(flipX ? -1.0 : 1.0, flipY ? -1.0 : 1.0, flipX ^ flipY ? -1.0 : 1.0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah I see, ok let's keep it 👍
@@ -786,6 +786,101 @@ void main() { | |||
|
|||
expect(tester.getBottomRight(find.byType(Container)), target.bottomRight(tester.getTopLeft(find.byType(Container)))); | |||
}); | |||
|
|||
testWidgets( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just bumping this to make sure you saw it, though it's fine if you want to keep it as-is.
bool flipX = false, | ||
bool flipY = false, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think two bools here is probably fine, given that it's a specialized constructor already. I can't think of any other ways that "flip" might be interpreted here, unless we also want to incorporate 90 degree rotations (which I don't think we do), and making it an enum makes it harder to write a call to the constructor using a boolean (which is probably the main use case here).
/// | ||
/// If `flipY` is true, the child widget will be flipped vertically. Defaults to false. | ||
/// | ||
/// If both are true, the child widget will be flipped both vertically and horizontally. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You might mention that flipping it in both is equivalent to a 180 degree rotation.
/// If both are true, the child widget will be flipped both vertically and horizontally. | ||
/// | ||
/// The [alignment] controls the origin of the flip; by default, this is | ||
/// the center of the box. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens if the alignment is Alignment.upperLeft
and both are flipped? Does it just draw nothing? Or does it draw outside of its bounding box?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, the more I think about it, isn't any alignment other than center
going to draw nothing, or draw outside of its bounding box as long as one flip is true? That seems undesirable, since both are surprising.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It draws outside the bounding box if alignment is something other than center
. Being restrictive, we could just fix the alignment to Alignment.center
and not provide the option to change it at all. But allowing it may help someone desiring the undesirable results. But they could also do it using the main Transform()
constructor. But again, the purpose of this flip
constructor is to just simplify and be descriptive of what is being done. What do you prefer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In that case, I think I'd prefer if we just eliminate the alignment
argument altogether and just fix it at Alignment.center. It's surprising to have it draw outside of its bounding box, and if they want to do that, they can do it using the main constructor. We can always add it later if a compelling use case arises.
5795ac7
to
20eee94
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
auto label is removed for flutter/flutter, pr: 116705, due to - The status or check suite Windows build_tests_3_3 has failed. Please fix the issues identified (or deflake) before re-applying this label. |
Co-authored-by: Greg Spencer <[email protected]>
b64e742
to
94cf825
Compare
@gspencergoog Can you add the label again? It was removed and now all is green. |
* 8065887 Add transform flip (flutter/flutter#116705) * 68b6e72 406dce64f Roll Fuchsia Mac SDK from ZTKDeVL1HDAwsZdhl... to l7jVM3Urw73TVWfee... (flutter/engine#39050) (flutter/flutter#118964) * cf628ad aa194347a Roll Fuchsia Linux SDK from S6wQW1tLFe-YnReaZ... to l3c_b-vRr-o6ZFX_M... (flutter/engine#39055) (flutter/flutter#118968) * f33e8d3 2a2dfaafb Roll Fuchsia Mac SDK from l7jVM3Urw73TVWfee... to 5TQ9IL4-Yu3KHCR-H... (flutter/engine#39056) (flutter/flutter#118969)
* 3c769ef Cupertino navbar ellipsis fix (flutter/flutter#118841) * d1be731 3fead63ba Roll Dart SDK from ac4c63168ff2 to 03d35455a8d8 (1 revision) (flutter/engine#39036) (flutter/flutter#118909) * c0ad6ad Marks Mac plugin_test_macos to be unflaky (flutter/flutter#118706) * 8372001 Remove unnecessary null checks in flutter_test (flutter/flutter#118865) * 288a773 Remove unnecessary null checks in flutter_driver (flutter/flutter#118864) * bb73121 Remove unnecessary null checks in flutter/test (flutter/flutter#118905) * 15bc4e4 Marks Mac_android microbenchmarks to be flaky (flutter/flutter#118693) * 1cdaf9e e2c2e5009 [impeller] correct input order in ColorFilterContents::MakeBlend (flutter/engine#39038) (flutter/flutter#118913) * 49e025d Update android defines test to use emulator (flutter/flutter#118808) * bae4c1d Revert "Update android defines test to use emulator (#118808)" (flutter/flutter#118928) * 9837eb6 Remove unnecessary null checks in flutter/rendering (flutter/flutter#118923) * 25843bd Remove macOS impeller benchmarks (flutter/flutter#118917) * 70cecf6 Remove unnecessary null checks in dev/*_tests (flutter/flutter#118844) * c757df3 Remove unnecessary null checks in dev/bots (flutter/flutter#118846) * 5d74b5c Remove unnecessary null checks in flutter/painting (flutter/flutter#118925) * 7272c80 Remove unnecessary null checks in `flutter/{animation,semantics,scheduler}` (flutter/flutter#118922) * 2baea2f 7b68d71b8 Roll Dart SDK from 03d35455a8d8 to 807077cc5d1b (1 revision) (flutter/engine#39042) (flutter/flutter#118933) * 8d60a8c Roll Flutter Engine from 7b68d71b8d03 to 3a444b36657c (3 revisions) (flutter/flutter#118938) * 5ccdb81 bb4e8dfe2 Roll Fuchsia Linux SDK from rPo4_TYHCtkoOfRup... to S6wQW1tLFe-YnReaZ... (flutter/engine#39048) (flutter/flutter#118942) * b1f4070 ef7b1856a Roll Dart SDK from 8c2eb20b5376 to 548678dd684c (1 revision) (flutter/engine#39049) (flutter/flutter#118944) * 8065887 Add transform flip (flutter/flutter#116705) * 68b6e72 406dce64f Roll Fuchsia Mac SDK from ZTKDeVL1HDAwsZdhl... to l7jVM3Urw73TVWfee... (flutter/engine#39050) (flutter/flutter#118964) * cf628ad aa194347a Roll Fuchsia Linux SDK from S6wQW1tLFe-YnReaZ... to l3c_b-vRr-o6ZFX_M... (flutter/engine#39055) (flutter/flutter#118968) * f33e8d3 2a2dfaafb Roll Fuchsia Mac SDK from l7jVM3Urw73TVWfee... to 5TQ9IL4-Yu3KHCR-H... (flutter/engine#39056) (flutter/flutter#118969)
* 3c769ef Cupertino navbar ellipsis fix (flutter/flutter#118841) * d1be731 3fead63ba Roll Dart SDK from ac4c63168ff2 to 03d35455a8d8 (1 revision) (flutter/engine#39036) (flutter/flutter#118909) * c0ad6ad Marks Mac plugin_test_macos to be unflaky (flutter/flutter#118706) * 8372001 Remove unnecessary null checks in flutter_test (flutter/flutter#118865) * 288a773 Remove unnecessary null checks in flutter_driver (flutter/flutter#118864) * bb73121 Remove unnecessary null checks in flutter/test (flutter/flutter#118905) * 15bc4e4 Marks Mac_android microbenchmarks to be flaky (flutter/flutter#118693) * 1cdaf9e e2c2e5009 [impeller] correct input order in ColorFilterContents::MakeBlend (flutter/engine#39038) (flutter/flutter#118913) * 49e025d Update android defines test to use emulator (flutter/flutter#118808) * bae4c1d Revert "Update android defines test to use emulator (#118808)" (flutter/flutter#118928) * 9837eb6 Remove unnecessary null checks in flutter/rendering (flutter/flutter#118923) * 25843bd Remove macOS impeller benchmarks (flutter/flutter#118917) * 70cecf6 Remove unnecessary null checks in dev/*_tests (flutter/flutter#118844) * c757df3 Remove unnecessary null checks in dev/bots (flutter/flutter#118846) * 5d74b5c Remove unnecessary null checks in flutter/painting (flutter/flutter#118925) * 7272c80 Remove unnecessary null checks in `flutter/{animation,semantics,scheduler}` (flutter/flutter#118922) * 2baea2f 7b68d71b8 Roll Dart SDK from 03d35455a8d8 to 807077cc5d1b (1 revision) (flutter/engine#39042) (flutter/flutter#118933) * 8d60a8c Roll Flutter Engine from 7b68d71b8d03 to 3a444b36657c (3 revisions) (flutter/flutter#118938) * 5ccdb81 bb4e8dfe2 Roll Fuchsia Linux SDK from rPo4_TYHCtkoOfRup... to S6wQW1tLFe-YnReaZ... (flutter/engine#39048) (flutter/flutter#118942) * b1f4070 ef7b1856a Roll Dart SDK from 8c2eb20b5376 to 548678dd684c (1 revision) (flutter/engine#39049) (flutter/flutter#118944) * 8065887 Add transform flip (flutter/flutter#116705) * 68b6e72 406dce64f Roll Fuchsia Mac SDK from ZTKDeVL1HDAwsZdhl... to l7jVM3Urw73TVWfee... (flutter/engine#39050) (flutter/flutter#118964) * cf628ad aa194347a Roll Fuchsia Linux SDK from S6wQW1tLFe-YnReaZ... to l3c_b-vRr-o6ZFX_M... (flutter/engine#39055) (flutter/flutter#118968) * f33e8d3 2a2dfaafb Roll Fuchsia Mac SDK from l7jVM3Urw73TVWfee... to 5TQ9IL4-Yu3KHCR-H... (flutter/engine#39056) (flutter/flutter#118969)
Adds Transform.flip to allow flipping/mirroring child widgets
Fixes #116702
Pre-launch Checklist
///
).