InteractiveViewer with a changing screen size (#60532)

This commit is contained in:
Justin McCandless 2020-07-01 22:43:03 -07:00 committed by GitHub
parent 14a4ed5888
commit 84fc52e1e9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 57 additions and 15 deletions

View file

@ -494,11 +494,7 @@ class _InteractiveViewerState extends State<InteractiveViewer> with TickerProvid
// The _boundaryRect is calculated by adding the boundaryMargin to the size of
// the child.
Rect _boundaryRectCached;
Rect get _boundaryRect {
if (_boundaryRectCached != null) {
return _boundaryRectCached;
}
assert(_childKey.currentContext != null);
assert(!widget.boundaryMargin.left.isNaN);
assert(!widget.boundaryMargin.right.isNaN);
@ -507,15 +503,15 @@ class _InteractiveViewerState extends State<InteractiveViewer> with TickerProvid
final RenderBox childRenderBox = _childKey.currentContext.findRenderObject() as RenderBox;
final Size childSize = childRenderBox.size;
_boundaryRectCached = widget.boundaryMargin.inflateRect(Offset.zero & childSize);
final Rect boundaryRect = widget.boundaryMargin.inflateRect(Offset.zero & childSize);
// Boundaries that are partially infinite are not allowed because Matrix4's
// rotation and translation methods don't handle infinites well.
assert(_boundaryRectCached.isFinite ||
(_boundaryRectCached.left.isInfinite
&& _boundaryRectCached.top.isInfinite
&& _boundaryRectCached.right.isInfinite
&& _boundaryRectCached.bottom.isInfinite), 'boundaryRect must either be infinite in all directions or finite in all directions.');
return _boundaryRectCached;
assert(boundaryRect.isFinite ||
(boundaryRect.left.isInfinite
&& boundaryRect.top.isInfinite
&& boundaryRect.right.isInfinite
&& boundaryRect.bottom.isInfinite), 'boundaryRect must either be infinite in all directions or finite in all directions.');
return boundaryRect;
}
// The Rect representing the child's parent.
@ -917,10 +913,6 @@ class _InteractiveViewerState extends State<InteractiveViewer> with TickerProvid
@override
void didUpdateWidget(InteractiveViewer oldWidget) {
super.didUpdateWidget(oldWidget);
if (widget.child != oldWidget.child || widget.boundaryMargin != oldWidget.boundaryMargin) {
_boundaryRectCached = null;
}
// Handle all cases of needing to dispose and initialize
// transformationControllers.
if (oldWidget.transformationController == null) {

View file

@ -450,6 +450,56 @@ void main() {
expect(transformationController.value.getMaxScaleOnAxis(), equals(1.0));
});
testWidgets('viewport changes size', (WidgetTester tester) async {
final TransformationController transformationController = TransformationController();
await tester.pumpWidget(
MaterialApp(
home: Scaffold(
body: Center(
child: InteractiveViewer(
transformationController: transformationController,
child: Container(),
),
),
),
),
);
expect(transformationController.value, equals(Matrix4.identity()));
// Attempting to drag to pan doesn't work because the child fits inside
// the viewport and has a tight boundary.
final Offset childOffset = tester.getTopLeft(find.byType(Container));
final Offset childInterior = Offset(
childOffset.dx + 20.0,
childOffset.dy + 20.0,
);
TestGesture gesture = await tester.startGesture(childInterior);
addTearDown(gesture.removePointer);
await tester.pump();
await gesture.moveTo(childOffset);
await tester.pump();
await gesture.up();
await tester.pumpAndSettle();
expect(transformationController.value, equals(Matrix4.identity()));
// Shrink the size of the screen.
tester.binding.window.physicalSizeTestValue = const Size(100.0, 100.0);
addTearDown(tester.binding.window.clearPhysicalSizeTestValue);
await tester.pump();
// Attempting to drag to pan still doesn't work, because the image has
// resized itself to fit the new screen size, and InteractiveViewer has
// updated its measurements to take that into consideration.
gesture = await tester.startGesture(childInterior);
await tester.pump();
await gesture.moveTo(childOffset);
await tester.pump();
await gesture.up();
await tester.pumpAndSettle();
expect(transformationController.value, equals(Matrix4.identity()));
});
});
group('getNearestPointOnLine', () {