Unverified Commit aa088501 authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

Return null from Layer.find when transform layer has a non-invertable transform (#18848)

parent 3ecd4301
...@@ -756,11 +756,12 @@ class TransformLayer extends OffsetLayer { ...@@ -756,11 +756,12 @@ class TransformLayer extends OffsetLayer {
if (value == _transform) if (value == _transform)
return; return;
_transform = value; _transform = value;
_invertedTransform = null; _inverseDirty = true;
} }
Matrix4 _lastEffectiveTransform; Matrix4 _lastEffectiveTransform;
Matrix4 _invertedTransform; Matrix4 _invertedTransform;
bool _inverseDirty = true;
@override @override
void addToScene(ui.SceneBuilder builder, Offset layerOffset) { void addToScene(ui.SceneBuilder builder, Offset layerOffset) {
...@@ -777,7 +778,12 @@ class TransformLayer extends OffsetLayer { ...@@ -777,7 +778,12 @@ class TransformLayer extends OffsetLayer {
@override @override
S find<S>(Offset regionOffset) { S find<S>(Offset regionOffset) {
_invertedTransform ??= new Matrix4.inverted(transform); if (_inverseDirty) {
_invertedTransform = Matrix4.tryInvert(transform);
_inverseDirty = false;
}
if (_invertedTransform == null)
return null;
final Vector4 vector = new Vector4(regionOffset.dx, regionOffset.dy, 0.0, 1.0); final Vector4 vector = new Vector4(regionOffset.dx, regionOffset.dy, 0.0, 1.0);
final Vector4 result = _invertedTransform.transform(vector); final Vector4 result = _invertedTransform.transform(vector);
return super.find<S>(new Offset(result[0], result[1])); return super.find<S>(new Offset(result[0], result[1]));
...@@ -1178,18 +1184,19 @@ class FollowerLayer extends ContainerLayer { ...@@ -1178,18 +1184,19 @@ class FollowerLayer extends ContainerLayer {
Offset _lastOffset; Offset _lastOffset;
Matrix4 _lastTransform; Matrix4 _lastTransform;
Matrix4 _invertedTransform; Matrix4 _invertedTransform;
bool _inverseDirty = true;
@override @override
S find<S>(Offset regionOffset) { S find<S>(Offset regionOffset) {
if (link.leader == null) { if (link.leader == null) {
return showWhenUnlinked ? super.find<S>(regionOffset - unlinkedOffset) : null; return showWhenUnlinked ? super.find<S>(regionOffset - unlinkedOffset) : null;
} }
if (_invertedTransform == null) { if (_inverseDirty) {
final Matrix4 transform = getLastTransform(); _invertedTransform = Matrix4.tryInvert(getLastTransform());
assert(transform != null); _inverseDirty = false;
_invertedTransform = new Matrix4.zero();
transform.copyInverse(_invertedTransform);
} }
if (_invertedTransform == null)
return null;
final Vector4 vector = new Vector4(regionOffset.dx, regionOffset.dy, 0.0, 1.0); final Vector4 vector = new Vector4(regionOffset.dx, regionOffset.dy, 0.0, 1.0);
final Vector4 result = _invertedTransform.transform(vector); final Vector4 result = _invertedTransform.transform(vector);
return super.find<S>(new Offset(result[0] - linkedOffset.dx, result[1] - linkedOffset.dy)); return super.find<S>(new Offset(result[0] - linkedOffset.dx, result[1] - linkedOffset.dy));
...@@ -1269,6 +1276,7 @@ class FollowerLayer extends ContainerLayer { ...@@ -1269,6 +1276,7 @@ class FollowerLayer extends ContainerLayer {
inverseTransform.multiply(forwardTransform); inverseTransform.multiply(forwardTransform);
inverseTransform.translate(linkedOffset.dx, linkedOffset.dy); inverseTransform.translate(linkedOffset.dx, linkedOffset.dy);
_lastTransform = inverseTransform; _lastTransform = inverseTransform;
_inverseDirty = true;
} }
@override @override
...@@ -1278,6 +1286,7 @@ class FollowerLayer extends ContainerLayer { ...@@ -1278,6 +1286,7 @@ class FollowerLayer extends ContainerLayer {
if (link.leader == null && !showWhenUnlinked) { if (link.leader == null && !showWhenUnlinked) {
_lastTransform = null; _lastTransform = null;
_lastOffset = null; _lastOffset = null;
_inverseDirty = true;
return; return;
} }
_establishTransform(); _establishTransform();
...@@ -1290,6 +1299,7 @@ class FollowerLayer extends ContainerLayer { ...@@ -1290,6 +1299,7 @@ class FollowerLayer extends ContainerLayer {
_lastOffset = null; _lastOffset = null;
addChildrenToScene(builder, unlinkedOffset + layerOffset); addChildrenToScene(builder, unlinkedOffset + layerOffset);
} }
_inverseDirty = true;
} }
@override @override
......
...@@ -123,6 +123,18 @@ void main() { ...@@ -123,6 +123,18 @@ void main() {
expect(layer.find<int>(const Offset(100.0, 100.0)), 1); expect(layer.find<int>(const Offset(100.0, 100.0)), 1);
}); });
test('handles non-invertable transforms', () {
final AnnotatedRegionLayer<int> child = new AnnotatedRegionLayer<int>(1);
final TransformLayer parent = new TransformLayer(transform: new Matrix4.diagonal3Values(0.0, 1.0, 1.0));
parent.append(child);
expect(parent.find<int>(const Offset(0.0, 0.0)), null);
parent.transform = new Matrix4.diagonal3Values(1.0, 1.0, 1.0);
expect(parent.find<int>(const Offset(0.0, 0.0)), 1);
});
}); });
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment