move getTransformTo method from RenderBox to RenderObject. (#10430)

* move getTransformTo method from RenderBox to RenderObject.

* Cleanup comment. Add slivers test.
This commit is contained in:
Jacob Richman 2017-06-16 23:54:27 -07:00 committed by Ian Hickson
parent b2909a245a
commit 28fd54c116
3 changed files with 67 additions and 29 deletions

View file

@ -11,7 +11,6 @@ import 'package:flutter/gestures.dart';
import 'package:vector_math/vector_math_64.dart';
import 'debug.dart';
import 'node.dart';
import 'object.dart';
// This class should only be used in debug builds.
@ -1860,34 +1859,6 @@ abstract class RenderBox extends RenderObject {
transform.translate(offset.dx, offset.dy);
}
/// Returns a matrix that maps the local coordinate system to the coordinate
/// system of `ancestor`.
///
/// If `ancestor` is null, this method returns a matrix that maps from the
/// local coordinate system to the coordinate system of the
/// [PipelineOwner.rootNode]. For the render tree owner by the
/// [RendererBinding] (i.e. for the main render tree displayed on the device)
/// this means that this method maps to the global coordinate system in
/// logical pixels. To get physical pixels, use [applyPaintTransform] from the
/// [RenderView] to further transform the coordinate.
Matrix4 getTransformTo(RenderObject ancestor) {
assert(attached);
if (ancestor == null) {
final AbstractNode rootNode = owner.rootNode;
if (rootNode is RenderObject)
ancestor = rootNode;
}
final List<RenderObject> renderers = <RenderObject>[];
for (RenderObject renderer = this; renderer != ancestor; renderer = renderer.parent) {
assert(renderer != null); // Failed to find ancestor in parent chain.
renderers.add(renderer);
}
final Matrix4 transform = new Matrix4.identity();
for (int index = renderers.length - 1; index > 0; index -= 1)
renderers[index].applyPaintTransform(renderers[index - 1], transform);
return transform;
}
/// Convert the given point from the global coodinate system in logical pixels
/// to the local coordinate system for this box.
///

View file

@ -2312,6 +2312,37 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
assert(child.parent == this);
}
/// Applies the paint transform up the tree to `ancestor`.
///
/// Returns a matrix that maps the local paint coordinate system to the
/// coordinate system of `ancestor`.
///
/// If `ancestor` is null, this method returns a matrix that maps from the
/// local paint coordinate system to the coordinate system of the
/// [PipelineOwner.rootNode]. For the render tree owner by the
/// [RendererBinding] (i.e. for the main render tree displayed on the device)
/// this means that this method maps to the global coordinate system in
/// logical pixels. To get physical pixels, use [applyPaintTransform] from the
/// [RenderView] to further transform the coordinate.
Matrix4 getTransformTo(RenderObject ancestor) {
assert(attached);
if (ancestor == null) {
final AbstractNode rootNode = owner.rootNode;
if (rootNode is RenderObject)
ancestor = rootNode;
}
final List<RenderObject> renderers = <RenderObject>[];
for (RenderObject renderer = this; renderer != ancestor; renderer = renderer.parent) {
assert(renderer != null); // Failed to find ancestor in parent chain.
renderers.add(renderer);
}
final Matrix4 transform = new Matrix4.identity();
for (int index = renderers.length - 1; index > 0; index -= 1)
renderers[index].applyPaintTransform(renderers[index - 1], transform);
return transform;
}
/// Returns a rect in this object's coordinate system that describes
/// the approximate bounding box of the clip rect that would be
/// applied to the given child during the paint phase, if any.

View file

@ -4,6 +4,7 @@
import 'package:flutter/rendering.dart';
import 'package:test/test.dart';
import 'package:vector_math/vector_math_64.dart';
import 'rendering_tester.dart';
@ -128,6 +129,11 @@ void main() {
expect(result.path.first.target, equals(c));
});
Offset _getPaintOrigin(RenderObject render) {
final Vector3 transformed3 = render.getTransformTo(null).perspectiveTransform(new Vector3(0.0, 0.0, 0.0));
return new Offset(transformed3.x, transformed3.y);
}
test('RenderViewport basic test - right', () {
RenderBox a, b, c, d, e;
final RenderViewport root = new RenderViewport(
@ -146,12 +152,24 @@ void main() {
expect(root.size.width, equals(800.0));
expect(root.size.height, equals(600.0));
final RenderSliver sliverA = a.parent;
final RenderSliver sliverB = b.parent;
final RenderSliver sliverC = c.parent;
final RenderSliver sliverD = d.parent;
final RenderSliver sliverE = e.parent;
expect(a.localToGlobal(const Offset(0.0, 0.0)), const Offset(0.0, 0.0));
expect(b.localToGlobal(const Offset(0.0, 0.0)), const Offset(400.0, 0.0));
expect(c.localToGlobal(const Offset(0.0, 0.0)), const Offset(800.0, 0.0));
expect(d.localToGlobal(const Offset(0.0, 0.0)), const Offset(800.0, 0.0));
expect(e.localToGlobal(const Offset(0.0, 0.0)), const Offset(800.0, 0.0));
expect(_getPaintOrigin(sliverA), const Offset(0.0, 0.0));
expect(_getPaintOrigin(sliverB), const Offset(400.0, 0.0));
expect(_getPaintOrigin(sliverC), const Offset(800.0, 0.0));
expect(_getPaintOrigin(sliverD), const Offset(800.0, 0.0));
expect(_getPaintOrigin(sliverE), const Offset(800.0, 0.0));
root.offset = new ViewportOffset.fixed(200.0);
pumpFrame();
expect(a.localToGlobal(const Offset(0.0, 0.0)), const Offset(-200.0, 0.0));
@ -160,6 +178,12 @@ void main() {
expect(d.localToGlobal(const Offset(0.0, 0.0)), const Offset(800.0, 0.0));
expect(e.localToGlobal(const Offset(0.0, 0.0)), const Offset(800.0, 0.0));
expect(_getPaintOrigin(sliverA), const Offset(000.0, 0.0));
expect(_getPaintOrigin(sliverB), const Offset(200.0, 0.0));
expect(_getPaintOrigin(sliverC), const Offset(600.0, 0.0));
expect(_getPaintOrigin(sliverD), const Offset(800.0, 0.0));
expect(_getPaintOrigin(sliverE), const Offset(800.0, 0.0));
root.offset = new ViewportOffset.fixed(600.0);
pumpFrame();
expect(a.localToGlobal(const Offset(0.0, 0.0)), const Offset(-600.0, 0.0));
@ -168,6 +192,12 @@ void main() {
expect(d.localToGlobal(const Offset(0.0, 0.0)), const Offset(600.0, 0.0));
expect(e.localToGlobal(const Offset(0.0, 0.0)), const Offset(800.0, 0.0));
expect(_getPaintOrigin(sliverA), const Offset(000.0, 0.0));
expect(_getPaintOrigin(sliverB), const Offset(000.0, 0.0));
expect(_getPaintOrigin(sliverC), const Offset(200.0, 0.0));
expect(_getPaintOrigin(sliverD), const Offset(600.0, 0.0));
expect(_getPaintOrigin(sliverE), const Offset(800.0, 0.0));
root.offset = new ViewportOffset.fixed(900.0);
pumpFrame();
expect(a.localToGlobal(const Offset(0.0, 0.0)), const Offset(-900.0, 0.0));
@ -176,6 +206,12 @@ void main() {
expect(d.localToGlobal(const Offset(0.0, 0.0)), const Offset(300.0, 0.0));
expect(e.localToGlobal(const Offset(0.0, 0.0)), const Offset(700.0, 0.0));
expect(_getPaintOrigin(sliverA), const Offset(000.0, 0.0));
expect(_getPaintOrigin(sliverB), const Offset(000.0, 0.0));
expect(_getPaintOrigin(sliverC), const Offset(000.0, 0.0));
expect(_getPaintOrigin(sliverD), const Offset(300.0, 0.0));
expect(_getPaintOrigin(sliverE), const Offset(700.0, 0.0));
final HitTestResult result = new HitTestResult();
root.hitTest(result, position: const Offset(150.0, 450.0));
expect(result.path.first.target, equals(c));