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

This commit is contained in:
Jonah Williams 2018-06-26 18:59:32 -07:00 committed by GitHub
parent 3ecd4301bf
commit aa088501a5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 29 additions and 7 deletions

View File

@ -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 {
@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 {
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 {
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 {
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 {
_lastOffset = null; _lastOffset = null;
addChildrenToScene(builder, unlinkedOffset + layerOffset); addChildrenToScene(builder, unlinkedOffset + layerOffset);
} }
_inverseDirty = true;
} }
@override @override

View File

@ -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);
});
}); });
} }