mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
The main purpose of this PR is to make it so that when you set the initial route and it's a hierarchical route (e.g. `/a/b/c`), it implies multiple pushes, one for each step of the route (so in that case, `/`, `/a`, `/a/b`, and `/a/b/c`, in that order). If any of those routes don't exist, it falls back to '/'. As part of doing that, I: * Changed the default for MaterialApp.initialRoute to honor the actual initial route. * Added a MaterialApp.onUnknownRoute for handling bad routes. * Added a feature to flutter_driver that allows the host test script and the device test app to communicate. * Added a test to make sure `flutter drive --route` works. (Hopefully that will also prove `flutter run --route` works, though this isn't testing the `flutter` tool's side of that. My main concern is over whether the engine side works.) * Fixed `flutter drive` to output the right target file name. * Changed how the stocks app represents its data, so that we can show a page for a stock before we know if it exists. * Made it possible to show a stock page that doesn't exist. It shows a progress indicator if we're loading the data, or else shows a message saying it doesn't exist. * Changed the pathing structure of routes in stocks to work more sanely. * Made search in the stocks app actually work (before it only worked if we happened to accidentally trigger a rebuild). Added a test. * Replaced some custom code in the stocks app with a BackButton. * Added a "color" feature to BackButton to support the stocks use case. * Spaced out the ErrorWidget text a bit more. * Added `RouteSettings.copyWith`, which I ended up not using. * Improved the error messages around routing. While I was in some files I made a few formatting fixes, fixed some code health issues, and also removed `flaky: true` from some devicelab tests that have been stable for a while. Also added some documentation here and there.
120 lines
4.2 KiB
Dart
120 lines
4.2 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 'dart:ui' as ui show Paragraph, ParagraphBuilder, ParagraphConstraints, ParagraphStyle, TextStyle;
|
|
|
|
import 'box.dart';
|
|
import 'object.dart';
|
|
|
|
const double _kMaxWidth = 100000.0;
|
|
const double _kMaxHeight = 100000.0;
|
|
|
|
// Line length to fit small phones without dynamically checking size.
|
|
const String _kLine = '\n\n────────────────────\n\n';
|
|
|
|
/// A render object used as a placeholder when an error occurs.
|
|
///
|
|
/// The box will be painted in the color given by the
|
|
/// [RenderErrorBox.backgroundColor] static property.
|
|
///
|
|
/// A message can be provided. To simplify the class and thus help reduce the
|
|
/// likelihood of this class itself being the source of errors, the message
|
|
/// cannot be changed once the object has been created. If provided, the text
|
|
/// will be painted on top of the background, using the styles given by the
|
|
/// [RenderErrorBox.textStyle] and [RenderErrorBox.paragraphStyle] static
|
|
/// properties.
|
|
///
|
|
/// Again to help simplify the class, this box tries to be 100000.0 pixels wide
|
|
/// and high, to approximate being infinitely high but without using infinities.
|
|
class RenderErrorBox extends RenderBox {
|
|
/// Creates a RenderErrorBox render object.
|
|
///
|
|
/// A message can optionally be provided. If a message is provided, an attempt
|
|
/// will be made to render the message when the box paints.
|
|
RenderErrorBox([ this.message = '' ]) {
|
|
try {
|
|
if (message != '') {
|
|
// This class is intentionally doing things using the low-level
|
|
// primitives to avoid depending on any subsystems that may have ended
|
|
// up in an unstable state -- after all, this class is mainly used when
|
|
// things have gone wrong.
|
|
//
|
|
// Generally, the much better way to draw text in a RenderObject is to
|
|
// use the TextPainter class. If you're looking for code to crib from,
|
|
// see the paragraph.dart file and the RenderParagraph class.
|
|
final ui.ParagraphBuilder builder = new ui.ParagraphBuilder(paragraphStyle);
|
|
builder.pushStyle(textStyle);
|
|
builder.addText(
|
|
'$message$_kLine$message$_kLine$message$_kLine$message$_kLine$message$_kLine$message$_kLine'
|
|
'$message$_kLine$message$_kLine$message$_kLine$message$_kLine$message$_kLine$message'
|
|
);
|
|
_paragraph = builder.build();
|
|
}
|
|
} catch (e) { } // ignore: empty_catches
|
|
}
|
|
|
|
/// The message to attempt to display at paint time.
|
|
final String message;
|
|
|
|
ui.Paragraph _paragraph;
|
|
|
|
@override
|
|
double computeMaxIntrinsicWidth(double height) {
|
|
return _kMaxWidth;
|
|
}
|
|
|
|
@override
|
|
double computeMaxIntrinsicHeight(double width) {
|
|
return _kMaxHeight;
|
|
}
|
|
|
|
@override
|
|
bool get sizedByParent => true;
|
|
|
|
@override
|
|
bool hitTestSelf(Offset position) => true;
|
|
|
|
@override
|
|
void performResize() {
|
|
size = constraints.constrain(const Size(_kMaxWidth, _kMaxHeight));
|
|
}
|
|
|
|
/// The color to use when painting the background of [RenderErrorBox] objects.
|
|
static Color backgroundColor = const Color(0xF0900000);
|
|
|
|
/// The text style to use when painting [RenderErrorBox] objects.
|
|
static ui.TextStyle textStyle = new ui.TextStyle(
|
|
color: const Color(0xFFFFFF66),
|
|
fontFamily: 'monospace',
|
|
fontSize: 14.0,
|
|
fontWeight: FontWeight.bold
|
|
);
|
|
|
|
/// The paragraph style to use when painting [RenderErrorBox] objects.
|
|
static ui.ParagraphStyle paragraphStyle = new ui.ParagraphStyle(
|
|
lineHeight: 1.0,
|
|
);
|
|
|
|
@override
|
|
void paint(PaintingContext context, Offset offset) {
|
|
try {
|
|
context.canvas.drawRect(offset & size, new Paint() .. color = backgroundColor);
|
|
double width;
|
|
if (_paragraph != null) {
|
|
// See the comment in the RenderErrorBox constructor. This is not the
|
|
// code you want to be copying and pasting. :-)
|
|
if (parent is RenderBox) {
|
|
final RenderBox parentBox = parent;
|
|
width = parentBox.size.width;
|
|
} else {
|
|
width = size.width;
|
|
}
|
|
_paragraph.layout(new ui.ParagraphConstraints(width: width));
|
|
|
|
context.canvas.drawParagraph(_paragraph, offset);
|
|
}
|
|
} catch (e) { } // ignore: empty_catches
|
|
}
|
|
}
|