mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
The core RenderSliver protocol. (#7370)
This implements a new RenderViewport2 class to replace the existing RenderViewport class.
This commit is contained in:
parent
016b5ab0cc
commit
e82b18d47b
@ -44,6 +44,7 @@ export 'src/rendering/proxy_box.dart';
|
||||
export 'src/rendering/rotated_box.dart';
|
||||
export 'src/rendering/semantics.dart';
|
||||
export 'src/rendering/shifted_box.dart';
|
||||
export 'src/rendering/sliver.dart';
|
||||
export 'src/rendering/stack.dart';
|
||||
export 'src/rendering/table.dart';
|
||||
export 'src/rendering/tweens.dart';
|
||||
|
1805
packages/flutter/lib/src/rendering/sliver.dart
Normal file
1805
packages/flutter/lib/src/rendering/sliver.dart
Normal file
File diff suppressed because it is too large
Load Diff
@ -46,6 +46,13 @@ TestRenderingFlutterBinding get renderer {
|
||||
|
||||
/// Place the box in the render tree, at the given size and with the given
|
||||
/// alignment on the screen.
|
||||
///
|
||||
/// If you've updated `box` and want to lay it out again, use [pumpFrame].
|
||||
///
|
||||
/// Once a particular [RenderBox] has been passed to [layout], it cannot easily
|
||||
/// be put in a different place in the tree or passed to [layout] again, because
|
||||
/// [layout] places the given object into another [RenderBox] which you would
|
||||
/// need to unparent it from (but that box isn't itself made available).
|
||||
void layout(RenderBox box, {
|
||||
BoxConstraints constraints,
|
||||
FractionalOffset alignment: FractionalOffset.center,
|
||||
|
69
packages/flutter/test/rendering/slivers_layout_test.dart
Normal file
69
packages/flutter/test/rendering/slivers_layout_test.dart
Normal file
@ -0,0 +1,69 @@
|
||||
// Copyright 2015 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
import 'rendering_tester.dart';
|
||||
|
||||
int layouts = 0;
|
||||
|
||||
class RenderLayoutWatcher extends RenderProxyBox {
|
||||
RenderLayoutWatcher(RenderBox child) : super(child);
|
||||
@override
|
||||
void performLayout() {
|
||||
layouts += 1;
|
||||
super.performLayout();
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
test('RenderViewport2 basic test - impact of layout', () {
|
||||
RenderSliverToBoxAdapter sliver;
|
||||
RenderViewport2 viewport;
|
||||
RenderBox box;
|
||||
RenderObject root = new RenderLayoutWatcher(
|
||||
viewport = new RenderViewport2(
|
||||
children: <RenderSliver>[
|
||||
sliver = new RenderSliverToBoxAdapter(child: box = new RenderSizedBox(const Size(100.0, 400.0))),
|
||||
],
|
||||
),
|
||||
);
|
||||
expect(layouts, 0);
|
||||
layout(root);
|
||||
expect(layouts, 1);
|
||||
expect(box.localToGlobal(box.size.center(Point.origin)), const Point(400.0, 200.0));
|
||||
|
||||
sliver.child = box = new RenderSizedBox(const Size(100.0, 300.0));
|
||||
expect(layouts, 1);
|
||||
pumpFrame();
|
||||
expect(layouts, 1);
|
||||
expect(box.localToGlobal(box.size.center(Point.origin)), const Point(400.0, 150.0));
|
||||
|
||||
viewport.offset = new ViewportOffset.fixed(20.0);
|
||||
expect(layouts, 1);
|
||||
pumpFrame();
|
||||
expect(layouts, 1);
|
||||
expect(box.localToGlobal(box.size.center(Point.origin)), const Point(400.0, 130.0));
|
||||
|
||||
viewport.offset = new ViewportOffset.fixed(-20.0);
|
||||
expect(layouts, 1);
|
||||
pumpFrame();
|
||||
expect(layouts, 1);
|
||||
expect(box.localToGlobal(box.size.center(Point.origin)), const Point(400.0, 170.0));
|
||||
|
||||
viewport.anchor = 20.0 / 600.0;
|
||||
expect(layouts, 1);
|
||||
pumpFrame();
|
||||
expect(layouts, 1);
|
||||
expect(box.localToGlobal(box.size.center(Point.origin)), const Point(400.0, 190.0));
|
||||
|
||||
viewport.axisDirection = AxisDirection.up;
|
||||
expect(layouts, 1);
|
||||
pumpFrame();
|
||||
expect(layouts, 1);
|
||||
expect(box.localToGlobal(box.size.center(Point.origin)), const Point(400.0, 600.0 - 190.0));
|
||||
});
|
||||
|
||||
}
|
210
packages/flutter/test/rendering/slivers_test.dart
Normal file
210
packages/flutter/test/rendering/slivers_test.dart
Normal file
@ -0,0 +1,210 @@
|
||||
// Copyright 2015 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
import 'rendering_tester.dart';
|
||||
|
||||
void main() {
|
||||
test('RenderViewport2 basic test - down', () {
|
||||
RenderBox a, b, c, d, e;
|
||||
RenderViewport2 root = new RenderViewport2(
|
||||
children: <RenderSliver>[
|
||||
new RenderSliverToBoxAdapter(child: a = new RenderSizedBox(const Size(100.0, 400.0))),
|
||||
new RenderSliverToBoxAdapter(child: b = new RenderSizedBox(const Size(100.0, 400.0))),
|
||||
new RenderSliverToBoxAdapter(child: c = new RenderSizedBox(const Size(100.0, 400.0))),
|
||||
new RenderSliverToBoxAdapter(child: d = new RenderSizedBox(const Size(100.0, 400.0))),
|
||||
new RenderSliverToBoxAdapter(child: e = new RenderSizedBox(const Size(100.0, 400.0))),
|
||||
],
|
||||
);
|
||||
layout(root);
|
||||
|
||||
expect(root.size.width, equals(800.0));
|
||||
expect(root.size.height, equals(600.0));
|
||||
|
||||
expect(a.localToGlobal(const Point(0.0, 0.0)), const Point(0.0, 0.0));
|
||||
expect(b.localToGlobal(const Point(0.0, 0.0)), const Point(0.0, 400.0));
|
||||
expect(c.localToGlobal(const Point(0.0, 0.0)), const Point(0.0, 600.0));
|
||||
expect(d.localToGlobal(const Point(0.0, 0.0)), const Point(0.0, 600.0));
|
||||
expect(e.localToGlobal(const Point(0.0, 0.0)), const Point(0.0, 600.0));
|
||||
|
||||
root.offset = new ViewportOffset.fixed(200.0);
|
||||
pumpFrame();
|
||||
expect(a.localToGlobal(const Point(0.0, 0.0)), const Point(0.0, -200.0));
|
||||
expect(b.localToGlobal(const Point(0.0, 0.0)), const Point(0.0, 200.0));
|
||||
expect(c.localToGlobal(const Point(0.0, 0.0)), const Point(0.0, 600.0));
|
||||
expect(d.localToGlobal(const Point(0.0, 0.0)), const Point(0.0, 600.0));
|
||||
expect(e.localToGlobal(const Point(0.0, 0.0)), const Point(0.0, 600.0));
|
||||
|
||||
root.offset = new ViewportOffset.fixed(600.0);
|
||||
pumpFrame();
|
||||
expect(a.localToGlobal(const Point(0.0, 0.0)), const Point(0.0, -600.0));
|
||||
expect(b.localToGlobal(const Point(0.0, 0.0)), const Point(0.0, -200.0));
|
||||
expect(c.localToGlobal(const Point(0.0, 0.0)), const Point(0.0, 200.0));
|
||||
expect(d.localToGlobal(const Point(0.0, 0.0)), const Point(0.0, 600.0));
|
||||
expect(e.localToGlobal(const Point(0.0, 0.0)), const Point(0.0, 600.0));
|
||||
|
||||
root.offset = new ViewportOffset.fixed(900.0);
|
||||
pumpFrame();
|
||||
expect(a.localToGlobal(const Point(0.0, 0.0)), const Point(0.0, -900.0));
|
||||
expect(b.localToGlobal(const Point(0.0, 0.0)), const Point(0.0, -500.0));
|
||||
expect(c.localToGlobal(const Point(0.0, 0.0)), const Point(0.0, -100.0));
|
||||
expect(d.localToGlobal(const Point(0.0, 0.0)), const Point(0.0, 300.0));
|
||||
expect(e.localToGlobal(const Point(0.0, 0.0)), const Point(0.0, 600.0));
|
||||
});
|
||||
|
||||
test('RenderViewport2 basic test - up', () {
|
||||
RenderBox a, b, c, d, e;
|
||||
RenderViewport2 root = new RenderViewport2(
|
||||
axisDirection: AxisDirection.up,
|
||||
children: <RenderSliver>[
|
||||
new RenderSliverToBoxAdapter(child: a = new RenderSizedBox(const Size(100.0, 400.0))),
|
||||
new RenderSliverToBoxAdapter(child: b = new RenderSizedBox(const Size(100.0, 400.0))),
|
||||
new RenderSliverToBoxAdapter(child: c = new RenderSizedBox(const Size(100.0, 400.0))),
|
||||
new RenderSliverToBoxAdapter(child: d = new RenderSizedBox(const Size(100.0, 400.0))),
|
||||
new RenderSliverToBoxAdapter(child: e = new RenderSizedBox(const Size(100.0, 400.0))),
|
||||
],
|
||||
);
|
||||
layout(root);
|
||||
|
||||
expect(root.size.width, equals(800.0));
|
||||
expect(root.size.height, equals(600.0));
|
||||
|
||||
expect(a.localToGlobal(const Point(0.0, 0.0)), const Point(0.0, 200.0));
|
||||
expect(b.localToGlobal(const Point(0.0, 0.0)), const Point(0.0, -200.0));
|
||||
expect(c.localToGlobal(const Point(0.0, 0.0)), const Point(0.0, -400.0));
|
||||
expect(d.localToGlobal(const Point(0.0, 0.0)), const Point(0.0, -400.0));
|
||||
expect(e.localToGlobal(const Point(0.0, 0.0)), const Point(0.0, -400.0));
|
||||
|
||||
root.offset = new ViewportOffset.fixed(200.0);
|
||||
pumpFrame();
|
||||
expect(a.localToGlobal(const Point(0.0, 0.0)), const Point(0.0, 400.0));
|
||||
expect(b.localToGlobal(const Point(0.0, 0.0)), const Point(0.0, 0.0));
|
||||
expect(c.localToGlobal(const Point(0.0, 0.0)), const Point(0.0, -400.0));
|
||||
expect(d.localToGlobal(const Point(0.0, 0.0)), const Point(0.0, -400.0));
|
||||
expect(e.localToGlobal(const Point(0.0, 0.0)), const Point(0.0, -400.0));
|
||||
|
||||
root.offset = new ViewportOffset.fixed(600.0);
|
||||
pumpFrame();
|
||||
expect(a.localToGlobal(const Point(0.0, 0.0)), const Point(0.0, 800.0));
|
||||
expect(b.localToGlobal(const Point(0.0, 0.0)), const Point(0.0, 400.0));
|
||||
expect(c.localToGlobal(const Point(0.0, 0.0)), const Point(0.0, 0.0));
|
||||
expect(d.localToGlobal(const Point(0.0, 0.0)), const Point(0.0, -400.0));
|
||||
expect(e.localToGlobal(const Point(0.0, 0.0)), const Point(0.0, -400.0));
|
||||
|
||||
root.offset = new ViewportOffset.fixed(900.0);
|
||||
pumpFrame();
|
||||
expect(a.localToGlobal(const Point(0.0, 0.0)), const Point(0.0, 1100.0));
|
||||
expect(b.localToGlobal(const Point(0.0, 0.0)), const Point(0.0, 700.0));
|
||||
expect(c.localToGlobal(const Point(0.0, 0.0)), const Point(0.0, 300.0));
|
||||
expect(d.localToGlobal(const Point(0.0, 0.0)), const Point(0.0, -100.0));
|
||||
expect(e.localToGlobal(const Point(0.0, 0.0)), const Point(0.0, -400.0));
|
||||
});
|
||||
|
||||
test('RenderViewport2 basic test - right', () {
|
||||
RenderBox a, b, c, d, e;
|
||||
RenderViewport2 root = new RenderViewport2(
|
||||
axisDirection: AxisDirection.right,
|
||||
children: <RenderSliver>[
|
||||
new RenderSliverToBoxAdapter(child: a = new RenderSizedBox(const Size(400.0, 100.0))),
|
||||
new RenderSliverToBoxAdapter(child: b = new RenderSizedBox(const Size(400.0, 100.0))),
|
||||
new RenderSliverToBoxAdapter(child: c = new RenderSizedBox(const Size(400.0, 100.0))),
|
||||
new RenderSliverToBoxAdapter(child: d = new RenderSizedBox(const Size(400.0, 100.0))),
|
||||
new RenderSliverToBoxAdapter(child: e = new RenderSizedBox(const Size(400.0, 100.0))),
|
||||
],
|
||||
);
|
||||
layout(root);
|
||||
|
||||
expect(root.size.width, equals(800.0));
|
||||
expect(root.size.height, equals(600.0));
|
||||
|
||||
expect(a.localToGlobal(const Point(0.0, 0.0)), const Point(0.0, 0.0));
|
||||
expect(b.localToGlobal(const Point(0.0, 0.0)), const Point(400.0, 0.0));
|
||||
expect(c.localToGlobal(const Point(0.0, 0.0)), const Point(800.0, 0.0));
|
||||
expect(d.localToGlobal(const Point(0.0, 0.0)), const Point(800.0, 0.0));
|
||||
expect(e.localToGlobal(const Point(0.0, 0.0)), const Point(800.0, 0.0));
|
||||
|
||||
root.offset = new ViewportOffset.fixed(200.0);
|
||||
pumpFrame();
|
||||
expect(a.localToGlobal(const Point(0.0, 0.0)), const Point(-200.0, 0.0));
|
||||
expect(b.localToGlobal(const Point(0.0, 0.0)), const Point(200.0, 0.0));
|
||||
expect(c.localToGlobal(const Point(0.0, 0.0)), const Point(600.0, 0.0));
|
||||
expect(d.localToGlobal(const Point(0.0, 0.0)), const Point(800.0, 0.0));
|
||||
expect(e.localToGlobal(const Point(0.0, 0.0)), const Point(800.0, 0.0));
|
||||
|
||||
root.offset = new ViewportOffset.fixed(600.0);
|
||||
pumpFrame();
|
||||
expect(a.localToGlobal(const Point(0.0, 0.0)), const Point(-600.0, 0.0));
|
||||
expect(b.localToGlobal(const Point(0.0, 0.0)), const Point(-200.0, 0.0));
|
||||
expect(c.localToGlobal(const Point(0.0, 0.0)), const Point(200.0, 0.0));
|
||||
expect(d.localToGlobal(const Point(0.0, 0.0)), const Point(600.0, 0.0));
|
||||
expect(e.localToGlobal(const Point(0.0, 0.0)), const Point(800.0, 0.0));
|
||||
|
||||
root.offset = new ViewportOffset.fixed(900.0);
|
||||
pumpFrame();
|
||||
expect(a.localToGlobal(const Point(0.0, 0.0)), const Point(-900.0, 0.0));
|
||||
expect(b.localToGlobal(const Point(0.0, 0.0)), const Point(-500.0, 0.0));
|
||||
expect(c.localToGlobal(const Point(0.0, 0.0)), const Point(-100.0, 0.0));
|
||||
expect(d.localToGlobal(const Point(0.0, 0.0)), const Point(300.0, 0.0));
|
||||
expect(e.localToGlobal(const Point(0.0, 0.0)), const Point(700.0, 0.0));
|
||||
});
|
||||
|
||||
test('RenderViewport2 basic test - left', () {
|
||||
RenderBox a, b, c, d, e;
|
||||
RenderViewport2 root = new RenderViewport2(
|
||||
axisDirection: AxisDirection.left,
|
||||
children: <RenderSliver>[
|
||||
new RenderSliverToBoxAdapter(child: a = new RenderSizedBox(const Size(400.0, 100.0))),
|
||||
new RenderSliverToBoxAdapter(child: b = new RenderSizedBox(const Size(400.0, 100.0))),
|
||||
new RenderSliverToBoxAdapter(child: c = new RenderSizedBox(const Size(400.0, 100.0))),
|
||||
new RenderSliverToBoxAdapter(child: d = new RenderSizedBox(const Size(400.0, 100.0))),
|
||||
new RenderSliverToBoxAdapter(child: e = new RenderSizedBox(const Size(400.0, 100.0))),
|
||||
],
|
||||
);
|
||||
layout(root);
|
||||
|
||||
expect(root.size.width, equals(800.0));
|
||||
expect(root.size.height, equals(600.0));
|
||||
|
||||
expect(a.localToGlobal(const Point(0.0, 0.0)), const Point(400.0, 0.0));
|
||||
expect(b.localToGlobal(const Point(0.0, 0.0)), const Point(0.0, 0.0));
|
||||
expect(c.localToGlobal(const Point(0.0, 0.0)), const Point(-400.0, 0.0));
|
||||
expect(d.localToGlobal(const Point(0.0, 0.0)), const Point(-400.0, 0.0));
|
||||
expect(e.localToGlobal(const Point(0.0, 0.0)), const Point(-400.0, 0.0));
|
||||
|
||||
root.offset = new ViewportOffset.fixed(200.0);
|
||||
pumpFrame();
|
||||
expect(a.localToGlobal(const Point(0.0, 0.0)), const Point(600.0, 0.0));
|
||||
expect(b.localToGlobal(const Point(0.0, 0.0)), const Point(200.0, 0.0));
|
||||
expect(c.localToGlobal(const Point(0.0, 0.0)), const Point(-200.0, 0.0));
|
||||
expect(d.localToGlobal(const Point(0.0, 0.0)), const Point(-400.0, 0.0));
|
||||
expect(e.localToGlobal(const Point(0.0, 0.0)), const Point(-400.0, 0.0));
|
||||
|
||||
root.offset = new ViewportOffset.fixed(600.0);
|
||||
pumpFrame();
|
||||
expect(a.localToGlobal(const Point(0.0, 0.0)), const Point(1000.0, 0.0));
|
||||
expect(b.localToGlobal(const Point(0.0, 0.0)), const Point(600.0, 0.0));
|
||||
expect(c.localToGlobal(const Point(0.0, 0.0)), const Point(200.0, 0.0));
|
||||
expect(d.localToGlobal(const Point(0.0, 0.0)), const Point(-200.0, 0.0));
|
||||
expect(e.localToGlobal(const Point(0.0, 0.0)), const Point(-400.0, 0.0));
|
||||
|
||||
root.offset = new ViewportOffset.fixed(900.0);
|
||||
pumpFrame();
|
||||
expect(a.localToGlobal(const Point(0.0, 0.0)), const Point(1300.0, 0.0));
|
||||
expect(b.localToGlobal(const Point(0.0, 0.0)), const Point(900.0, 0.0));
|
||||
expect(c.localToGlobal(const Point(0.0, 0.0)), const Point(500.0, 0.0));
|
||||
expect(d.localToGlobal(const Point(0.0, 0.0)), const Point(100.0, 0.0));
|
||||
expect(e.localToGlobal(const Point(0.0, 0.0)), const Point(-300.0, 0.0));
|
||||
});
|
||||
|
||||
// TODO(ianh): test positioning when the children are too big to fit in the main axis
|
||||
// TODO(ianh): test shrinkWrap
|
||||
// TODO(ianh): test anchor
|
||||
// TODO(ianh): test offset
|
||||
// TODO(ianh): test center
|
||||
// TODO(ianh): test hit testing
|
||||
// TODO(ianh): test semantics
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user