Unverified Commit ca35ddd4 authored by Ian Hickson's avatar Ian Hickson Committed by GitHub

Add some Transform constructors (#16553)

See https://github.com/flutter/flutter/pull/15383
parent 7d5e5ebc
......@@ -819,6 +819,8 @@ class PhysicalShape extends SingleChildRenderObjectWidget {
///
/// * [RotatedBox], which rotates the child widget during layout, not just
/// during painting.
/// * [FractionalTranslation], which applies a translation to the child
/// that is relative to the child's size.
/// * [FittedBox], which sizes and positions its child widget to fit the parent
/// according to a given [BoxFit] discipline.
class Transform extends SingleChildRenderObjectWidget {
......@@ -866,6 +868,67 @@ class Transform extends SingleChildRenderObjectWidget {
}) : transform = new Matrix4.rotationZ(angle),
super(key: key, child: child);
/// Creates a widget that transforms its child using a translation.
///
/// The `offset` argument must not be null. It specifies the translation.
///
/// ## Sample code
///
/// This example shifts the silver-colored child down by fifteen pixels.
///
/// ```dart
/// new Transform.translate(
/// offset: const Offset(0.0, 15.0),
/// child: new Container(
/// padding: const EdgeInsets.all(8.0),
/// color: const Color(0xFF7F7F7F),
/// child: const Text('Quarter'),
/// ),
/// )
/// ```
Transform.translate({
Key key,
@required Offset offset,
this.transformHitTests: true,
Widget child,
}) : transform = new Matrix4.translationValues(offset.dx, offset.dy, 0.0),
origin = null,
alignment = null,
super(key: key, child: child);
/// Creates a widget that scales its child uniformly.
///
/// The `scale` argument must not be null. It gives the scalar by which
/// to multiply the `x` and `y` axes.
///
/// The [alignment] controls the origin of the scale; by default, this is
/// the center of the box.
///
/// ## Sample code
///
/// This example shrinks an orange box containing text such that each dimension
/// is half the size it would otherwise be.
///
/// ```dart
/// new Transform.scale(
/// scale: 0.5,
/// child: new Container(
/// padding: const EdgeInsets.all(8.0),
/// color: const Color(0xFFE8581C),
/// child: const Text('Bad Ideas'),
/// ),
/// )
/// ```
Transform.scale({
Key key,
@required double scale,
this.origin,
this.alignment: Alignment.center,
this.transformHitTests: true,
Widget child,
}) : transform = new Matrix4.diagonal3Values(scale, scale, 1.0),
super(key: key, child: child);
/// The matrix to transform the child by during painting.
final Matrix4 transform;
......@@ -1124,6 +1187,10 @@ class FittedBox extends SingleChildRenderObjectWidget {
///
/// See also:
///
/// * [Transform], which applies an arbitrary transform to its child widget at
/// paint time.
/// * [new Transform.translate], which applies an absolute offset translation
/// transformation instead of an offset scaled to the child.
/// * The [catalog of layout widgets](https://flutter.io/widgets/layout/).
class FractionalTranslation extends SingleChildRenderObjectWidget {
/// Creates a widget that translates its child's painting.
......@@ -1133,7 +1200,7 @@ class FractionalTranslation extends SingleChildRenderObjectWidget {
Key key,
@required this.translation,
this.transformHitTests: true,
Widget child
Widget child,
}) : assert(translation != null),
super(key: key, child: child);
......@@ -1184,6 +1251,7 @@ class FractionalTranslation extends SingleChildRenderObjectWidget {
///
/// * [Transform], which is a paint effect that allows you to apply an
/// arbitrary transform to a child.
/// * [new Transform.rotate], which applies a rotation paint effect.
/// * The [catalog of layout widgets](https://flutter.io/widgets/layout/).
class RotatedBox extends SingleChildRenderObjectWidget {
/// A widget that rotates its child.
......
......@@ -295,4 +295,42 @@ void main() {
);
expect(tester.getTopLeft(find.byType(Placeholder)), const Offset(30.0, 20.0));
});
testWidgets('Transform.translate', (WidgetTester tester) async {
await tester.pumpWidget(
new Transform.translate(
offset: const Offset(100.0, 50.0),
child: new Opacity(opacity: 0.5, child: new Container()),
),
);
// This should not cause a transform layer to be inserted.
final List<Layer> layers = tester.layers
..retainWhere((Layer layer) => layer is TransformLayer);
expect(layers.length, 1); // only the render view
expect(tester.getTopLeft(find.byType(Container)), const Offset(100.0, 50.0));
});
testWidgets('Transform.scale', (WidgetTester tester) async {
await tester.pumpWidget(
new Transform.scale(
scale: 2.0,
child: new Opacity(opacity: 0.5, child: new Container()),
),
);
final List<Layer> layers = tester.layers
..retainWhere((Layer layer) => layer is TransformLayer);
expect(layers.length, 2);
// The first transform is from the render view.
final TransformLayer layer = layers[1];
final Matrix4 transform = layer.transform;
expect(transform.storage, <dynamic>[
// These are column-major, not row-major.
2.0, 0.0, 0.0, 0.0,
0.0, 2.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
-400.0, -300.0, 0.0, 1.0, // it's 1600x1200, centered in an 800x600 square
]);
});
}
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