Unverified Commit 637bd0fb authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

[framework] simplify raster widget, rename, combine painters (#109485)

parent 7f260672
......@@ -342,7 +342,7 @@ class CupertinoPageRoute<T> extends PageRoute<T> with CupertinoRouteTransitionMi
super.settings,
this.maintainState = true,
super.fullscreenDialog,
super.preferRasterization = true,
super.allowSnapshotting = true,
}) : assert(builder != null),
assert(maintainState != null),
assert(fullscreenDialog != null) {
......@@ -372,7 +372,7 @@ class CupertinoPageRoute<T> extends PageRoute<T> with CupertinoRouteTransitionMi
class _PageBasedCupertinoPageRoute<T> extends PageRoute<T> with CupertinoRouteTransitionMixin<T> {
_PageBasedCupertinoPageRoute({
required CupertinoPage<T> page,
super.preferRasterization = true,
super.allowSnapshotting = true,
}) : assert(page != null),
super(settings: page) {
assert(opaque);
......@@ -419,7 +419,7 @@ class CupertinoPage<T> extends Page<T> {
this.maintainState = true,
this.title,
this.fullscreenDialog = false,
this.preferRasterization = true,
this.allowSnapshotting = true,
super.key,
super.name,
super.arguments,
......@@ -440,12 +440,12 @@ class CupertinoPage<T> extends Page<T> {
/// {@macro flutter.widgets.PageRoute.fullscreenDialog}
final bool fullscreenDialog;
/// {@macro flutter.widgets.TransitionRoute.preferRasterization}
final bool preferRasterization;
/// {@macro flutter.widgets.TransitionRoute.allowSnapshotting}
final bool allowSnapshotting;
@override
Route<T> createRoute(BuildContext context) {
return _PageBasedCupertinoPageRoute<T>(page: this, preferRasterization: preferRasterization);
return _PageBasedCupertinoPageRoute<T>(page: this, allowSnapshotting: allowSnapshotting);
}
}
......
......@@ -39,7 +39,7 @@ class MaterialPageRoute<T> extends PageRoute<T> with MaterialRouteTransitionMixi
super.settings,
this.maintainState = true,
super.fullscreenDialog,
super.preferRasterization = true,
super.allowSnapshotting = true,
}) : assert(builder != null),
assert(maintainState != null),
assert(fullscreenDialog != null) {
......@@ -158,7 +158,7 @@ class MaterialPage<T> extends Page<T> {
required this.child,
this.maintainState = true,
this.fullscreenDialog = false,
this.preferRasterization = true,
this.allowSnapshotting = true,
super.key,
super.name,
super.arguments,
......@@ -176,12 +176,12 @@ class MaterialPage<T> extends Page<T> {
/// {@macro flutter.widgets.PageRoute.fullscreenDialog}
final bool fullscreenDialog;
/// {@macro flutter.widgets.TransitionRoute.preferRasterization}
final bool preferRasterization;
/// {@macro flutter.widgets.TransitionRoute.allowSnapshotting}
final bool allowSnapshotting;
@override
Route<T> createRoute(BuildContext context) {
return _PageBasedMaterialPageRoute<T>(page: this, preferRasterization: preferRasterization);
return _PageBasedMaterialPageRoute<T>(page: this, allowSnapshotting: allowSnapshotting);
}
}
......@@ -192,7 +192,7 @@ class MaterialPage<T> extends Page<T> {
class _PageBasedMaterialPageRoute<T> extends PageRoute<T> with MaterialRouteTransitionMixin<T> {
_PageBasedMaterialPageRoute({
required MaterialPage<T> page,
super.preferRasterization,
super.allowSnapshotting,
}) : assert(page != null),
super(settings: page) {
assert(opaque);
......
......@@ -19,7 +19,7 @@ abstract class PageRoute<T> extends ModalRoute<T> {
PageRoute({
super.settings,
this.fullscreenDialog = false,
this.preferRasterization = true,
this.allowSnapshotting = true,
});
/// {@template flutter.widgets.PageRoute.fullscreenDialog}
......@@ -33,7 +33,7 @@ abstract class PageRoute<T> extends ModalRoute<T> {
final bool fullscreenDialog;
@override
final bool preferRasterization;
final bool allowSnapshotting;
@override
bool get opaque => true;
......@@ -80,7 +80,7 @@ class PageRouteBuilder<T> extends PageRoute<T> {
this.barrierLabel,
this.maintainState = true,
super.fullscreenDialog,
super.preferRasterization = true,
super.allowSnapshotting = true,
}) : assert(pageBuilder != null),
assert(transitionsBuilder != null),
assert(opaque != null),
......
......@@ -134,20 +134,20 @@ abstract class TransitionRoute<T> extends OverlayRoute<T> {
/// {@endtemplate}
bool get opaque;
/// {@template flutter.widgets.TransitionRoute.preferRasterization}
/// Whether the route transition will prefer to animate a rasterized
/// snapshot of the entering/exiting routes.
/// {@template flutter.widgets.TransitionRoute.allowSnapshotting}
/// Whether the route transition will prefer to animate a snapshot of the
/// entering/exiting routes.
///
/// When this value is true, certain route transitions (such as the Android
/// zoom page transition) will rasterize the entering and exiting routes.
/// These textures are then animated in place of the underlying widgets to
/// zoom page transition) will snapshot the entering and exiting routes.
/// These snapshots are then animated in place of the underlying widgets to
/// improve performance of the transition.
///
/// Generally this means that animations that occur on the entering/exiting
/// route while the route animation plays may appear frozen - unless they
/// are a hero animation or something that is drawn in a separate overlay.
/// {@endtemplate}
bool get preferRasterization => true;
bool get allowSnapshotting => true;
// This ensures that if we got to the dismissed state while still current,
// we will still be disposed when we are eventually popped.
......@@ -1749,7 +1749,7 @@ abstract class PopupRoute<T> extends ModalRoute<T> {
bool get maintainState => true;
@override
bool get preferRasterization => false;
bool get allowSnapshotting => false;
}
/// A [Navigator] observer that notifies [RouteAware]s of changes to the
......
......@@ -91,7 +91,6 @@ export 'src/widgets/platform_selectable_region_context_menu.dart';
export 'src/widgets/platform_view.dart';
export 'src/widgets/preferred_size.dart';
export 'src/widgets/primary_scroll_controller.dart';
export 'src/widgets/raster_widget.dart';
export 'src/widgets/raw_keyboard_listener.dart';
export 'src/widgets/reorderable_list.dart';
export 'src/widgets/restoration.dart';
......@@ -127,6 +126,7 @@ export 'src/widgets/sliver_layout_builder.dart';
export 'src/widgets/sliver_persistent_header.dart';
export 'src/widgets/sliver_prototype_extent_list.dart';
export 'src/widgets/slotted_render_object_widget.dart';
export 'src/widgets/snapshot_widget.dart';
export 'src/widgets/spacer.dart';
export 'src/widgets/spell_check.dart';
export 'src/widgets/status_transitions.dart';
......
......@@ -399,18 +399,21 @@ void main() {
Widget build() {
return Directionality(
textDirection: TextDirection.ltr,
child: Navigator(
initialRoute: '/',
onGenerateRoute: (RouteSettings settings) {
return MaterialPageRoute<void>(
settings: settings,
builder: (BuildContext context) {
return Material(
child: buildFrame(value: 'one', onChanged: didChangeValue),
);
},
);
},
child: MediaQuery(
data: MediaQueryData.fromWindow(WidgetsBinding.instance.window),
child: Navigator(
initialRoute: '/',
onGenerateRoute: (RouteSettings settings) {
return MaterialPageRoute<void>(
settings: settings,
builder: (BuildContext context) {
return Material(
child: buildFrame(value: 'one', onChanged: didChangeValue),
);
},
);
},
),
),
);
}
......
......@@ -158,7 +158,7 @@ void main() {
testWidgets('test page transition (_ZoomPageTransition) without rasterization', (WidgetTester tester) async {
Iterable<Layer> findLayers(Finder of) {
return tester.layerListOf(
find.ancestor(of: of, matching: find.byType(RasterWidget)).first,
find.ancestor(of: of, matching: find.byType(SnapshotWidget)).first,
);
}
......@@ -174,7 +174,7 @@ void main() {
MaterialApp(
onGenerateRoute: (RouteSettings settings) {
return MaterialPageRoute<void>(
preferRasterization: false,
allowSnapshotting: false,
builder: (BuildContext context) {
if (settings.name == '/') {
return const Material(child: Text('Page 1'));
......@@ -1004,8 +1004,7 @@ void main() {
await tester.pumpWidget(
RootRestorationScope(
restorationId: 'root',
child: Directionality(
textDirection: TextDirection.ltr,
child: TestDependencies(
child: Navigator(
onPopPage: (Route<dynamic> route, dynamic result) { return false; },
pages: const <Page<Object?>>[
......@@ -1177,3 +1176,20 @@ class _TestRestorableWidgetState extends State<TestRestorableWidget> with Restor
);
}
}
class TestDependencies extends StatelessWidget {
const TestDependencies({required this.child, super.key});
final Widget child;
@override
Widget build(BuildContext context) {
return Directionality(
textDirection: TextDirection.ltr,
child: MediaQuery(
data: MediaQueryData.fromWindow(WidgetsBinding.instance.window),
child: child,
),
);
}
}
......@@ -1821,7 +1821,7 @@ void main() {
// Wait for context menu to be built.
await tester.pumpAndSettle();
final RenderBox container = tester.renderObject(find.descendant(
of: find.byType(RasterWidget),
of: find.byType(SnapshotWidget),
matching: find.byType(SizedBox),
).first);
expect(container.size, Size.zero);
......
......@@ -327,8 +327,7 @@ Future<void> main() async {
await tester.pumpWidget(
HeroControllerScope(
controller: HeroController(),
child: Directionality(
textDirection: TextDirection.ltr,
child: TestDependencies(
child: Navigator(
key: key,
initialRoute: 'navigator1',
......@@ -382,8 +381,7 @@ Future<void> main() async {
await tester.pumpWidget(
HeroControllerScope(
controller: HeroController(),
child: Directionality(
textDirection: TextDirection.ltr,
child: TestDependencies(
child: Navigator(
key: key,
initialRoute: 'navigator1',
......@@ -3160,3 +3158,20 @@ Future<void> main() async {
},
);
}
class TestDependencies extends StatelessWidget {
const TestDependencies({required this.child, super.key});
final Widget child;
@override
Widget build(BuildContext context) {
return Directionality(
textDirection: TextDirection.ltr,
child: MediaQuery(
data: MediaQueryData.fromWindow(WidgetsBinding.instance.window),
child: child,
),
);
}
}
......@@ -1042,9 +1042,12 @@ class PagedTestWidget extends StatelessWidget {
Widget build(BuildContext context) {
return RootRestorationScope(
restorationId: restorationId,
child: const Directionality(
child: Directionality(
textDirection: TextDirection.ltr,
child: PagedTestNavigator(),
child: MediaQuery(
data: MediaQueryData.fromWindow(WidgetsBinding.instance.window),
child: const PagedTestNavigator(),
),
),
);
}
......@@ -1167,20 +1170,23 @@ class TestWidget extends StatelessWidget {
restorationId: restorationId,
child: Directionality(
textDirection: TextDirection.ltr,
child: Navigator(
initialRoute: 'home',
restorationScopeId: 'app',
onGenerateRoute: (RouteSettings settings) {
return MaterialPageRoute<int>(
settings: settings,
builder: (BuildContext context) {
return RouteWidget(
name: settings.name!,
arguments: settings.arguments,
);
},
);
},
child: MediaQuery(
data: MediaQueryData.fromWindow(WidgetsBinding.instance.window),
child: Navigator(
initialRoute: 'home',
restorationScopeId: 'app',
onGenerateRoute: (RouteSettings settings) {
return MaterialPageRoute<int>(
settings: settings,
builder: (BuildContext context) {
return RouteWidget(
name: settings.name!,
arguments: settings.arguments,
);
},
);
},
),
),
),
);
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:ui';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
......@@ -201,8 +199,7 @@ void main() {
};
final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
TestDependencies(
child: Navigator(
key: navigator,
pages: pages,
......@@ -566,8 +563,7 @@ void main() {
}
final TabController controller = TabController(length: 3, vsync: tester);
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
TestDependencies(
child: TabBarView(
controller: controller,
children: <Widget>[
......@@ -598,8 +594,7 @@ void main() {
);
}
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
TestDependencies(
child: buildNavigator(),
),
);
......@@ -608,8 +603,7 @@ void main() {
pages.add(const MaterialPage<void>(child: Text('Page 2')));
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
TestDependencies(
child: buildNavigator(),
),
);
......@@ -641,8 +635,7 @@ void main() {
);
}
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
TestDependencies(
child: buildNavigator(),
),
);
......@@ -659,8 +652,7 @@ void main() {
];
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
TestDependencies(
child: buildNavigator(),
),
);
......@@ -1904,8 +1896,7 @@ void main() {
testWidgets('initial routes below opaque route are offstage', (WidgetTester tester) async {
final GlobalKey<NavigatorState> testKey = GlobalKey<NavigatorState>();
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
TestDependencies(
child: Navigator(
key: testKey,
initialRoute: '/a/b',
......@@ -1947,8 +1938,7 @@ void main() {
bool onGenerateInitialRoutesCalled = false;
final GlobalKey<NavigatorState> testKey = GlobalKey<NavigatorState>();
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
TestDependencies(
child: Navigator(
key: testKey,
initialRoute: 'Hello World',
......@@ -2074,8 +2064,7 @@ void main() {
final Map<String, MaterialPageRoute<dynamic>> routeNameToContext = <String, MaterialPageRoute<dynamic>>{};
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
TestDependencies(
child: Navigator(
key: navigator,
initialRoute: 'root',
......@@ -2154,8 +2143,7 @@ void main() {
Widget widgetUnderTest({required bool enabled}) {
return TickerMode(
enabled: enabled,
child: Directionality(
textDirection: TextDirection.ltr,
child: TestDependencies(
child: Navigator(
initialRoute: 'root',
onGenerateRoute: (RouteSettings settings) {
......@@ -2261,8 +2249,7 @@ void main() {
await tester.pumpWidget(
HeroControllerScope(
controller: spy,
child: Directionality(
textDirection: TextDirection.ltr,
child: TestDependencies(
child: Navigator(
key: top,
initialRoute: 'top1',
......@@ -2332,8 +2319,7 @@ void main() {
await tester.pumpWidget(
HeroControllerScope(
controller: spy,
child: Directionality(
textDirection: TextDirection.ltr,
child: TestDependencies(
child: Navigator(
key: key1,
initialRoute: 'navigator1',
......@@ -2353,8 +2339,7 @@ void main() {
await tester.pumpWidget(
HeroControllerScope(
controller: spy,
child: Directionality(
textDirection: TextDirection.ltr,
child: TestDependencies(
child: Navigator(
key: key2,
initialRoute: 'navigator2',
......@@ -2412,8 +2397,7 @@ void main() {
);
};
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
TestDependencies(
child: Stack(
children: <Widget>[
HeroControllerScope(
......@@ -2459,8 +2443,7 @@ void main() {
// Swaps the spies.
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
TestDependencies(
child: Stack(
children: <Widget>[
HeroControllerScope(
......@@ -2532,8 +2515,7 @@ void main() {
await tester.pumpWidget(
HeroControllerScope(
controller: spy,
child: Directionality(
textDirection: TextDirection.ltr,
child: TestDependencies(
child: Stack(
children: <Widget>[
Navigator(
......@@ -2571,8 +2553,7 @@ void main() {
await tester.pumpWidget(
HeroControllerScope(
controller: spy,
child: Directionality(
textDirection: TextDirection.ltr,
child: TestDependencies(
child: Stack(
children: <Widget>[
Navigator(
......@@ -2637,8 +2618,7 @@ void main() {
DefaultMaterialLocalizations.delegate,
DefaultWidgetsLocalizations.delegate,
],
child: Directionality(
textDirection: TextDirection.ltr,
child: TestDependencies(
child: Navigator(
key: key,
pages: pages,
......@@ -2736,8 +2716,7 @@ void main() {
DefaultMaterialLocalizations.delegate,
DefaultWidgetsLocalizations.delegate,
],
child: Directionality(
textDirection: TextDirection.ltr,
child: TestDependencies(
child: Navigator(
pages: myPages,
),
......@@ -2832,8 +2811,7 @@ void main() {
DefaultMaterialLocalizations.delegate,
DefaultWidgetsLocalizations.delegate,
],
child: Directionality(
textDirection: TextDirection.ltr,
child: TestDependencies(
child: Navigator(
pages: myPages,
),
......@@ -3086,8 +3064,7 @@ void main() {
testWidgets('Pop no animation page does not crash', (WidgetTester tester) async {
// Regression Test for https://github.com/flutter/flutter/issues/86604.
Widget buildNavigator(bool secondPage) {
return Directionality(
textDirection: TextDirection.ltr,
return TestDependencies(
child: Navigator(
pages: <Page<void>>[
const ZeroDurationPage(
......@@ -3691,8 +3668,7 @@ void main() {
testWidgets('Can reuse NavigatorObserver in rebuilt tree', (WidgetTester tester) async {
final NavigatorObserver observer = NavigatorObserver();
Widget build([Key? key]) {
return Directionality(
textDirection: TextDirection.ltr,
return TestDependencies(
child: Navigator(
key: key,
observers: <NavigatorObserver>[observer],
......@@ -3869,8 +3845,7 @@ void main() {
testWidgets('class implementing NavigatorObserver can be used without problems', (WidgetTester tester) async {
final _MockNavigatorObserver observer = _MockNavigatorObserver();
Widget build([Key? key]) {
return Directionality(
textDirection: TextDirection.ltr,
return TestDependencies(
child: Navigator(
key: key,
observers: <NavigatorObserver>[observer],
......@@ -4122,7 +4097,7 @@ class ZeroDurationPage extends Page<void> {
class ZeroDurationPageRoute extends PageRoute<void> {
ZeroDurationPageRoute({required ZeroDurationPage page})
: super(settings: page, preferRasterization: false);
: super(settings: page, allowSnapshotting: false);
@override
Duration get transitionDuration => Duration.zero;
......@@ -4163,3 +4138,20 @@ class _MockNavigatorObserver implements NavigatorObserver {
return null;
}
}
class TestDependencies extends StatelessWidget {
const TestDependencies({super.key, required this.child});
final Widget child;
@override
Widget build(BuildContext context) {
return MediaQuery(
data: MediaQueryData.fromWindow(WidgetsBinding.instance.window),
child: Directionality(
textDirection: TextDirection.ltr,
child: child,
)
);
}
}
......@@ -33,24 +33,27 @@ Future<void> performTest(WidgetTester tester, bool maintainState) async {
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: Navigator(
key: navigatorKey,
onGenerateRoute: (RouteSettings settings) {
if (settings.name == '/') {
return MaterialPageRoute<void>(
settings: settings,
builder: (_) => const ThePositiveNumbers(from: 0),
maintainState: maintainState,
);
} else if (settings.name == '/second') {
return MaterialPageRoute<void>(
settings: settings,
builder: (_) => const ThePositiveNumbers(from: 10000),
maintainState: maintainState,
);
}
return null;
},
child: MediaQuery(
data: MediaQueryData.fromWindow(WidgetsBinding.instance.window),
child: Navigator(
key: navigatorKey,
onGenerateRoute: (RouteSettings settings) {
if (settings.name == '/') {
return MaterialPageRoute<void>(
settings: settings,
builder: (_) => const ThePositiveNumbers(from: 0),
maintainState: maintainState,
);
} else if (settings.name == '/second') {
return MaterialPageRoute<void>(
settings: settings,
builder: (_) => const ThePositiveNumbers(from: 10000),
maintainState: maintainState,
);
}
return null;
},
),
),
),
);
......
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