mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
This allows the scheduler library to depend on the services library and the painting library to depend on the scheduler library without the services library having to depend on the scheduler library. While I was at it I also cleaned up some of the binding logic: the licenses logic can now be overridden (and the test library does so), and the image cache can now be overridden as well.
143 lines
4.0 KiB
Dart
143 lines
4.0 KiB
Dart
// 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/foundation.dart';
|
|
import 'package:flutter/gestures.dart';
|
|
import 'package:flutter/rendering.dart';
|
|
import 'package:flutter/scheduler.dart';
|
|
import 'package:flutter/services.dart';
|
|
|
|
import 'package:flutter_test/flutter_test.dart' show EnginePhase;
|
|
export 'package:flutter_test/flutter_test.dart' show EnginePhase;
|
|
|
|
class TestRenderingFlutterBinding extends BindingBase with ServicesBinding, GestureBinding, SchedulerBinding, PaintingBinding, RendererBinding {
|
|
EnginePhase phase = EnginePhase.composite;
|
|
|
|
@override
|
|
void drawFrame() {
|
|
assert(phase != EnginePhase.build, 'rendering_tester does not support testing the build phase; use flutter_test instead');
|
|
pipelineOwner.flushLayout();
|
|
if (phase == EnginePhase.layout)
|
|
return;
|
|
pipelineOwner.flushCompositingBits();
|
|
if (phase == EnginePhase.compositingBits)
|
|
return;
|
|
pipelineOwner.flushPaint();
|
|
if (phase == EnginePhase.paint)
|
|
return;
|
|
renderView.compositeFrame();
|
|
if (phase == EnginePhase.composite)
|
|
return;
|
|
pipelineOwner.flushSemantics();
|
|
if (phase == EnginePhase.flushSemantics)
|
|
return;
|
|
assert(phase == EnginePhase.flushSemantics ||
|
|
phase == EnginePhase.sendSemanticsUpdate);
|
|
}
|
|
}
|
|
|
|
TestRenderingFlutterBinding _renderer;
|
|
TestRenderingFlutterBinding get renderer {
|
|
_renderer ??= new TestRenderingFlutterBinding();
|
|
return _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).
|
|
///
|
|
/// The EnginePhase must not be [EnginePhase.build], since the rendering layer
|
|
/// has no build phase.
|
|
void layout(RenderBox box, {
|
|
BoxConstraints constraints,
|
|
Alignment alignment: Alignment.center,
|
|
EnginePhase phase: EnginePhase.layout,
|
|
}) {
|
|
assert(box != null); // If you want to just repump the last box, call pumpFrame().
|
|
assert(box.parent == null); // We stick the box in another, so you can't reuse it easily, sorry.
|
|
|
|
renderer.renderView.child = null;
|
|
if (constraints != null) {
|
|
box = new RenderPositionedBox(
|
|
alignment: alignment,
|
|
child: new RenderConstrainedBox(
|
|
additionalConstraints: constraints,
|
|
child: box
|
|
)
|
|
);
|
|
}
|
|
renderer.renderView.child = box;
|
|
|
|
pumpFrame(phase: phase);
|
|
}
|
|
|
|
void pumpFrame({ EnginePhase phase: EnginePhase.layout }) {
|
|
assert(renderer != null);
|
|
assert(renderer.renderView != null);
|
|
assert(renderer.renderView.child != null); // call layout() first!
|
|
renderer.phase = phase;
|
|
renderer.drawFrame();
|
|
}
|
|
|
|
class TestCallbackPainter extends CustomPainter {
|
|
const TestCallbackPainter({ this.onPaint });
|
|
|
|
final VoidCallback onPaint;
|
|
|
|
@override
|
|
void paint(Canvas canvas, Size size) {
|
|
onPaint();
|
|
}
|
|
|
|
@override
|
|
bool shouldRepaint(TestCallbackPainter oldPainter) => true;
|
|
}
|
|
|
|
|
|
class RenderSizedBox extends RenderBox {
|
|
RenderSizedBox(this._size);
|
|
|
|
final Size _size;
|
|
|
|
@override
|
|
double computeMinIntrinsicWidth(double height) {
|
|
return _size.width;
|
|
}
|
|
|
|
@override
|
|
double computeMaxIntrinsicWidth(double height) {
|
|
return _size.width;
|
|
}
|
|
|
|
@override
|
|
double computeMinIntrinsicHeight(double width) {
|
|
return _size.height;
|
|
}
|
|
|
|
@override
|
|
double computeMaxIntrinsicHeight(double width) {
|
|
return _size.height;
|
|
}
|
|
|
|
@override
|
|
bool get sizedByParent => true;
|
|
|
|
@override
|
|
void performResize() {
|
|
size = constraints.constrain(_size);
|
|
}
|
|
|
|
@override
|
|
void performLayout() { }
|
|
|
|
@override
|
|
bool hitTestSelf(Offset position) => true;
|
|
}
|