Commit a0338203 authored by Ian Hickson's avatar Ian Hickson

Merge pull request #1164 from Hixie/AnimatedPositioned

AnimatedPositioned
parents 682243ef 63c2ac9c
...@@ -1023,15 +1023,15 @@ class Positioned extends ParentDataWidget<StackRenderObjectWidgetBase> { ...@@ -1023,15 +1023,15 @@ class Positioned extends ParentDataWidget<StackRenderObjectWidgetBase> {
Positioned({ Positioned({
Key key, Key key,
Widget child, Widget child,
this.left,
this.top, this.top,
this.right, this.right,
this.bottom, this.bottom,
this.left,
this.width, this.width,
this.height this.height
}) : super(key: key, child: child) { }) : super(key: key, child: child) {
assert(top == null || bottom == null || height == null);
assert(left == null || right == null || width == null); assert(left == null || right == null || width == null);
assert(top == null || bottom == null || height == null);
} }
Positioned.fromRect({ Positioned.fromRect({
...@@ -1046,6 +1046,9 @@ class Positioned extends ParentDataWidget<StackRenderObjectWidgetBase> { ...@@ -1046,6 +1046,9 @@ class Positioned extends ParentDataWidget<StackRenderObjectWidgetBase> {
bottom = null, bottom = null,
super(key: key, child: child); super(key: key, child: child);
/// The offset of the child's left edge from the left of the stack.
final double left;
/// The offset of the child's top edge from the top of the stack. /// The offset of the child's top edge from the top of the stack.
final double top; final double top;
...@@ -1055,17 +1058,16 @@ class Positioned extends ParentDataWidget<StackRenderObjectWidgetBase> { ...@@ -1055,17 +1058,16 @@ class Positioned extends ParentDataWidget<StackRenderObjectWidgetBase> {
/// The offset of the child's bottom edge from the bottom of the stack. /// The offset of the child's bottom edge from the bottom of the stack.
final double bottom; final double bottom;
/// The offset of the child's left edge from the left of the stack.
final double left;
/// The child's width. /// The child's width.
/// ///
/// Ignored if both left and right are non-null. /// Only two out of the three horizontal values (left, right, width) can be
/// set. The third must be null.
final double width; final double width;
/// The child's height. /// The child's height.
/// ///
/// Ignored if both top and bottom are non-null. /// Only two out of the three vertical values (top, bottom, height) can be
/// set. The third must be null.
final double height; final double height;
void applyParentData(RenderObject renderObject) { void applyParentData(RenderObject renderObject) {
...@@ -1073,6 +1075,11 @@ class Positioned extends ParentDataWidget<StackRenderObjectWidgetBase> { ...@@ -1073,6 +1075,11 @@ class Positioned extends ParentDataWidget<StackRenderObjectWidgetBase> {
final StackParentData parentData = renderObject.parentData; final StackParentData parentData = renderObject.parentData;
bool needsLayout = false; bool needsLayout = false;
if (parentData.left != left) {
parentData.left = left;
needsLayout = true;
}
if (parentData.top != top) { if (parentData.top != top) {
parentData.top = top; parentData.top = top;
needsLayout = true; needsLayout = true;
...@@ -1088,11 +1095,6 @@ class Positioned extends ParentDataWidget<StackRenderObjectWidgetBase> { ...@@ -1088,11 +1095,6 @@ class Positioned extends ParentDataWidget<StackRenderObjectWidgetBase> {
needsLayout = true; needsLayout = true;
} }
if (parentData.left != left) {
parentData.left = left;
needsLayout = true;
}
if (parentData.width != width) { if (parentData.width != width) {
parentData.width = width; parentData.width = width;
needsLayout = true; needsLayout = true;
......
...@@ -226,7 +226,11 @@ class AnimatedRelativeRectValue extends AnimatedValue<RelativeRect> { ...@@ -226,7 +226,11 @@ class AnimatedRelativeRectValue extends AnimatedValue<RelativeRect> {
RelativeRect lerp(double t) => RelativeRect.lerp(begin, end, t); RelativeRect lerp(double t) => RelativeRect.lerp(begin, end, t);
} }
/// Animated version of [Positioned]. /// Animated version of [Positioned] which takes a specific
/// [AnimatedRelativeRectValue] and a [PerformanceView] to transition the
/// child's position from a start position to and end position over the lifetime
/// of the performance.
///
/// Only works if it's the child of a [Stack]. /// Only works if it's the child of a [Stack].
class PositionedTransition extends TransitionWithChild { class PositionedTransition extends TransitionWithChild {
PositionedTransition({ PositionedTransition({
......
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
/// The Flutter widget framework. /// The Flutter widget framework.
library widgets; library widgets;
export 'src/widgets/animated_container.dart';
export 'src/widgets/basic.dart'; export 'src/widgets/basic.dart';
export 'src/widgets/binding.dart'; export 'src/widgets/binding.dart';
export 'src/widgets/dismissable.dart'; export 'src/widgets/dismissable.dart';
...@@ -18,6 +17,7 @@ export 'src/widgets/gesture_detector.dart'; ...@@ -18,6 +17,7 @@ export 'src/widgets/gesture_detector.dart';
export 'src/widgets/gridpaper.dart'; export 'src/widgets/gridpaper.dart';
export 'src/widgets/heroes.dart'; export 'src/widgets/heroes.dart';
export 'src/widgets/homogeneous_viewport.dart'; export 'src/widgets/homogeneous_viewport.dart';
export 'src/widgets/implicit_animations.dart';
export 'src/widgets/locale_query.dart'; export 'src/widgets/locale_query.dart';
export 'src/widgets/media_query.dart'; export 'src/widgets/media_query.dart';
export 'src/widgets/mimic.dart'; export 'src/widgets/mimic.dart';
......
...@@ -30,7 +30,7 @@ void main() { ...@@ -30,7 +30,7 @@ void main() {
) )
); );
RenderDecoratedBox box = key.currentState.context.findRenderObject(); RenderDecoratedBox box = key.currentContext.findRenderObject();
actualDecoration = box.decoration; actualDecoration = box.decoration;
expect(actualDecoration.backgroundColor, equals(decorationA.backgroundColor)); expect(actualDecoration.backgroundColor, equals(decorationA.backgroundColor));
...@@ -42,7 +42,7 @@ void main() { ...@@ -42,7 +42,7 @@ void main() {
) )
); );
expect(key.currentState.context.findRenderObject(), equals(box)); expect(key.currentContext.findRenderObject(), equals(box));
actualDecoration = box.decoration; actualDecoration = box.decoration;
expect(actualDecoration.backgroundColor, equals(decorationA.backgroundColor)); expect(actualDecoration.backgroundColor, equals(decorationA.backgroundColor));
......
// 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_test/flutter_test.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'package:test/test.dart';
void main() {
test('AnimatedPositioned - basics', () {
testWidgets((WidgetTester tester) {
GlobalKey key = new GlobalKey();
RenderBox box;
tester.pumpWidget(
new Stack(
<Widget>[
new AnimatedPositioned(
child: new Container(key: key),
left: 50.0,
top: 30.0,
width: 70.0,
height: 110.0,
duration: const Duration(seconds: 2)
)
]
)
);
box = key.currentContext.findRenderObject();
expect(box.localToGlobal(box.size.center(Point.origin)), equals(const Point(50.0 + 70.0 / 2.0, 30.0 + 110.0 / 2.0)));
tester.pump(const Duration(seconds: 1));
box = key.currentContext.findRenderObject();
expect(box.localToGlobal(box.size.center(Point.origin)), equals(const Point(50.0 + 70.0 / 2.0, 30.0 + 110.0 / 2.0)));
tester.pumpWidget(
new Stack(
<Widget>[
new AnimatedPositioned(
child: new Container(key: key),
left: 37.0,
top: 31.0,
width: 59.0,
height: 71.0,
duration: const Duration(seconds: 2)
)
]
)
);
box = key.currentContext.findRenderObject();
expect(box.localToGlobal(box.size.center(Point.origin)), equals(const Point(50.0 + 70.0 / 2.0, 30.0 + 110.0 / 2.0)));
tester.pump(const Duration(seconds: 1));
box = key.currentContext.findRenderObject();
expect(box.localToGlobal(box.size.center(Point.origin)), equals(const Point(50.0 - (50.0 - 37.0) / 2.0 + (70.0 - (70.0 - 59.0) / 2.0) / 2.0,
30.0 + (31.0 - 30.0) / 2.0 + (110.0 - (110.0 - 71.0) / 2.0) / 2.0)));
tester.pump(const Duration(seconds: 1));
box = key.currentContext.findRenderObject();
expect(box.localToGlobal(box.size.center(Point.origin)), equals(const Point(37.0 + 59.0 / 2.0, 31.0 + 71.0 / 2.0)));
});
});
test('AnimatedPositioned - interrupted animation', () {
testWidgets((WidgetTester tester) {
GlobalKey key = new GlobalKey();
RenderBox box;
tester.pumpWidget(
new Stack(
<Widget>[
new AnimatedPositioned(
child: new Container(key: key),
left: 0.0,
top: 0.0,
width: 100.0,
height: 100.0,
duration: const Duration(seconds: 2)
)
]
)
);
box = key.currentContext.findRenderObject();
expect(box.localToGlobal(box.size.center(Point.origin)), equals(const Point(50.0, 50.0)));
tester.pump(const Duration(seconds: 1));
box = key.currentContext.findRenderObject();
expect(box.localToGlobal(box.size.center(Point.origin)), equals(const Point(50.0, 50.0)));
tester.pumpWidget(
new Stack(
<Widget>[
new AnimatedPositioned(
child: new Container(key: key),
left: 100.0,
top: 100.0,
width: 100.0,
height: 100.0,
duration: const Duration(seconds: 2)
)
]
)
);
box = key.currentContext.findRenderObject();
expect(box.localToGlobal(box.size.center(Point.origin)), equals(const Point(50.0, 50.0)));
tester.pump(const Duration(seconds: 1));
box = key.currentContext.findRenderObject();
expect(box.localToGlobal(box.size.center(Point.origin)), equals(const Point(100.0, 100.0)));
tester.pumpWidget(
new Stack(
<Widget>[
new AnimatedPositioned(
child: new Container(key: key),
left: 150.0,
top: 150.0,
width: 100.0,
height: 100.0,
duration: const Duration(seconds: 2)
)
]
)
);
box = key.currentContext.findRenderObject();
expect(box.localToGlobal(box.size.center(Point.origin)), equals(const Point(100.0, 100.0)));
tester.pump(const Duration(seconds: 1));
box = key.currentContext.findRenderObject();
expect(box.localToGlobal(box.size.center(Point.origin)), equals(const Point(150.0, 150.0)));
tester.pump(const Duration(seconds: 1));
box = key.currentContext.findRenderObject();
expect(box.localToGlobal(box.size.center(Point.origin)), equals(const Point(200.0, 200.0)));
});
});
test('AnimatedPositioned - switching variables', () {
testWidgets((WidgetTester tester) {
GlobalKey key = new GlobalKey();
RenderBox box;
tester.pumpWidget(
new Stack(
<Widget>[
new AnimatedPositioned(
child: new Container(key: key),
left: 0.0,
top: 0.0,
width: 100.0,
height: 100.0,
duration: const Duration(seconds: 2)
)
]
)
);
box = key.currentContext.findRenderObject();
expect(box.localToGlobal(box.size.center(Point.origin)), equals(const Point(50.0, 50.0)));
tester.pump(const Duration(seconds: 1));
box = key.currentContext.findRenderObject();
expect(box.localToGlobal(box.size.center(Point.origin)), equals(const Point(50.0, 50.0)));
tester.pumpWidget(
new Stack(
<Widget>[
new AnimatedPositioned(
child: new Container(key: key),
left: 0.0,
top: 100.0,
right: 100.0, // 700.0 from the left
height: 100.0,
duration: const Duration(seconds: 2)
)
]
)
);
box = key.currentContext.findRenderObject();
expect(box.localToGlobal(box.size.center(Point.origin)), equals(const Point(350.0, 50.0)));
tester.pump(const Duration(seconds: 1));
box = key.currentContext.findRenderObject();
expect(box.localToGlobal(box.size.center(Point.origin)), equals(const Point(350.0, 100.0)));
tester.pump(const Duration(seconds: 1));
box = key.currentContext.findRenderObject();
expect(box.localToGlobal(box.size.center(Point.origin)), equals(const Point(350.0, 150.0)));
});
});
}
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