• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2015 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5import 'dart:ui' as ui show Image, ImageFilter;
6
7import 'package:flutter/foundation.dart';
8import 'package:flutter/gestures.dart';
9import 'package:flutter/rendering.dart';
10import 'package:flutter/services.dart';
11
12import 'debug.dart';
13import 'framework.dart';
14import 'localizations.dart';
15import 'widget_span.dart';
16
17export 'package:flutter/animation.dart';
18export 'package:flutter/foundation.dart' show
19  ChangeNotifier,
20  FlutterErrorDetails,
21  Listenable,
22  TargetPlatform,
23  ValueNotifier;
24export 'package:flutter/painting.dart';
25export 'package:flutter/rendering.dart' show
26  AlignmentTween,
27  AlignmentGeometryTween,
28  Axis,
29  BoxConstraints,
30  CrossAxisAlignment,
31  CustomClipper,
32  CustomPainter,
33  CustomPainterSemantics,
34  DecorationPosition,
35  FlexFit,
36  FlowDelegate,
37  FlowPaintingContext,
38  FractionalOffsetTween,
39  HitTestBehavior,
40  LayerLink,
41  MainAxisAlignment,
42  MainAxisSize,
43  MultiChildLayoutDelegate,
44  Overflow,
45  PaintingContext,
46  PointerCancelEvent,
47  PointerCancelEventListener,
48  PointerDownEvent,
49  PointerDownEventListener,
50  PointerEvent,
51  PointerMoveEvent,
52  PointerMoveEventListener,
53  PointerUpEvent,
54  PointerUpEventListener,
55  RelativeRect,
56  SemanticsBuilderCallback,
57  ShaderCallback,
58  ShapeBorderClipper,
59  SingleChildLayoutDelegate,
60  StackFit,
61  TextOverflow,
62  ValueChanged,
63  ValueGetter,
64  WrapAlignment,
65  WrapCrossAlignment;
66
67// Examples can assume:
68// class TestWidget extends StatelessWidget { @override Widget build(BuildContext context) => const Placeholder(); }
69// WidgetTester tester;
70// bool _visible;
71// class Sky extends CustomPainter { @override void paint(Canvas c, Size s) => null; @override bool shouldRepaint(Sky s) => false; }
72// BuildContext context;
73// dynamic userAvatarUrl;
74
75// BIDIRECTIONAL TEXT SUPPORT
76
77/// A widget that determines the ambient directionality of text and
78/// text-direction-sensitive render objects.
79///
80/// For example, [Padding] depends on the [Directionality] to resolve
81/// [EdgeInsetsDirectional] objects into absolute [EdgeInsets] objects.
82class Directionality extends InheritedWidget {
83  /// Creates a widget that determines the directionality of text and
84  /// text-direction-sensitive render objects.
85  ///
86  /// The [textDirection] and [child] arguments must not be null.
87  const Directionality({
88    Key key,
89    @required this.textDirection,
90    @required Widget child,
91  }) : assert(textDirection != null),
92       assert(child != null),
93       super(key: key, child: child);
94
95  /// The text direction for this subtree.
96  final TextDirection textDirection;
97
98  /// The text direction from the closest instance of this class that encloses
99  /// the given context.
100  ///
101  /// If there is no [Directionality] ancestor widget in the tree at the given
102  /// context, then this will return null.
103  ///
104  /// Typical usage is as follows:
105  ///
106  /// ```dart
107  /// TextDirection textDirection = Directionality.of(context);
108  /// ```
109  static TextDirection of(BuildContext context) {
110    final Directionality widget = context.inheritFromWidgetOfExactType(Directionality);
111    return widget?.textDirection;
112  }
113
114  @override
115  bool updateShouldNotify(Directionality oldWidget) => textDirection != oldWidget.textDirection;
116
117  @override
118  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
119    super.debugFillProperties(properties);
120    properties.add(EnumProperty<TextDirection>('textDirection', textDirection));
121  }
122}
123
124
125// PAINTING NODES
126
127/// A widget that makes its child partially transparent.
128///
129/// This class paints its child into an intermediate buffer and then blends the
130/// child back into the scene partially transparent.
131///
132/// For values of opacity other than 0.0 and 1.0, this class is relatively
133/// expensive because it requires painting the child into an intermediate
134/// buffer. For the value 0.0, the child is simply not painted at all. For the
135/// value 1.0, the child is painted immediately without an intermediate buffer.
136///
137/// {@youtube 560 315 https://www.youtube.com/watch?v=9hltevOHQBw}
138///
139/// {@tool sample}
140///
141/// This example shows some [Text] when the `_visible` member field is true, and
142/// hides it when it is false:
143///
144/// ```dart
145/// Opacity(
146///   opacity: _visible ? 1.0 : 0.0,
147///   child: const Text('Now you see me, now you don\'t!'),
148/// )
149/// ```
150/// {@end-tool}
151///
152/// This is more efficient than adding and removing the child widget from the
153/// tree on demand.
154///
155/// ## Performance considerations for opacity animation
156///
157/// Animating an [Opacity] widget directly causes the widget (and possibly its
158/// subtree) to rebuild each frame, which is not very efficient. Consider using
159/// an [AnimatedOpacity] instead.
160///
161/// ## Transparent image
162///
163/// If only a single [Image] or [Color] needs to be composited with an opacity
164/// between 0.0 and 1.0, it's much faster to directly use them without [Opacity]
165/// widgets.
166///
167/// For example, `Container(color: Color.fromRGBO(255, 0, 0, 0.5))` is much
168/// faster than `Opacity(opacity: 0.5, child: Container(color: Colors.red))`.
169///
170/// {@tool sample}
171///
172/// The following example draws an [Image] with 0.5 opacity without using
173/// [Opacity]:
174///
175/// ```dart
176/// Image.network(
177///   'https://raw.githubusercontent.com/flutter/assets-for-api-docs/master/packages/diagrams/assets/blend_mode_destination.jpeg',
178///   color: Color.fromRGBO(255, 255, 255, 0.5),
179///   colorBlendMode: BlendMode.modulate
180/// )
181/// ```
182///
183/// {@end-tool}
184///
185/// Directly drawing an [Image] or [Color] with opacity is faster than using
186/// [Opacity] on top of them because [Opacity] could apply the opacity to a
187/// group of widgets and therefore a costly offscreen buffer will be used.
188/// Drawing content into the offscreen buffer may also trigger render target
189/// switches and such switching is particularly slow in older GPUs.
190///
191/// See also:
192///
193///  * [Visibility], which can hide a child more efficiently (albeit less
194///    subtly, because it is either visible or hidden, rather than allowing
195///    fractional opacity values).
196///  * [ShaderMask], which can apply more elaborate effects to its child.
197///  * [Transform], which applies an arbitrary transform to its child widget at
198///    paint time.
199///  * [AnimatedOpacity], which uses an animation internally to efficiently
200///    animate opacity.
201///  * [FadeTransition], which uses a provided animation to efficiently animate
202///    opacity.
203///  * [Image], which can directly provide a partially transparent image with
204///    much less performance hit.
205class Opacity extends SingleChildRenderObjectWidget {
206  /// Creates a widget that makes its child partially transparent.
207  ///
208  /// The [opacity] argument must not be null and must be between 0.0 and 1.0
209  /// (inclusive).
210  const Opacity({
211    Key key,
212    @required this.opacity,
213    this.alwaysIncludeSemantics = false,
214    Widget child,
215  }) : assert(opacity != null && opacity >= 0.0 && opacity <= 1.0),
216       assert(alwaysIncludeSemantics != null),
217       super(key: key, child: child);
218
219  /// The fraction to scale the child's alpha value.
220  ///
221  /// An opacity of 1.0 is fully opaque. An opacity of 0.0 is fully transparent
222  /// (i.e., invisible).
223  ///
224  /// The opacity must not be null.
225  ///
226  /// Values 1.0 and 0.0 are painted with a fast path. Other values
227  /// require painting the child into an intermediate buffer, which is
228  /// expensive.
229  final double opacity;
230
231  /// Whether the semantic information of the children is always included.
232  ///
233  /// Defaults to false.
234  ///
235  /// When true, regardless of the opacity settings the child semantic
236  /// information is exposed as if the widget were fully visible. This is
237  /// useful in cases where labels may be hidden during animations that
238  /// would otherwise contribute relevant semantics.
239  final bool alwaysIncludeSemantics;
240
241  @override
242  RenderOpacity createRenderObject(BuildContext context) {
243    return RenderOpacity(
244      opacity: opacity,
245      alwaysIncludeSemantics: alwaysIncludeSemantics,
246    );
247  }
248
249  @override
250  void updateRenderObject(BuildContext context, RenderOpacity renderObject) {
251    renderObject
252      ..opacity = opacity
253      ..alwaysIncludeSemantics = alwaysIncludeSemantics;
254  }
255
256  @override
257  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
258    super.debugFillProperties(properties);
259    properties.add(DoubleProperty('opacity', opacity));
260    properties.add(FlagProperty('alwaysIncludeSemantics', value: alwaysIncludeSemantics, ifTrue: 'alwaysIncludeSemantics'));
261  }
262}
263
264/// A widget that applies a mask generated by a [Shader] to its child.
265///
266/// For example, [ShaderMask] can be used to gradually fade out the edge
267/// of a child by using a [new ui.Gradient.linear] mask.
268///
269/// {@tool sample}
270///
271/// This example makes the text look like it is on fire:
272///
273/// ```dart
274/// ShaderMask(
275///   shaderCallback: (Rect bounds) {
276///     return RadialGradient(
277///       center: Alignment.topLeft,
278///       radius: 1.0,
279///       colors: <Color>[Colors.yellow, Colors.deepOrange.shade900],
280///       tileMode: TileMode.mirror,
281///     ).createShader(bounds);
282///   },
283///   child: const Text('I’m burning the memories'),
284/// )
285/// ```
286/// {@end-tool}
287///
288/// See also:
289///
290///  * [Opacity], which can apply a uniform alpha effect to its child.
291///  * [CustomPaint], which lets you draw directly on the canvas.
292///  * [DecoratedBox], for another approach at decorating child widgets.
293///  * [BackdropFilter], which applies an image filter to the background.
294class ShaderMask extends SingleChildRenderObjectWidget {
295  /// Creates a widget that applies a mask generated by a [Shader] to its child.
296  ///
297  /// The [shaderCallback] and [blendMode] arguments must not be null.
298  const ShaderMask({
299    Key key,
300    @required this.shaderCallback,
301    this.blendMode = BlendMode.modulate,
302    Widget child,
303  }) : assert(shaderCallback != null),
304       assert(blendMode != null),
305       super(key: key, child: child);
306
307  /// Called to create the [dart:ui.Shader] that generates the mask.
308  ///
309  /// The shader callback is called with the current size of the child so that
310  /// it can customize the shader to the size and location of the child.
311  ///
312  /// Typically this will use a [LinearGradient], [RadialGradient], or
313  /// [SweepGradient] to create the [dart:ui.Shader], though the
314  /// [dart:ui.ImageShader] class could also be used.
315  final ShaderCallback shaderCallback;
316
317  /// The [BlendMode] to use when applying the shader to the child.
318  ///
319  /// The default, [BlendMode.modulate], is useful for applying an alpha blend
320  /// to the child. Other blend modes can be used to create other effects.
321  final BlendMode blendMode;
322
323  @override
324  RenderShaderMask createRenderObject(BuildContext context) {
325    return RenderShaderMask(
326      shaderCallback: shaderCallback,
327      blendMode: blendMode,
328    );
329  }
330
331  @override
332  void updateRenderObject(BuildContext context, RenderShaderMask renderObject) {
333    renderObject
334      ..shaderCallback = shaderCallback
335      ..blendMode = blendMode;
336  }
337}
338
339/// A widget that applies a filter to the existing painted content and then
340/// paints [child].
341///
342/// The filter will be applied to all the area within its parent or ancestor
343/// widget's clip. If there's no clip, the filter will be applied to the full
344/// screen.
345///
346/// {@youtube 560 315 https://www.youtube.com/watch?v=dYRs7Q1vfYI}
347///
348/// {@tool sample}
349/// If the [BackdropFilter] needs to be applied to an area that exactly matches
350/// its child, wraps the [BackdropFilter] with a clip widget that clips exactly
351/// to that child.
352///
353/// ```dart
354/// Stack(
355///   fit: StackFit.expand,
356///   children: <Widget>[
357///     Text('0' * 10000),
358///     Center(
359///       child: ClipRect(  // <-- clips to the 200x200 [Container] below
360///         child: BackdropFilter(
361///           filter: ui.ImageFilter.blur(
362///             sigmaX: 5.0,
363///             sigmaY: 5.0,
364///           ),
365///           child: Container(
366///             alignment: Alignment.center,
367///             width: 200.0,
368///             height: 200.0,
369///             child: Text('Hello World'),
370///           ),
371///         ),
372///       ),
373///     ),
374///   ],
375/// )
376/// ```
377/// {@end-tool}
378///
379/// This effect is relatively expensive, especially if the filter is non-local,
380/// such as a blur.
381///
382/// See also:
383///
384///  * [DecoratedBox], which draws a background under (or over) a widget.
385///  * [Opacity], which changes the opacity of the widget itself.
386class BackdropFilter extends SingleChildRenderObjectWidget {
387  /// Creates a backdrop filter.
388  ///
389  /// The [filter] argument must not be null.
390  const BackdropFilter({
391    Key key,
392    @required this.filter,
393    Widget child,
394  }) : assert(filter != null),
395       super(key: key, child: child);
396
397  /// The image filter to apply to the existing painted content before painting the child.
398  ///
399  /// For example, consider using [ImageFilter.blur] to create a backdrop
400  /// blur effect
401  final ui.ImageFilter filter;
402
403  @override
404  RenderBackdropFilter createRenderObject(BuildContext context) {
405    return RenderBackdropFilter(filter: filter);
406  }
407
408  @override
409  void updateRenderObject(BuildContext context, RenderBackdropFilter renderObject) {
410    renderObject.filter = filter;
411  }
412}
413
414/// A widget that provides a canvas on which to draw during the paint phase.
415///
416/// When asked to paint, [CustomPaint] first asks its [painter] to paint on the
417/// current canvas, then it paints its child, and then, after painting its
418/// child, it asks its [foregroundPainter] to paint. The coordinate system of the
419/// canvas matches the coordinate system of the [CustomPaint] object. The
420/// painters are expected to paint within a rectangle starting at the origin and
421/// encompassing a region of the given size. (If the painters paint outside
422/// those bounds, there might be insufficient memory allocated to rasterize the
423/// painting commands and the resulting behavior is undefined.) To enforce
424/// painting within those bounds, consider wrapping this [CustomPaint] with a
425/// [ClipRect] widget.
426///
427/// Painters are implemented by subclassing [CustomPainter].
428///
429/// {@youtube 560 315 https://www.youtube.com/watch?v=kp14Y4uHpHs}
430///
431/// Because custom paint calls its painters during paint, you cannot call
432/// `setState` or `markNeedsLayout` during the callback (the layout for this
433/// frame has already happened).
434///
435/// Custom painters normally size themselves to their child. If they do not have
436/// a child, they attempt to size themselves to the [size], which defaults to
437/// [Size.zero]. [size] must not be null.
438///
439/// [isComplex] and [willChange] are hints to the compositor's raster cache
440/// and must not be null.
441///
442/// {@tool sample}
443///
444/// This example shows how the sample custom painter shown at [CustomPainter]
445/// could be used in a [CustomPaint] widget to display a background to some
446/// text.
447///
448/// ```dart
449/// CustomPaint(
450///   painter: Sky(),
451///   child: Center(
452///     child: Text(
453///       'Once upon a time...',
454///       style: const TextStyle(
455///         fontSize: 40.0,
456///         fontWeight: FontWeight.w900,
457///         color: Color(0xFFFFFFFF),
458///       ),
459///     ),
460///   ),
461/// )
462/// ```
463/// {@end-tool}
464///
465/// See also:
466///
467///  * [CustomPainter], the class to extend when creating custom painters.
468///  * [Canvas], the class that a custom painter uses to paint.
469class CustomPaint extends SingleChildRenderObjectWidget {
470  /// Creates a widget that delegates its painting.
471  const CustomPaint({
472    Key key,
473    this.painter,
474    this.foregroundPainter,
475    this.size = Size.zero,
476    this.isComplex = false,
477    this.willChange = false,
478    Widget child,
479  }) : assert(size != null),
480       assert(isComplex != null),
481       assert(willChange != null),
482       super(key: key, child: child);
483
484  /// The painter that paints before the children.
485  final CustomPainter painter;
486
487  /// The painter that paints after the children.
488  final CustomPainter foregroundPainter;
489
490  /// The size that this [CustomPaint] should aim for, given the layout
491  /// constraints, if there is no child.
492  ///
493  /// Defaults to [Size.zero].
494  ///
495  /// If there's a child, this is ignored, and the size of the child is used
496  /// instead.
497  final Size size;
498
499  /// Whether the painting is complex enough to benefit from caching.
500  ///
501  /// The compositor contains a raster cache that holds bitmaps of layers in
502  /// order to avoid the cost of repeatedly rendering those layers on each
503  /// frame. If this flag is not set, then the compositor will apply its own
504  /// heuristics to decide whether the this layer is complex enough to benefit
505  /// from caching.
506  final bool isComplex;
507
508  /// Whether the raster cache should be told that this painting is likely
509  /// to change in the next frame.
510  final bool willChange;
511
512  @override
513  RenderCustomPaint createRenderObject(BuildContext context) {
514    return RenderCustomPaint(
515      painter: painter,
516      foregroundPainter: foregroundPainter,
517      preferredSize: size,
518      isComplex: isComplex,
519      willChange: willChange,
520    );
521  }
522
523  @override
524  void updateRenderObject(BuildContext context, RenderCustomPaint renderObject) {
525    renderObject
526      ..painter = painter
527      ..foregroundPainter = foregroundPainter
528      ..preferredSize = size
529      ..isComplex = isComplex
530      ..willChange = willChange;
531  }
532
533  @override
534  void didUnmountRenderObject(RenderCustomPaint renderObject) {
535    renderObject
536      ..painter = null
537      ..foregroundPainter = null;
538  }
539}
540
541/// A widget that clips its child using a rectangle.
542///
543/// By default, [ClipRect] prevents its child from painting outside its
544/// bounds, but the size and location of the clip rect can be customized using a
545/// custom [clipper].
546///
547/// [ClipRect] is commonly used with these widgets, which commonly paint outside
548/// their bounds:
549///
550///  * [CustomPaint]
551///  * [CustomSingleChildLayout]
552///  * [CustomMultiChildLayout]
553///  * [Align] and [Center] (e.g., if [Align.widthFactor] or
554///    [Align.heightFactor] is less than 1.0).
555///  * [OverflowBox]
556///  * [SizedOverflowBox]
557///
558/// {@tool sample}
559///
560/// For example, by combining a [ClipRect] with an [Align], one can show just
561/// the top half of an [Image]:
562///
563/// ```dart
564/// ClipRect(
565///   child: Align(
566///     alignment: Alignment.topCenter,
567///     heightFactor: 0.5,
568///     child: Image.network(userAvatarUrl),
569///   ),
570/// )
571/// ```
572/// {@end-tool}
573///
574/// See also:
575///
576///  * [CustomClipper], for information about creating custom clips.
577///  * [ClipRRect], for a clip with rounded corners.
578///  * [ClipOval], for an elliptical clip.
579///  * [ClipPath], for an arbitrarily shaped clip.
580class ClipRect extends SingleChildRenderObjectWidget {
581  /// Creates a rectangular clip.
582  ///
583  /// If [clipper] is null, the clip will match the layout size and position of
584  /// the child.
585  const ClipRect({ Key key, this.clipper, this.clipBehavior = Clip.hardEdge, Widget child }) : super(key: key, child: child);
586
587  /// If non-null, determines which clip to use.
588  final CustomClipper<Rect> clipper;
589
590  /// {@macro flutter.clipper.clipBehavior}
591  final Clip clipBehavior;
592
593  @override
594  RenderClipRect createRenderObject(BuildContext context) => RenderClipRect(clipper: clipper, clipBehavior: clipBehavior);
595
596  @override
597  void updateRenderObject(BuildContext context, RenderClipRect renderObject) {
598    renderObject
599      ..clipper = clipper
600      ..clipBehavior = clipBehavior;
601  }
602
603  @override
604  void didUnmountRenderObject(RenderClipRect renderObject) {
605    renderObject.clipper = null;
606  }
607
608  @override
609  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
610    super.debugFillProperties(properties);
611    properties.add(DiagnosticsProperty<CustomClipper<Rect>>('clipper', clipper, defaultValue: null));
612  }
613}
614
615/// A widget that clips its child using a rounded rectangle.
616///
617/// By default, [ClipRRect] uses its own bounds as the base rectangle for the
618/// clip, but the size and location of the clip can be customized using a custom
619/// [clipper].
620///
621/// {@youtube 560 315 https://www.youtube.com/watch?v=eI43jkQkrvs}
622///
623/// See also:
624///
625///  * [CustomClipper], for information about creating custom clips.
626///  * [ClipRect], for more efficient clips without rounded corners.
627///  * [ClipOval], for an elliptical clip.
628///  * [ClipPath], for an arbitrarily shaped clip.
629class ClipRRect extends SingleChildRenderObjectWidget {
630  /// Creates a rounded-rectangular clip.
631  ///
632  /// The [borderRadius] defaults to [BorderRadius.zero], i.e. a rectangle with
633  /// right-angled corners.
634  ///
635  /// If [clipper] is non-null, then [borderRadius] is ignored.
636  const ClipRRect({
637    Key key,
638    this.borderRadius,
639    this.clipper,
640    this.clipBehavior = Clip.antiAlias,
641    Widget child,
642  }) : assert(borderRadius != null || clipper != null),
643       assert(clipBehavior != null),
644       super(key: key, child: child);
645
646  /// The border radius of the rounded corners.
647  ///
648  /// Values are clamped so that horizontal and vertical radii sums do not
649  /// exceed width/height.
650  ///
651  /// This value is ignored if [clipper] is non-null.
652  final BorderRadius borderRadius;
653
654  /// If non-null, determines which clip to use.
655  final CustomClipper<RRect> clipper;
656
657  /// {@macro flutter.clipper.clipBehavior}
658  final Clip clipBehavior;
659
660  @override
661  RenderClipRRect createRenderObject(BuildContext context) => RenderClipRRect(borderRadius: borderRadius, clipper: clipper, clipBehavior: clipBehavior);
662
663  @override
664  void updateRenderObject(BuildContext context, RenderClipRRect renderObject) {
665    renderObject
666      ..borderRadius = borderRadius
667      ..clipBehavior = clipBehavior
668      ..clipper = clipper;
669  }
670
671  @override
672  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
673    super.debugFillProperties(properties);
674    properties.add(DiagnosticsProperty<BorderRadius>('borderRadius', borderRadius, showName: false, defaultValue: null));
675    properties.add(DiagnosticsProperty<CustomClipper<RRect>>('clipper', clipper, defaultValue: null));
676  }
677}
678
679/// A widget that clips its child using an oval.
680///
681/// By default, inscribes an axis-aligned oval into its layout dimensions and
682/// prevents its child from painting outside that oval, but the size and
683/// location of the clip oval can be customized using a custom [clipper].
684///
685/// See also:
686///
687///  * [CustomClipper], for information about creating custom clips.
688///  * [ClipRect], for more efficient clips without rounded corners.
689///  * [ClipRRect], for a clip with rounded corners.
690///  * [ClipPath], for an arbitrarily shaped clip.
691class ClipOval extends SingleChildRenderObjectWidget {
692  /// Creates an oval-shaped clip.
693  ///
694  /// If [clipper] is null, the oval will be inscribed into the layout size and
695  /// position of the child.
696  const ClipOval({ Key key, this.clipper, this.clipBehavior = Clip.antiAlias, Widget child }) : super(key: key, child: child);
697
698  /// If non-null, determines which clip to use.
699  ///
700  /// The delegate returns a rectangle that describes the axis-aligned
701  /// bounding box of the oval. The oval's axes will themselves also
702  /// be axis-aligned.
703  ///
704  /// If the [clipper] delegate is null, then the oval uses the
705  /// widget's bounding box (the layout dimensions of the render
706  /// object) instead.
707  final CustomClipper<Rect> clipper;
708
709  /// {@macro flutter.clipper.clipBehavior}
710  final Clip clipBehavior;
711
712  @override
713  RenderClipOval createRenderObject(BuildContext context) => RenderClipOval(clipper: clipper, clipBehavior: clipBehavior);
714
715  @override
716  void updateRenderObject(BuildContext context, RenderClipOval renderObject) {
717    renderObject
718      ..clipper = clipper
719      ..clipBehavior = clipBehavior;
720  }
721
722  @override
723  void didUnmountRenderObject(RenderClipOval renderObject) {
724    renderObject.clipper = null;
725  }
726
727  @override
728  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
729    super.debugFillProperties(properties);
730    properties.add(DiagnosticsProperty<CustomClipper<Rect>>('clipper', clipper, defaultValue: null));
731  }
732}
733
734/// A widget that clips its child using a path.
735///
736/// Calls a callback on a delegate whenever the widget is to be
737/// painted. The callback returns a path and the widget prevents the
738/// child from painting outside the path.
739///
740/// Clipping to a path is expensive. Certain shapes have more
741/// optimized widgets:
742///
743///  * To clip to a rectangle, consider [ClipRect].
744///  * To clip to an oval or circle, consider [ClipOval].
745///  * To clip to a rounded rectangle, consider [ClipRRect].
746///
747/// To clip to a particular [ShapeBorder], consider using either the
748/// [ClipPath.shape] static method or the [ShapeBorderClipper] custom clipper
749/// class.
750class ClipPath extends SingleChildRenderObjectWidget {
751  /// Creates a path clip.
752  ///
753  /// If [clipper] is null, the clip will be a rectangle that matches the layout
754  /// size and location of the child. However, rather than use this default,
755  /// consider using a [ClipRect], which can achieve the same effect more
756  /// efficiently.
757  const ClipPath({
758    Key key,
759    this.clipper,
760    this.clipBehavior = Clip.antiAlias,
761    Widget child,
762  }) : super(key: key, child: child);
763
764  /// Creates a shape clip.
765  ///
766  /// Uses a [ShapeBorderClipper] to configure the [ClipPath] to clip to the
767  /// given [ShapeBorder].
768  static Widget shape({
769    Key key,
770    @required ShapeBorder shape,
771    Clip clipBehavior = Clip.antiAlias,
772    Widget child,
773  }) {
774    assert(shape != null);
775    return Builder(
776      key: key,
777      builder: (BuildContext context) {
778        return ClipPath(
779          clipper: ShapeBorderClipper(
780            shape: shape,
781            textDirection: Directionality.of(context),
782          ),
783          clipBehavior: clipBehavior,
784          child: child,
785        );
786      },
787    );
788  }
789
790  /// If non-null, determines which clip to use.
791  ///
792  /// The default clip, which is used if this property is null, is the
793  /// bounding box rectangle of the widget. [ClipRect] is a more
794  /// efficient way of obtaining that effect.
795  final CustomClipper<Path> clipper;
796
797  /// {@macro flutter.clipper.clipBehavior}
798  final Clip clipBehavior;
799
800  @override
801  RenderClipPath createRenderObject(BuildContext context) => RenderClipPath(clipper: clipper, clipBehavior: clipBehavior);
802
803  @override
804  void updateRenderObject(BuildContext context, RenderClipPath renderObject) {
805    renderObject
806      ..clipper = clipper
807      ..clipBehavior = clipBehavior;
808  }
809
810  @override
811  void didUnmountRenderObject(RenderClipPath renderObject) {
812    renderObject.clipper = null;
813  }
814
815  @override
816  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
817    super.debugFillProperties(properties);
818    properties.add(DiagnosticsProperty<CustomClipper<Path>>('clipper', clipper, defaultValue: null));
819  }
820}
821
822/// A widget representing a physical layer that clips its children to a shape.
823///
824/// Physical layers cast shadows based on an [elevation] which is nominally in
825/// logical pixels, coming vertically out of the rendering surface.
826///
827/// For shapes that cannot be expressed as a rectangle with rounded corners use
828/// [PhysicalShape].
829///
830/// See also:
831///
832///  * [AnimatedPhysicalModel], which animates property changes smoothly over
833///    a given duration.
834///  * [DecoratedBox], which can apply more arbitrary shadow effects.
835///  * [ClipRect], which applies a clip to its child.
836class PhysicalModel extends SingleChildRenderObjectWidget {
837  /// Creates a physical model with a rounded-rectangular clip.
838  ///
839  /// The [color] is required; physical things have a color.
840  ///
841  /// The [shape], [elevation], [color], and [shadowColor] must not be null.
842  /// Additionally, the [elevation] must be non-negative.
843  const PhysicalModel({
844    Key key,
845    this.shape = BoxShape.rectangle,
846    this.clipBehavior = Clip.none,
847    this.borderRadius,
848    this.elevation = 0.0,
849    @required this.color,
850    this.shadowColor = const Color(0xFF000000),
851    Widget child,
852  }) : assert(shape != null),
853       assert(elevation != null && elevation >= 0.0),
854       assert(color != null),
855       assert(shadowColor != null),
856       super(key: key, child: child);
857
858  /// The type of shape.
859  final BoxShape shape;
860
861  /// {@macro flutter.widgets.Clip}
862  final Clip clipBehavior;
863
864  /// The border radius of the rounded corners.
865  ///
866  /// Values are clamped so that horizontal and vertical radii sums do not
867  /// exceed width/height.
868  ///
869  /// This is ignored if the [shape] is not [BoxShape.rectangle].
870  final BorderRadius borderRadius;
871
872  /// The z-coordinate relative to the parent at which to place this physical
873  /// object.
874  ///
875  /// The value is non-negative.
876  final double elevation;
877
878  /// The background color.
879  final Color color;
880
881  /// The shadow color.
882  final Color shadowColor;
883
884  @override
885  RenderPhysicalModel createRenderObject(BuildContext context) {
886    return RenderPhysicalModel(
887      shape: shape,
888      clipBehavior: clipBehavior,
889      borderRadius: borderRadius,
890      elevation: elevation, color: color,
891      shadowColor: shadowColor,
892    );
893  }
894
895  @override
896  void updateRenderObject(BuildContext context, RenderPhysicalModel renderObject) {
897    renderObject
898      ..shape = shape
899      ..clipBehavior = clipBehavior
900      ..borderRadius = borderRadius
901      ..elevation = elevation
902      ..color = color
903      ..shadowColor = shadowColor;
904  }
905
906  @override
907  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
908    super.debugFillProperties(properties);
909    properties.add(EnumProperty<BoxShape>('shape', shape));
910    properties.add(DiagnosticsProperty<BorderRadius>('borderRadius', borderRadius));
911    properties.add(DoubleProperty('elevation', elevation));
912    properties.add(ColorProperty('color', color));
913    properties.add(ColorProperty('shadowColor', shadowColor));
914  }
915}
916
917/// A widget representing a physical layer that clips its children to a path.
918///
919/// Physical layers cast shadows based on an [elevation] which is nominally in
920/// logical pixels, coming vertically out of the rendering surface.
921///
922/// [PhysicalModel] does the same but only supports shapes that can be expressed
923/// as rectangles with rounded corners.
924///
925/// See also:
926///
927///  * [ShapeBorderClipper], which converts a [ShapeBorder] to a [CustomerClipper], as
928///    needed by this widget.
929class PhysicalShape extends SingleChildRenderObjectWidget {
930  /// Creates a physical model with an arbitrary shape clip.
931  ///
932  /// The [color] is required; physical things have a color.
933  ///
934  /// The [clipper], [elevation], [color], and [shadowColor] must not be null.
935  /// Additionally, the [elevation] must be non-negative.
936  const PhysicalShape({
937    Key key,
938    @required this.clipper,
939    this.clipBehavior = Clip.none,
940    this.elevation = 0.0,
941    @required this.color,
942    this.shadowColor = const Color(0xFF000000),
943    Widget child,
944  }) : assert(clipper != null),
945       assert(clipBehavior != null),
946       assert(elevation != null && elevation >= 0.0),
947       assert(color != null),
948       assert(shadowColor != null),
949       super(key: key, child: child);
950
951  /// Determines which clip to use.
952  ///
953  /// If the path in question is expressed as a [ShapeBorder] subclass,
954  /// consider using the [ShapeBorderClipper] delegate class to adapt the
955  /// shape for use with this widget.
956  final CustomClipper<Path> clipper;
957
958  /// {@macro flutter.widgets.Clip}
959  final Clip clipBehavior;
960
961  /// The z-coordinate relative to the parent at which to place this physical
962  /// object.
963  ///
964  /// The value is non-negative.
965  final double elevation;
966
967  /// The background color.
968  final Color color;
969
970  /// When elevation is non zero the color to use for the shadow color.
971  final Color shadowColor;
972
973  @override
974  RenderPhysicalShape createRenderObject(BuildContext context) {
975    return RenderPhysicalShape(
976      clipper: clipper,
977      clipBehavior: clipBehavior,
978      elevation: elevation,
979      color: color,
980      shadowColor: shadowColor,
981    );
982  }
983
984  @override
985  void updateRenderObject(BuildContext context, RenderPhysicalShape renderObject) {
986    renderObject
987      ..clipper = clipper
988      ..clipBehavior = clipBehavior
989      ..elevation = elevation
990      ..color = color
991      ..shadowColor = shadowColor;
992  }
993
994  @override
995  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
996    super.debugFillProperties(properties);
997    properties.add(DiagnosticsProperty<CustomClipper<Path>>('clipper', clipper));
998    properties.add(DoubleProperty('elevation', elevation));
999    properties.add(ColorProperty('color', color));
1000    properties.add(ColorProperty('shadowColor', shadowColor));
1001  }
1002}
1003
1004// POSITIONING AND SIZING NODES
1005
1006/// A widget that applies a transformation before painting its child.
1007///
1008/// Unlike [RotatedBox], which applies a rotation prior to layout, this object
1009/// applies its transformation just prior to painting, which means the
1010/// transformation is not taken into account when calculating how much space
1011/// this widget's child (and thus this widget) consumes.
1012///
1013/// {@youtube 560 315 https://www.youtube.com/watch?v=9z_YNlRlWfA}
1014///
1015/// {@tool sample}
1016///
1017/// This example rotates and skews an orange box containing text, keeping the
1018/// top right corner pinned to its original position.
1019///
1020/// ```dart
1021/// Container(
1022///   color: Colors.black,
1023///   child: Transform(
1024///     alignment: Alignment.topRight,
1025///     transform: Matrix4.skewY(0.3)..rotateZ(-math.pi / 12.0),
1026///     child: Container(
1027///       padding: const EdgeInsets.all(8.0),
1028///       color: const Color(0xFFE8581C),
1029///       child: const Text('Apartment for rent!'),
1030///     ),
1031///   ),
1032/// )
1033/// ```
1034/// {@end-tool}
1035///
1036/// See also:
1037///
1038///  * [RotatedBox], which rotates the child widget during layout, not just
1039///    during painting.
1040///  * [FractionalTranslation], which applies a translation to the child
1041///    that is relative to the child's size.
1042///  * [FittedBox], which sizes and positions its child widget to fit the parent
1043///    according to a given [BoxFit] discipline.
1044class Transform extends SingleChildRenderObjectWidget {
1045  /// Creates a widget that transforms its child.
1046  ///
1047  /// The [transform] argument must not be null.
1048  const Transform({
1049    Key key,
1050    @required this.transform,
1051    this.origin,
1052    this.alignment,
1053    this.transformHitTests = true,
1054    Widget child,
1055  }) : assert(transform != null),
1056       super(key: key, child: child);
1057
1058  /// Creates a widget that transforms its child using a rotation around the
1059  /// center.
1060  ///
1061  /// The `angle` argument must not be null. It gives the rotation in clockwise
1062  /// radians.
1063  ///
1064  /// {@tool sample}
1065  ///
1066  /// This example rotates an orange box containing text around its center by
1067  /// fifteen degrees.
1068  ///
1069  /// ```dart
1070  /// Transform.rotate(
1071  ///   angle: -math.pi / 12.0,
1072  ///   child: Container(
1073  ///     padding: const EdgeInsets.all(8.0),
1074  ///     color: const Color(0xFFE8581C),
1075  ///     child: const Text('Apartment for rent!'),
1076  ///   ),
1077  /// )
1078  /// ```
1079  /// {@end-tool}
1080  ///
1081  /// See also:
1082  ///
1083  ///  * [RotationTransition], which animates changes in rotation smoothly
1084  ///    over a given duration.
1085  Transform.rotate({
1086    Key key,
1087    @required double angle,
1088    this.origin,
1089    this.alignment = Alignment.center,
1090    this.transformHitTests = true,
1091    Widget child,
1092  }) : transform = Matrix4.rotationZ(angle),
1093       super(key: key, child: child);
1094
1095  /// Creates a widget that transforms its child using a translation.
1096  ///
1097  /// The `offset` argument must not be null. It specifies the translation.
1098  ///
1099  /// {@tool sample}
1100  ///
1101  /// This example shifts the silver-colored child down by fifteen pixels.
1102  ///
1103  /// ```dart
1104  /// Transform.translate(
1105  ///   offset: const Offset(0.0, 15.0),
1106  ///   child: Container(
1107  ///     padding: const EdgeInsets.all(8.0),
1108  ///     color: const Color(0xFF7F7F7F),
1109  ///     child: const Text('Quarter'),
1110  ///   ),
1111  /// )
1112  /// ```
1113  /// {@end-tool}
1114  Transform.translate({
1115    Key key,
1116    @required Offset offset,
1117    this.transformHitTests = true,
1118    Widget child,
1119  }) : transform = Matrix4.translationValues(offset.dx, offset.dy, 0.0),
1120       origin = null,
1121       alignment = null,
1122       super(key: key, child: child);
1123
1124  /// Creates a widget that scales its child uniformly.
1125  ///
1126  /// The `scale` argument must not be null. It gives the scalar by which
1127  /// to multiply the `x` and `y` axes.
1128  ///
1129  /// The [alignment] controls the origin of the scale; by default, this is
1130  /// the center of the box.
1131  ///
1132  /// {@tool sample}
1133  ///
1134  /// This example shrinks an orange box containing text such that each dimension
1135  /// is half the size it would otherwise be.
1136  ///
1137  /// ```dart
1138  /// Transform.scale(
1139  ///   scale: 0.5,
1140  ///   child: Container(
1141  ///     padding: const EdgeInsets.all(8.0),
1142  ///     color: const Color(0xFFE8581C),
1143  ///     child: const Text('Bad Ideas'),
1144  ///   ),
1145  /// )
1146  /// ```
1147  /// {@end-tool}
1148  ///
1149  /// See also:
1150  ///
1151  ///  * [ScaleTransition], which animates changes in scale smoothly
1152  ///    over a given duration.
1153  Transform.scale({
1154    Key key,
1155    @required double scale,
1156    this.origin,
1157    this.alignment = Alignment.center,
1158    this.transformHitTests = true,
1159    Widget child,
1160  }) : transform = Matrix4.diagonal3Values(scale, scale, 1.0),
1161       super(key: key, child: child);
1162
1163  /// The matrix to transform the child by during painting.
1164  final Matrix4 transform;
1165
1166  /// The origin of the coordinate system (relative to the upper left corder of
1167  /// this render object) in which to apply the matrix.
1168  ///
1169  /// Setting an origin is equivalent to conjugating the transform matrix by a
1170  /// translation. This property is provided just for convenience.
1171  final Offset origin;
1172
1173  /// The alignment of the origin, relative to the size of the box.
1174  ///
1175  /// This is equivalent to setting an origin based on the size of the box.
1176  /// If it is specified at the same time as the [origin], both are applied.
1177  ///
1178  /// An [AlignmentDirectional.start] value is the same as an [Alignment]
1179  /// whose [Alignment.x] value is `-1.0` if [textDirection] is
1180  /// [TextDirection.ltr], and `1.0` if [textDirection] is [TextDirection.rtl].
1181  /// Similarly [AlignmentDirectional.end] is the same as an [Alignment]
1182  /// whose [Alignment.x] value is `1.0` if [textDirection] is
1183  /// [TextDirection.ltr], and `-1.0` if [textDirection] is [TextDirection.rtl].
1184  final AlignmentGeometry alignment;
1185
1186  /// Whether to apply the transformation when performing hit tests.
1187  final bool transformHitTests;
1188
1189  @override
1190  RenderTransform createRenderObject(BuildContext context) {
1191    return RenderTransform(
1192      transform: transform,
1193      origin: origin,
1194      alignment: alignment,
1195      textDirection: Directionality.of(context),
1196      transformHitTests: transformHitTests,
1197    );
1198  }
1199
1200  @override
1201  void updateRenderObject(BuildContext context, RenderTransform renderObject) {
1202    renderObject
1203      ..transform = transform
1204      ..origin = origin
1205      ..alignment = alignment
1206      ..textDirection = Directionality.of(context)
1207      ..transformHitTests = transformHitTests;
1208  }
1209}
1210
1211/// A widget that can be targeted by a [CompositedTransformFollower].
1212///
1213/// When this widget is composited during the compositing phase (which comes
1214/// after the paint phase, as described in [WidgetsBinding.drawFrame]), it
1215/// updates the [link] object so that any [CompositedTransformFollower] widgets
1216/// that are subsequently composited in the same frame and were given the same
1217/// [LayerLink] can position themselves at the same screen location.
1218///
1219/// A single [CompositedTransformTarget] can be followed by multiple
1220/// [CompositedTransformFollower] widgets.
1221///
1222/// The [CompositedTransformTarget] must come earlier in the paint order than
1223/// any linked [CompositedTransformFollower]s.
1224///
1225/// See also:
1226///
1227///  * [CompositedTransformFollower], the widget that can target this one.
1228///  * [LeaderLayer], the layer that implements this widget's logic.
1229class CompositedTransformTarget extends SingleChildRenderObjectWidget {
1230  /// Creates a composited transform target widget.
1231  ///
1232  /// The [link] property must not be null, and must not be currently being used
1233  /// by any other [CompositedTransformTarget] object that is in the tree.
1234  const CompositedTransformTarget({
1235    Key key,
1236    @required this.link,
1237    Widget child,
1238  }) : assert(link != null),
1239       super(key: key, child: child);
1240
1241  /// The link object that connects this [CompositedTransformTarget] with one or
1242  /// more [CompositedTransformFollower]s.
1243  ///
1244  /// This property must not be null. The object must not be associated with
1245  /// another [CompositedTransformTarget] that is also being painted.
1246  final LayerLink link;
1247
1248  @override
1249  RenderLeaderLayer createRenderObject(BuildContext context) {
1250    return RenderLeaderLayer(
1251      link: link,
1252    );
1253  }
1254
1255  @override
1256  void updateRenderObject(BuildContext context, RenderLeaderLayer renderObject) {
1257    renderObject
1258      ..link = link;
1259  }
1260}
1261
1262/// A widget that follows a [CompositedTransformTarget].
1263///
1264/// When this widget is composited during the compositing phase (which comes
1265/// after the paint phase, as described in [WidgetsBinding.drawFrame]), it
1266/// applies a transformation that causes it to provide its child with a
1267/// coordinate space that matches that of the linked [CompositedTransformTarget]
1268/// widget, offset by [offset].
1269///
1270/// The [LayerLink] object used as the [link] must be the same object as that
1271/// provided to the matching [CompositedTransformTarget].
1272///
1273/// The [CompositedTransformTarget] must come earlier in the paint order than
1274/// this [CompositedTransformFollower].
1275///
1276/// Hit testing on descendants of this widget will only work if the target
1277/// position is within the box that this widget's parent considers to be
1278/// hittable. If the parent covers the screen, this is trivially achievable, so
1279/// this widget is usually used as the root of an [OverlayEntry] in an app-wide
1280/// [Overlay] (e.g. as created by the [MaterialApp] widget's [Navigator]).
1281///
1282/// See also:
1283///
1284///  * [CompositedTransformTarget], the widget that this widget can target.
1285///  * [FollowerLayer], the layer that implements this widget's logic.
1286///  * [Transform], which applies an arbitrary transform to a child.
1287class CompositedTransformFollower extends SingleChildRenderObjectWidget {
1288  /// Creates a composited transform target widget.
1289  ///
1290  /// The [link] property must not be null. If it was also provided to a
1291  /// [CompositedTransformTarget], that widget must come earlier in the paint
1292  /// order.
1293  ///
1294  /// The [showWhenUnlinked] and [offset] properties must also not be null.
1295  const CompositedTransformFollower({
1296    Key key,
1297    @required this.link,
1298    this.showWhenUnlinked = true,
1299    this.offset = Offset.zero,
1300    Widget child,
1301  }) : assert(link != null),
1302       assert(showWhenUnlinked != null),
1303       assert(offset != null),
1304       super(key: key, child: child);
1305
1306  /// The link object that connects this [CompositedTransformFollower] with a
1307  /// [CompositedTransformTarget].
1308  ///
1309  /// This property must not be null.
1310  final LayerLink link;
1311
1312  /// Whether to show the widget's contents when there is no corresponding
1313  /// [CompositedTransformTarget] with the same [link].
1314  ///
1315  /// When the widget is linked, the child is positioned such that it has the
1316  /// same global position as the linked [CompositedTransformTarget].
1317  ///
1318  /// When the widget is not linked, then: if [showWhenUnlinked] is true, the
1319  /// child is visible and not repositioned; if it is false, then child is
1320  /// hidden.
1321  final bool showWhenUnlinked;
1322
1323  /// The offset to apply to the origin of the linked
1324  /// [CompositedTransformTarget] to obtain this widget's origin.
1325  final Offset offset;
1326
1327  @override
1328  RenderFollowerLayer createRenderObject(BuildContext context) {
1329    return RenderFollowerLayer(
1330      link: link,
1331      showWhenUnlinked: showWhenUnlinked,
1332      offset: offset,
1333    );
1334  }
1335
1336  @override
1337  void updateRenderObject(BuildContext context, RenderFollowerLayer renderObject) {
1338    renderObject
1339      ..link = link
1340      ..showWhenUnlinked = showWhenUnlinked
1341      ..offset = offset;
1342  }
1343}
1344
1345/// Scales and positions its child within itself according to [fit].
1346///
1347/// {@youtube 560 315 https://www.youtube.com/watch?v=T4Uehk3_wlY}
1348///
1349/// See also:
1350///
1351///  * [Transform], which applies an arbitrary transform to its child widget at
1352///    paint time.
1353///  * The [catalog of layout widgets](https://flutter.dev/widgets/layout/).
1354class FittedBox extends SingleChildRenderObjectWidget {
1355  /// Creates a widget that scales and positions its child within itself according to [fit].
1356  ///
1357  /// The [fit] and [alignment] arguments must not be null.
1358  const FittedBox({
1359    Key key,
1360    this.fit = BoxFit.contain,
1361    this.alignment = Alignment.center,
1362    Widget child,
1363  }) : assert(fit != null),
1364       assert(alignment != null),
1365       super(key: key, child: child);
1366
1367  /// How to inscribe the child into the space allocated during layout.
1368  final BoxFit fit;
1369
1370  /// How to align the child within its parent's bounds.
1371  ///
1372  /// An alignment of (-1.0, -1.0) aligns the child to the top-left corner of its
1373  /// parent's bounds. An alignment of (1.0, 0.0) aligns the child to the middle
1374  /// of the right edge of its parent's bounds.
1375  ///
1376  /// Defaults to [Alignment.center].
1377  ///
1378  /// See also:
1379  ///
1380  ///  * [Alignment], a class with convenient constants typically used to
1381  ///    specify an [AlignmentGeometry].
1382  ///  * [AlignmentDirectional], like [Alignment] for specifying alignments
1383  ///    relative to text direction.
1384  final AlignmentGeometry alignment;
1385
1386  @override
1387  RenderFittedBox createRenderObject(BuildContext context) {
1388    return RenderFittedBox(
1389      fit: fit,
1390      alignment: alignment,
1391      textDirection: Directionality.of(context),
1392    );
1393  }
1394
1395  @override
1396  void updateRenderObject(BuildContext context, RenderFittedBox renderObject) {
1397    renderObject
1398      ..fit = fit
1399      ..alignment = alignment
1400      ..textDirection = Directionality.of(context);
1401  }
1402
1403  @override
1404  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
1405    super.debugFillProperties(properties);
1406    properties.add(EnumProperty<BoxFit>('fit', fit));
1407    properties.add(DiagnosticsProperty<AlignmentGeometry>('alignment', alignment));
1408  }
1409}
1410
1411/// Applies a translation transformation before painting its child.
1412///
1413/// The translation is expressed as a [Offset] scaled to the child's size. For
1414/// example, an [Offset] with a `dx` of 0.25 will result in a horizontal
1415/// translation of one quarter the width of the child.
1416///
1417/// Hit tests will only be detected inside the bounds of the
1418/// [FractionalTranslation], even if the contents are offset such that
1419/// they overflow.
1420///
1421/// See also:
1422///
1423///  * [Transform], which applies an arbitrary transform to its child widget at
1424///    paint time.
1425///  * [new Transform.translate], which applies an absolute offset translation
1426///    transformation instead of an offset scaled to the child.
1427///  * The [catalog of layout widgets](https://flutter.dev/widgets/layout/).
1428class FractionalTranslation extends SingleChildRenderObjectWidget {
1429  /// Creates a widget that translates its child's painting.
1430  ///
1431  /// The [translation] argument must not be null.
1432  const FractionalTranslation({
1433    Key key,
1434    @required this.translation,
1435    this.transformHitTests = true,
1436    Widget child,
1437  }) : assert(translation != null),
1438       super(key: key, child: child);
1439
1440  /// The translation to apply to the child, scaled to the child's size.
1441  ///
1442  /// For example, an [Offset] with a `dx` of 0.25 will result in a horizontal
1443  /// translation of one quarter the width of the child.
1444  final Offset translation;
1445
1446  /// Whether to apply the translation when performing hit tests.
1447  final bool transformHitTests;
1448
1449  @override
1450  RenderFractionalTranslation createRenderObject(BuildContext context) {
1451    return RenderFractionalTranslation(
1452      translation: translation,
1453      transformHitTests: transformHitTests,
1454    );
1455  }
1456
1457  @override
1458  void updateRenderObject(BuildContext context, RenderFractionalTranslation renderObject) {
1459    renderObject
1460      ..translation = translation
1461      ..transformHitTests = transformHitTests;
1462  }
1463}
1464
1465/// A widget that rotates its child by a integral number of quarter turns.
1466///
1467/// Unlike [Transform], which applies a transform just prior to painting,
1468/// this object applies its rotation prior to layout, which means the entire
1469/// rotated box consumes only as much space as required by the rotated child.
1470///
1471/// {@tool sample}
1472///
1473/// This snippet rotates the child (some [Text]) so that it renders from bottom
1474/// to top, like an axis label on a graph:
1475///
1476/// ```dart
1477/// RotatedBox(
1478///   quarterTurns: 3,
1479///   child: const Text('Hello World!'),
1480/// )
1481/// ```
1482/// {@end-tool}
1483///
1484/// See also:
1485///
1486///  * [Transform], which is a paint effect that allows you to apply an
1487///    arbitrary transform to a child.
1488///  * [new Transform.rotate], which applies a rotation paint effect.
1489///  * The [catalog of layout widgets](https://flutter.dev/widgets/layout/).
1490class RotatedBox extends SingleChildRenderObjectWidget {
1491  /// A widget that rotates its child.
1492  ///
1493  /// The [quarterTurns] argument must not be null.
1494  const RotatedBox({
1495    Key key,
1496    @required this.quarterTurns,
1497    Widget child,
1498  }) : assert(quarterTurns != null),
1499       super(key: key, child: child);
1500
1501  /// The number of clockwise quarter turns the child should be rotated.
1502  final int quarterTurns;
1503
1504  @override
1505  RenderRotatedBox createRenderObject(BuildContext context) => RenderRotatedBox(quarterTurns: quarterTurns);
1506
1507  @override
1508  void updateRenderObject(BuildContext context, RenderRotatedBox renderObject) {
1509    renderObject.quarterTurns = quarterTurns;
1510  }
1511}
1512
1513/// A widget that insets its child by the given padding.
1514///
1515/// When passing layout constraints to its child, padding shrinks the
1516/// constraints by the given padding, causing the child to layout at a smaller
1517/// size. Padding then sizes itself to its child's size, inflated by the
1518/// padding, effectively creating empty space around the child.
1519///
1520/// {@tool sample}
1521///
1522/// This snippet indents the child (a [Card] with some [Text]) by eight pixels
1523/// in each direction:
1524///
1525/// ```dart
1526/// Padding(
1527///   padding: EdgeInsets.all(8.0),
1528///   child: const Card(child: Text('Hello World!')),
1529/// )
1530/// ```
1531/// {@end-tool}
1532///
1533/// ## Design discussion
1534///
1535/// ### Why use a [Padding] widget rather than a [Container] with a [Container.padding] property?
1536///
1537/// There isn't really any difference between the two. If you supply a
1538/// [Container.padding] argument, [Container] simply builds a [Padding] widget
1539/// for you.
1540///
1541/// [Container] doesn't implement its properties directly. Instead, [Container]
1542/// combines a number of simpler widgets together into a convenient package. For
1543/// example, the [Container.padding] property causes the container to build a
1544/// [Padding] widget and the [Container.decoration] property causes the
1545/// container to build a [DecoratedBox] widget. If you find [Container]
1546/// convenient, feel free to use it. If not, feel free to build these simpler
1547/// widgets in whatever combination meets your needs.
1548///
1549/// In fact, the majority of widgets in Flutter are simply combinations of other
1550/// simpler widgets. Composition, rather than inheritance, is the primary
1551/// mechanism for building up widgets.
1552///
1553/// See also:
1554///
1555///  * [AnimatedPadding], which animates changes in [padding] over a given
1556///    duration.
1557///  * [EdgeInsets], the class that is used to describe the padding dimensions.
1558///  * The [catalog of layout widgets](https://flutter.dev/widgets/layout/).
1559class Padding extends SingleChildRenderObjectWidget {
1560  /// Creates a widget that insets its child.
1561  ///
1562  /// The [padding] argument must not be null.
1563  const Padding({
1564    Key key,
1565    @required this.padding,
1566    Widget child,
1567  }) : assert(padding != null),
1568       super(key: key, child: child);
1569
1570  /// The amount of space by which to inset the child.
1571  final EdgeInsetsGeometry padding;
1572
1573  @override
1574  RenderPadding createRenderObject(BuildContext context) {
1575    return RenderPadding(
1576      padding: padding,
1577      textDirection: Directionality.of(context),
1578    );
1579  }
1580
1581  @override
1582  void updateRenderObject(BuildContext context, RenderPadding renderObject) {
1583    renderObject
1584      ..padding = padding
1585      ..textDirection = Directionality.of(context);
1586  }
1587
1588  @override
1589  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
1590    super.debugFillProperties(properties);
1591    properties.add(DiagnosticsProperty<EdgeInsetsGeometry>('padding', padding));
1592  }
1593}
1594
1595/// A widget that aligns its child within itself and optionally sizes itself
1596/// based on the child's size.
1597///
1598/// For example, to align a box at the bottom right, you would pass this box a
1599/// tight constraint that is bigger than the child's natural size,
1600/// with an alignment of [Alignment.bottomRight].
1601///
1602/// {@youtube 560 315 https://www.youtube.com/watch?v=g2E7yl3MwMk}
1603///
1604/// This widget will be as big as possible if its dimensions are constrained and
1605/// [widthFactor] and [heightFactor] are null. If a dimension is unconstrained
1606/// and the corresponding size factor is null then the widget will match its
1607/// child's size in that dimension. If a size factor is non-null then the
1608/// corresponding dimension of this widget will be the product of the child's
1609/// dimension and the size factor. For example if widthFactor is 2.0 then
1610/// the width of this widget will always be twice its child's width.
1611///
1612/// ## How it works
1613///
1614/// The [alignment] property describes a point in the `child`'s coordinate system
1615/// and a different point in the coordinate system of this widget. The [Align]
1616/// widget positions the `child` such that both points are lined up on top of
1617/// each other.
1618///
1619/// {@tool sample}
1620/// The [Align] widget in this example uses one of the defined constants from
1621/// [Alignment], [topRight]. This places the [FlutterLogo] in the top right corner
1622/// of the parent blue [Container].
1623///
1624/// ![A blue square container with the Flutter logo in the top right corner.](https://flutter.github.io/assets-for-api-docs/assets/widgets/align_constant.png)
1625///
1626/// ```dart
1627/// Center(
1628///   child: Container(
1629///     height: 120.0,
1630///     width: 120.0,
1631///     color: Colors.blue[50],
1632///     child: Align(
1633///       alignment: Alignment.topRight,
1634///       child: FlutterLogo(
1635///         size: 60,
1636///       ),
1637///     ),
1638///   ),
1639/// )
1640/// ```
1641/// {@end-tool}
1642///
1643/// {@tool sample}
1644/// The [Alignment] used in the following example defines a single point:
1645///
1646///   * (0.2 * width of [FlutterLogo]/2 + width of [FlutterLogo]/2, 0.6 * height
1647///   of [FlutterLogo]/2 + height of [FlutterLogo]/2) = (36.0, 48.0).
1648///
1649/// The [Alignment] class uses a coordinate system with an origin in the center
1650/// of the [Container], as shown with the [Icon] above. [Align] will place the
1651/// [FlutterLogo] at (36.0, 48.0) according to this coordinate system.
1652///
1653/// ![A blue square container with the Flutter logo positioned according to the
1654/// Alignment specified above. A point is marked at the center of the container
1655/// for the origin of the Alignment coordinate system.](https://flutter.github.io/assets-for-api-docs/assets/widgets/align_alignment.png)
1656///
1657/// ```dart
1658/// Center(
1659///   child: Container(
1660///     height: 120.0,
1661///     width: 120.0,
1662///     color: Colors.blue[50],
1663///     child: Align(
1664///       alignment: Alignment(0.2, 0.6),
1665///       child: FlutterLogo(
1666///         size: 60,
1667///       ),
1668///     ),
1669///   ),
1670/// )
1671/// ```
1672/// {@end-tool}
1673///
1674/// {@tool sample}
1675/// The [FractionalOffset] used in the following example defines two points:
1676///
1677///   * (0.2 * width of [FlutterLogo], 0.6 * height of [FlutterLogo]) = (12.0, 36.0)
1678///     in the coordinate system of the blue container.
1679///   * (0.2 * width of [Align], 0.6 * height of [Align]) = (24.0, 72.0) in the
1680///     coordinate system of the [Align] widget.
1681///
1682/// The [Align] widget positions the [FlutterLogo] such that the two points are on
1683/// top of each other. In this example, the top left of the [FlutterLogo] will
1684/// be placed at (24.0, 72.0) - (12.0, 36.0) = (12.0, 36.0) from the top left of
1685/// the [Align] widget.
1686///
1687/// The [FractionalOffset] class uses a coordinate system with an origin in the top-left
1688/// corner of the [Container] in difference to the center-oriented system used in
1689/// the example above with [Alignment].
1690///
1691/// ![A blue square container with the Flutter logo positioned according to the
1692/// FractionalOffset specified above. A point is marked at the top left corner
1693/// of the container for the origin of the FractionalOffset coordinate system.](https://flutter.github.io/assets-for-api-docs/assets/widgets/align_fractional_offset.png)
1694///
1695/// ```dart
1696/// Center(
1697///   child: Container(
1698///     height: 120.0,
1699///     width: 120.0,
1700///     color: Colors.blue[50],
1701///     child: Align(
1702///       alignment: FractionalOffset(0.2, 0.6),
1703///       child: FlutterLogo(
1704///         size: 60,
1705///       ),
1706///     ),
1707///   ),
1708/// )
1709/// ```
1710/// {@end-tool}
1711///
1712/// See also:
1713///
1714///  * [AnimatedAlign], which animates changes in [alignment] smoothly over a
1715///    given duration.
1716///  * [CustomSingleChildLayout], which uses a delegate to control the layout of
1717///    a single child.
1718///  * [Center], which is the same as [Align] but with the [alignment] always
1719///    set to [Alignment.center].
1720///  * [FractionallySizedBox], which sizes its child based on a fraction of its
1721///    own size and positions the child according to an [Alignment] value.
1722///  * The [catalog of layout widgets](https://flutter.dev/widgets/layout/).
1723class Align extends SingleChildRenderObjectWidget {
1724  /// Creates an alignment widget.
1725  ///
1726  /// The alignment defaults to [Alignment.center].
1727  const Align({
1728    Key key,
1729    this.alignment = Alignment.center,
1730    this.widthFactor,
1731    this.heightFactor,
1732    Widget child,
1733  }) : assert(alignment != null),
1734       assert(widthFactor == null || widthFactor >= 0.0),
1735       assert(heightFactor == null || heightFactor >= 0.0),
1736       super(key: key, child: child);
1737
1738  /// How to align the child.
1739  ///
1740  /// The x and y values of the [Alignment] control the horizontal and vertical
1741  /// alignment, respectively. An x value of -1.0 means that the left edge of
1742  /// the child is aligned with the left edge of the parent whereas an x value
1743  /// of 1.0 means that the right edge of the child is aligned with the right
1744  /// edge of the parent. Other values interpolate (and extrapolate) linearly.
1745  /// For example, a value of 0.0 means that the center of the child is aligned
1746  /// with the center of the parent.
1747  ///
1748  /// See also:
1749  ///
1750  ///  * [Alignment], which has more details and some convenience constants for
1751  ///    common positions.
1752  ///  * [AlignmentDirectional], which has a horizontal coordinate orientation
1753  ///    that depends on the [TextDirection].
1754  final AlignmentGeometry alignment;
1755
1756  /// If non-null, sets its width to the child's width multiplied by this factor.
1757  ///
1758  /// Can be both greater and less than 1.0 but must be positive.
1759  final double widthFactor;
1760
1761  /// If non-null, sets its height to the child's height multiplied by this factor.
1762  ///
1763  /// Can be both greater and less than 1.0 but must be positive.
1764  final double heightFactor;
1765
1766  @override
1767  RenderPositionedBox createRenderObject(BuildContext context) {
1768    return RenderPositionedBox(
1769      alignment: alignment,
1770      widthFactor: widthFactor,
1771      heightFactor: heightFactor,
1772      textDirection: Directionality.of(context),
1773    );
1774  }
1775
1776  @override
1777  void updateRenderObject(BuildContext context, RenderPositionedBox renderObject) {
1778    renderObject
1779      ..alignment = alignment
1780      ..widthFactor = widthFactor
1781      ..heightFactor = heightFactor
1782      ..textDirection = Directionality.of(context);
1783  }
1784
1785  @override
1786  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
1787    super.debugFillProperties(properties);
1788    properties.add(DiagnosticsProperty<AlignmentGeometry>('alignment', alignment));
1789    properties.add(DoubleProperty('widthFactor', widthFactor, defaultValue: null));
1790    properties.add(DoubleProperty('heightFactor', heightFactor, defaultValue: null));
1791  }
1792}
1793
1794/// A widget that centers its child within itself.
1795///
1796/// This widget will be as big as possible if its dimensions are constrained and
1797/// [widthFactor] and [heightFactor] are null. If a dimension is unconstrained
1798/// and the corresponding size factor is null then the widget will match its
1799/// child's size in that dimension. If a size factor is non-null then the
1800/// corresponding dimension of this widget will be the product of the child's
1801/// dimension and the size factor. For example if widthFactor is 2.0 then
1802/// the width of this widget will always be twice its child's width.
1803///
1804/// See also:
1805///
1806///  * [Align], which lets you arbitrarily position a child within itself,
1807///    rather than just centering it.
1808///  * [Row], a widget that displays its children in a horizontal array.
1809///  * [Column], a widget that displays its children in a vertical array.
1810///  * [Container], a convenience widget that combines common painting,
1811///    positioning, and sizing widgets.
1812///  * The [catalog of layout widgets](https://flutter.dev/widgets/layout/).
1813class Center extends Align {
1814  /// Creates a widget that centers its child.
1815  const Center({ Key key, double widthFactor, double heightFactor, Widget child })
1816    : super(key: key, widthFactor: widthFactor, heightFactor: heightFactor, child: child);
1817}
1818
1819/// A widget that defers the layout of its single child to a delegate.
1820///
1821/// The delegate can determine the layout constraints for the child and can
1822/// decide where to position the child. The delegate can also determine the size
1823/// of the parent, but the size of the parent cannot depend on the size of the
1824/// child.
1825///
1826/// See also:
1827///
1828///  * [SingleChildLayoutDelegate], which controls the layout of the child.
1829///  * [Align], which sizes itself based on its child's size and positions
1830///    the child according to an [Alignment] value.
1831///  * [FractionallySizedBox], which sizes its child based on a fraction of its own
1832///    size and positions the child according to an [Alignment] value.
1833///  * [CustomMultiChildLayout], which uses a delegate to position multiple
1834///    children.
1835class CustomSingleChildLayout extends SingleChildRenderObjectWidget {
1836  /// Creates a custom single child layout.
1837  ///
1838  /// The [delegate] argument must not be null.
1839  const CustomSingleChildLayout({
1840    Key key,
1841    @required this.delegate,
1842    Widget child,
1843  }) : assert(delegate != null),
1844       super(key: key, child: child);
1845
1846  /// The delegate that controls the layout of the child.
1847  final SingleChildLayoutDelegate delegate;
1848
1849  @override
1850  RenderCustomSingleChildLayoutBox createRenderObject(BuildContext context) {
1851    return RenderCustomSingleChildLayoutBox(delegate: delegate);
1852  }
1853
1854  @override
1855  void updateRenderObject(BuildContext context, RenderCustomSingleChildLayoutBox renderObject) {
1856    renderObject.delegate = delegate;
1857  }
1858}
1859
1860/// Metadata for identifying children in a [CustomMultiChildLayout].
1861///
1862/// The [MultiChildLayoutDelegate.hasChild],
1863/// [MultiChildLayoutDelegate.layoutChild], and
1864/// [MultiChildLayoutDelegate.positionChild] methods use these identifiers.
1865class LayoutId extends ParentDataWidget<CustomMultiChildLayout> {
1866  /// Marks a child with a layout identifier.
1867  ///
1868  /// Both the child and the id arguments must not be null.
1869  LayoutId({
1870    Key key,
1871    @required this.id,
1872    @required Widget child,
1873  }) : assert(child != null),
1874       assert(id != null),
1875       super(key: key ?? ValueKey<Object>(id), child: child);
1876
1877  /// An object representing the identity of this child.
1878  ///
1879  /// The [id] needs to be unique among the children that the
1880  /// [CustomMultiChildLayout] manages.
1881  final Object id;
1882
1883  @override
1884  void applyParentData(RenderObject renderObject) {
1885    assert(renderObject.parentData is MultiChildLayoutParentData);
1886    final MultiChildLayoutParentData parentData = renderObject.parentData;
1887    if (parentData.id != id) {
1888      parentData.id = id;
1889      final AbstractNode targetParent = renderObject.parent;
1890      if (targetParent is RenderObject)
1891        targetParent.markNeedsLayout();
1892    }
1893  }
1894
1895  @override
1896  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
1897    super.debugFillProperties(properties);
1898    properties.add(DiagnosticsProperty<Object>('id', id));
1899  }
1900}
1901
1902/// A widget that uses a delegate to size and position multiple children.
1903///
1904/// The delegate can determine the layout constraints for each child and can
1905/// decide where to position each child. The delegate can also determine the
1906/// size of the parent, but the size of the parent cannot depend on the sizes of
1907/// the children.
1908///
1909/// [CustomMultiChildLayout] is appropriate when there are complex relationships
1910/// between the size and positioning of a multiple widgets. To control the
1911/// layout of a single child, [CustomSingleChildLayout] is more appropriate. For
1912/// simple cases, such as aligning a widget to one or another edge, the [Stack]
1913/// widget is more appropriate.
1914///
1915/// Each child must be wrapped in a [LayoutId] widget to identify the widget for
1916/// the delegate.
1917///
1918/// See also:
1919///
1920///  * [MultiChildLayoutDelegate], for details about how to control the layout of
1921///    the children.
1922///  * [CustomSingleChildLayout], which uses a delegate to control the layout of
1923///    a single child.
1924///  * [Stack], which arranges children relative to the edges of the container.
1925///  * [Flow], which provides paint-time control of its children using transform
1926///    matrices.
1927class CustomMultiChildLayout extends MultiChildRenderObjectWidget {
1928  /// Creates a custom multi-child layout.
1929  ///
1930  /// The [delegate] argument must not be null.
1931  CustomMultiChildLayout({
1932    Key key,
1933    @required this.delegate,
1934    List<Widget> children = const <Widget>[],
1935  }) : assert(delegate != null),
1936       super(key: key, children: children);
1937
1938  /// The delegate that controls the layout of the children.
1939  final MultiChildLayoutDelegate delegate;
1940
1941  @override
1942  RenderCustomMultiChildLayoutBox createRenderObject(BuildContext context) {
1943    return RenderCustomMultiChildLayoutBox(delegate: delegate);
1944  }
1945
1946  @override
1947  void updateRenderObject(BuildContext context, RenderCustomMultiChildLayoutBox renderObject) {
1948    renderObject.delegate = delegate;
1949  }
1950}
1951
1952/// A box with a specified size.
1953///
1954/// If given a child, this widget forces its child to have a specific width
1955/// and/or height (assuming values are permitted by this widget's parent). If
1956/// either the width or height is null, this widget will size itself to match
1957/// the child's size in that dimension.
1958///
1959/// If not given a child, [SizedBox] will try to size itself as close to the
1960/// specified height and width as possible given the parent's constraints. If
1961/// [height] or [width] is null or unspecified, it will be treated as zero.
1962///
1963/// The [new SizedBox.expand] constructor can be used to make a [SizedBox] that
1964/// sizes itself to fit the parent. It is equivalent to setting [width] and
1965/// [height] to [double.infinity].
1966///
1967/// {@youtube 560 315 https://www.youtube.com/watch?v=EHPu_DzRfqA}
1968///
1969/// {@tool sample}
1970///
1971/// This snippet makes the child widget (a [Card] with some [Text]) have the
1972/// exact size 200x300, parental constraints permitting:
1973///
1974/// ```dart
1975/// SizedBox(
1976///   width: 200.0,
1977///   height: 300.0,
1978///   child: const Card(child: Text('Hello World!')),
1979/// )
1980/// ```
1981/// {@end-tool}
1982///
1983/// See also:
1984///
1985///  * [ConstrainedBox], a more generic version of this class that takes
1986///    arbitrary [BoxConstraints] instead of an explicit width and height.
1987///  * [UnconstrainedBox], a container that tries to let its child draw without
1988///    constraints.
1989///  * [FractionallySizedBox], a widget that sizes its child to a fraction of
1990///    the total available space.
1991///  * [AspectRatio], a widget that attempts to fit within the parent's
1992///    constraints while also sizing its child to match a given aspect ratio.
1993///  * [FittedBox], which sizes and positions its child widget to fit the parent
1994///    according to a given [BoxFit] discipline.
1995///  * The [catalog of layout widgets](https://flutter.dev/widgets/layout/).
1996class SizedBox extends SingleChildRenderObjectWidget {
1997  /// Creates a fixed size box. The [width] and [height] parameters can be null
1998  /// to indicate that the size of the box should not be constrained in
1999  /// the corresponding dimension.
2000  const SizedBox({ Key key, this.width, this.height, Widget child })
2001    : super(key: key, child: child);
2002
2003  /// Creates a box that will become as large as its parent allows.
2004  const SizedBox.expand({ Key key, Widget child })
2005    : width = double.infinity,
2006      height = double.infinity,
2007      super(key: key, child: child);
2008
2009  /// Creates a box that will become as small as its parent allows.
2010  const SizedBox.shrink({ Key key, Widget child })
2011    : width = 0.0,
2012      height = 0.0,
2013      super(key: key, child: child);
2014
2015  /// Creates a box with the specified size.
2016  SizedBox.fromSize({ Key key, Widget child, Size size })
2017    : width = size?.width,
2018      height = size?.height,
2019      super(key: key, child: child);
2020
2021  /// If non-null, requires the child to have exactly this width.
2022  final double width;
2023
2024  /// If non-null, requires the child to have exactly this height.
2025  final double height;
2026
2027  @override
2028  RenderConstrainedBox createRenderObject(BuildContext context) {
2029    return RenderConstrainedBox(
2030      additionalConstraints: _additionalConstraints,
2031    );
2032  }
2033
2034  BoxConstraints get _additionalConstraints {
2035    return BoxConstraints.tightFor(width: width, height: height);
2036  }
2037
2038  @override
2039  void updateRenderObject(BuildContext context, RenderConstrainedBox renderObject) {
2040    renderObject.additionalConstraints = _additionalConstraints;
2041  }
2042
2043  @override
2044  String toStringShort() {
2045    String type;
2046    if (width == double.infinity && height == double.infinity) {
2047      type = '$runtimeType.expand';
2048    } else if (width == 0.0 && height == 0.0) {
2049      type = '$runtimeType.shrink';
2050    } else {
2051      type = '$runtimeType';
2052    }
2053    return key == null ? '$type' : '$type-$key';
2054  }
2055
2056  @override
2057  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
2058    super.debugFillProperties(properties);
2059    DiagnosticLevel level;
2060    if ((width == double.infinity && height == double.infinity) ||
2061        (width == 0.0 && height == 0.0)) {
2062      level = DiagnosticLevel.hidden;
2063    } else {
2064      level = DiagnosticLevel.info;
2065    }
2066    properties.add(DoubleProperty('width', width, defaultValue: null, level: level));
2067    properties.add(DoubleProperty('height', height, defaultValue: null, level: level));
2068  }
2069}
2070
2071/// A widget that imposes additional constraints on its child.
2072///
2073/// For example, if you wanted [child] to have a minimum height of 50.0 logical
2074/// pixels, you could use `const BoxConstraints(minHeight: 50.0)` as the
2075/// [constraints].
2076///
2077/// {@tool sample}
2078///
2079/// This snippet makes the child widget (a [Card] with some [Text]) fill the
2080/// parent, by applying [BoxConstraints.expand] constraints:
2081///
2082/// ```dart
2083/// ConstrainedBox(
2084///   constraints: const BoxConstraints.expand(),
2085///   child: const Card(child: Text('Hello World!')),
2086/// )
2087/// ```
2088/// {@end-tool}
2089///
2090/// The same behavior can be obtained using the [new SizedBox.expand] widget.
2091///
2092/// See also:
2093///
2094///  * [BoxConstraints], the class that describes constraints.
2095///  * [UnconstrainedBox], a container that tries to let its child draw without
2096///    constraints.
2097///  * [SizedBox], which lets you specify tight constraints by explicitly
2098///    specifying the height or width.
2099///  * [FractionallySizedBox], which sizes its child based on a fraction of its
2100///    own size and positions the child according to an [Alignment] value.
2101///  * [AspectRatio], a widget that attempts to fit within the parent's
2102///    constraints while also sizing its child to match a given aspect ratio.
2103///  * The [catalog of layout widgets](https://flutter.dev/widgets/layout/).
2104class ConstrainedBox extends SingleChildRenderObjectWidget {
2105  /// Creates a widget that imposes additional constraints on its child.
2106  ///
2107  /// The [constraints] argument must not be null.
2108  ConstrainedBox({
2109    Key key,
2110    @required this.constraints,
2111    Widget child,
2112  }) : assert(constraints != null),
2113       assert(constraints.debugAssertIsValid()),
2114       super(key: key, child: child);
2115
2116  /// The additional constraints to impose on the child.
2117  final BoxConstraints constraints;
2118
2119  @override
2120  RenderConstrainedBox createRenderObject(BuildContext context) {
2121    return RenderConstrainedBox(additionalConstraints: constraints);
2122  }
2123
2124  @override
2125  void updateRenderObject(BuildContext context, RenderConstrainedBox renderObject) {
2126    renderObject.additionalConstraints = constraints;
2127  }
2128
2129  @override
2130  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
2131    super.debugFillProperties(properties);
2132    properties.add(DiagnosticsProperty<BoxConstraints>('constraints', constraints, showName: false));
2133  }
2134}
2135
2136/// A widget that imposes no constraints on its child, allowing it to render
2137/// at its "natural" size.
2138///
2139/// This allows a child to render at the size it would render if it were alone
2140/// on an infinite canvas with no constraints. This container will then attempt
2141/// to adopt the same size, within the limits of its own constraints. If it ends
2142/// up with a different size, it will align the child based on [alignment].
2143/// If the box cannot expand enough to accommodate the entire child, the
2144/// child will be clipped.
2145///
2146/// In debug mode, if the child overflows the container, a warning will be
2147/// printed on the console, and black and yellow striped areas will appear where
2148/// the overflow occurs.
2149///
2150/// See also:
2151///
2152///  * [ConstrainedBox], for a box which imposes constraints on its child.
2153///  * [Align], which loosens the constraints given to the child rather than
2154///    removing them entirely.
2155///  * [Container], a convenience widget that combines common painting,
2156///    positioning, and sizing widgets.
2157///  * [OverflowBox], a widget that imposes different constraints on its child
2158///    than it gets from its parent, possibly allowing the child to overflow
2159///    the parent.
2160class UnconstrainedBox extends SingleChildRenderObjectWidget {
2161  /// Creates a widget that imposes no constraints on its child, allowing it to
2162  /// render at its "natural" size. If the child overflows the parents
2163  /// constraints, a warning will be given in debug mode.
2164  const UnconstrainedBox({
2165    Key key,
2166    Widget child,
2167    this.textDirection,
2168    this.alignment = Alignment.center,
2169    this.constrainedAxis,
2170  }) : assert(alignment != null),
2171       super(key: key, child: child);
2172
2173  /// The text direction to use when interpreting the [alignment] if it is an
2174  /// [AlignmentDirectional].
2175  final TextDirection textDirection;
2176
2177  /// The alignment to use when laying out the child.
2178  ///
2179  /// If this is an [AlignmentDirectional], then [textDirection] must not be
2180  /// null.
2181  ///
2182  /// See also:
2183  ///
2184  ///  * [Alignment] for non-[Directionality]-aware alignments.
2185  ///  * [AlignmentDirectional] for [Directionality]-aware alignments.
2186  final AlignmentGeometry alignment;
2187
2188  /// The axis to retain constraints on, if any.
2189  ///
2190  /// If not set, or set to null (the default), neither axis will retain its
2191  /// constraints. If set to [Axis.vertical], then vertical constraints will
2192  /// be retained, and if set to [Axis.horizontal], then horizontal constraints
2193  /// will be retained.
2194  final Axis constrainedAxis;
2195
2196  @override
2197  void updateRenderObject(BuildContext context, covariant RenderUnconstrainedBox renderObject) {
2198    renderObject
2199      ..textDirection = textDirection ?? Directionality.of(context)
2200      ..alignment = alignment
2201      ..constrainedAxis = constrainedAxis;
2202  }
2203
2204  @override
2205  RenderUnconstrainedBox createRenderObject(BuildContext context) => RenderUnconstrainedBox(
2206    textDirection: textDirection ?? Directionality.of(context),
2207    alignment: alignment,
2208    constrainedAxis: constrainedAxis,
2209  );
2210
2211  @override
2212  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
2213    super.debugFillProperties(properties);
2214    properties.add(DiagnosticsProperty<AlignmentGeometry>('alignment', alignment));
2215    properties.add(EnumProperty<Axis>('constrainedAxis', constrainedAxis, defaultValue: null));
2216    properties.add(EnumProperty<TextDirection>('textDirection', textDirection, defaultValue: null));
2217  }
2218}
2219
2220/// A widget that sizes its child to a fraction of the total available space.
2221/// For more details about the layout algorithm, see
2222/// [RenderFractionallySizedOverflowBox].
2223///
2224/// See also:
2225///
2226///  * [Align], which sizes itself based on its child's size and positions
2227///    the child according to an [Alignment] value.
2228///  * [OverflowBox], a widget that imposes different constraints on its child
2229///    than it gets from its parent, possibly allowing the child to overflow the
2230///    parent.
2231///  * The [catalog of layout widgets](https://flutter.dev/widgets/layout/).
2232class FractionallySizedBox extends SingleChildRenderObjectWidget {
2233  /// Creates a widget that sizes its child to a fraction of the total available space.
2234  ///
2235  /// If non-null, the [widthFactor] and [heightFactor] arguments must be
2236  /// non-negative.
2237  const FractionallySizedBox({
2238    Key key,
2239    this.alignment = Alignment.center,
2240    this.widthFactor,
2241    this.heightFactor,
2242    Widget child,
2243  }) : assert(alignment != null),
2244       assert(widthFactor == null || widthFactor >= 0.0),
2245       assert(heightFactor == null || heightFactor >= 0.0),
2246       super(key: key, child: child);
2247
2248  /// If non-null, the fraction of the incoming width given to the child.
2249  ///
2250  /// If non-null, the child is given a tight width constraint that is the max
2251  /// incoming width constraint multiplied by this factor.
2252  ///
2253  /// If null, the incoming width constraints are passed to the child
2254  /// unmodified.
2255  final double widthFactor;
2256
2257  /// If non-null, the fraction of the incoming height given to the child.
2258  ///
2259  /// If non-null, the child is given a tight height constraint that is the max
2260  /// incoming height constraint multiplied by this factor.
2261  ///
2262  /// If null, the incoming height constraints are passed to the child
2263  /// unmodified.
2264  final double heightFactor;
2265
2266  /// How to align the child.
2267  ///
2268  /// The x and y values of the alignment control the horizontal and vertical
2269  /// alignment, respectively. An x value of -1.0 means that the left edge of
2270  /// the child is aligned with the left edge of the parent whereas an x value
2271  /// of 1.0 means that the right edge of the child is aligned with the right
2272  /// edge of the parent. Other values interpolate (and extrapolate) linearly.
2273  /// For example, a value of 0.0 means that the center of the child is aligned
2274  /// with the center of the parent.
2275  ///
2276  /// Defaults to [Alignment.center].
2277  ///
2278  /// See also:
2279  ///
2280  ///  * [Alignment], a class with convenient constants typically used to
2281  ///    specify an [AlignmentGeometry].
2282  ///  * [AlignmentDirectional], like [Alignment] for specifying alignments
2283  ///    relative to text direction.
2284  final AlignmentGeometry alignment;
2285
2286  @override
2287  RenderFractionallySizedOverflowBox createRenderObject(BuildContext context) {
2288    return RenderFractionallySizedOverflowBox(
2289      alignment: alignment,
2290      widthFactor: widthFactor,
2291      heightFactor: heightFactor,
2292      textDirection: Directionality.of(context),
2293    );
2294  }
2295
2296  @override
2297  void updateRenderObject(BuildContext context, RenderFractionallySizedOverflowBox renderObject) {
2298    renderObject
2299      ..alignment = alignment
2300      ..widthFactor = widthFactor
2301      ..heightFactor = heightFactor
2302      ..textDirection = Directionality.of(context);
2303  }
2304
2305  @override
2306  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
2307    super.debugFillProperties(properties);
2308    properties.add(DiagnosticsProperty<AlignmentGeometry>('alignment', alignment));
2309    properties.add(DoubleProperty('widthFactor', widthFactor, defaultValue: null));
2310    properties.add(DoubleProperty('heightFactor', heightFactor, defaultValue: null));
2311  }
2312}
2313
2314/// A box that limits its size only when it's unconstrained.
2315///
2316/// If this widget's maximum width is unconstrained then its child's width is
2317/// limited to [maxWidth]. Similarly, if this widget's maximum height is
2318/// unconstrained then its child's height is limited to [maxHeight].
2319///
2320/// This has the effect of giving the child a natural dimension in unbounded
2321/// environments. For example, by providing a [maxHeight] to a widget that
2322/// normally tries to be as big as possible, the widget will normally size
2323/// itself to fit its parent, but when placed in a vertical list, it will take
2324/// on the given height.
2325///
2326/// This is useful when composing widgets that normally try to match their
2327/// parents' size, so that they behave reasonably in lists (which are
2328/// unbounded).
2329///
2330/// See also:
2331///
2332///  * [ConstrainedBox], which applies its constraints in all cases, not just
2333///    when the incoming constraints are unbounded.
2334///  * [SizedBox], which lets you specify tight constraints by explicitly
2335///    specifying the height or width.
2336///  * The [catalog of layout widgets](https://flutter.dev/widgets/layout/).
2337class LimitedBox extends SingleChildRenderObjectWidget {
2338  /// Creates a box that limits its size only when it's unconstrained.
2339  ///
2340  /// The [maxWidth] and [maxHeight] arguments must not be null and must not be
2341  /// negative.
2342  const LimitedBox({
2343    Key key,
2344    this.maxWidth = double.infinity,
2345    this.maxHeight = double.infinity,
2346    Widget child,
2347  }) : assert(maxWidth != null && maxWidth >= 0.0),
2348       assert(maxHeight != null && maxHeight >= 0.0),
2349       super(key: key, child: child);
2350
2351  /// The maximum width limit to apply in the absence of a
2352  /// [BoxConstraints.maxWidth] constraint.
2353  final double maxWidth;
2354
2355  /// The maximum height limit to apply in the absence of a
2356  /// [BoxConstraints.maxHeight] constraint.
2357  final double maxHeight;
2358
2359  @override
2360  RenderLimitedBox createRenderObject(BuildContext context) {
2361    return RenderLimitedBox(
2362      maxWidth: maxWidth,
2363      maxHeight: maxHeight,
2364    );
2365  }
2366
2367  @override
2368  void updateRenderObject(BuildContext context, RenderLimitedBox renderObject) {
2369    renderObject
2370      ..maxWidth = maxWidth
2371      ..maxHeight = maxHeight;
2372  }
2373
2374  @override
2375  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
2376    super.debugFillProperties(properties);
2377    properties.add(DoubleProperty('maxWidth', maxWidth, defaultValue: double.infinity));
2378    properties.add(DoubleProperty('maxHeight', maxHeight, defaultValue: double.infinity));
2379  }
2380}
2381
2382/// A widget that imposes different constraints on its child than it gets
2383/// from its parent, possibly allowing the child to overflow the parent.
2384///
2385/// See also:
2386///
2387///  * [RenderConstrainedOverflowBox] for details about how [OverflowBox] is
2388///    rendered.
2389///  * [SizedOverflowBox], a widget that is a specific size but passes its
2390///    original constraints through to its child, which may then overflow.
2391///  * [ConstrainedBox], a widget that imposes additional constraints on its
2392///    child.
2393///  * [UnconstrainedBox], a container that tries to let its child draw without
2394///    constraints.
2395///  * [SizedBox], a box with a specified size.
2396///  * The [catalog of layout widgets](https://flutter.dev/widgets/layout/).
2397class OverflowBox extends SingleChildRenderObjectWidget {
2398  /// Creates a widget that lets its child overflow itself.
2399  const OverflowBox({
2400    Key key,
2401    this.alignment = Alignment.center,
2402    this.minWidth,
2403    this.maxWidth,
2404    this.minHeight,
2405    this.maxHeight,
2406    Widget child,
2407  }) : super(key: key, child: child);
2408
2409  /// How to align the child.
2410  ///
2411  /// The x and y values of the alignment control the horizontal and vertical
2412  /// alignment, respectively. An x value of -1.0 means that the left edge of
2413  /// the child is aligned with the left edge of the parent whereas an x value
2414  /// of 1.0 means that the right edge of the child is aligned with the right
2415  /// edge of the parent. Other values interpolate (and extrapolate) linearly.
2416  /// For example, a value of 0.0 means that the center of the child is aligned
2417  /// with the center of the parent.
2418  ///
2419  /// Defaults to [Alignment.center].
2420  ///
2421  /// See also:
2422  ///
2423  ///  * [Alignment], a class with convenient constants typically used to
2424  ///    specify an [AlignmentGeometry].
2425  ///  * [AlignmentDirectional], like [Alignment] for specifying alignments
2426  ///    relative to text direction.
2427  final AlignmentGeometry alignment;
2428
2429  /// The minimum width constraint to give the child. Set this to null (the
2430  /// default) to use the constraint from the parent instead.
2431  final double minWidth;
2432
2433  /// The maximum width constraint to give the child. Set this to null (the
2434  /// default) to use the constraint from the parent instead.
2435  final double maxWidth;
2436
2437  /// The minimum height constraint to give the child. Set this to null (the
2438  /// default) to use the constraint from the parent instead.
2439  final double minHeight;
2440
2441  /// The maximum height constraint to give the child. Set this to null (the
2442  /// default) to use the constraint from the parent instead.
2443  final double maxHeight;
2444
2445  @override
2446  RenderConstrainedOverflowBox createRenderObject(BuildContext context) {
2447    return RenderConstrainedOverflowBox(
2448      alignment: alignment,
2449      minWidth: minWidth,
2450      maxWidth: maxWidth,
2451      minHeight: minHeight,
2452      maxHeight: maxHeight,
2453      textDirection: Directionality.of(context),
2454    );
2455  }
2456
2457  @override
2458  void updateRenderObject(BuildContext context, RenderConstrainedOverflowBox renderObject) {
2459    renderObject
2460      ..alignment = alignment
2461      ..minWidth = minWidth
2462      ..maxWidth = maxWidth
2463      ..minHeight = minHeight
2464      ..maxHeight = maxHeight
2465      ..textDirection = Directionality.of(context);
2466  }
2467
2468  @override
2469  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
2470    super.debugFillProperties(properties);
2471    properties.add(DiagnosticsProperty<AlignmentGeometry>('alignment', alignment));
2472    properties.add(DoubleProperty('minWidth', minWidth, defaultValue: null));
2473    properties.add(DoubleProperty('maxWidth', maxWidth, defaultValue: null));
2474    properties.add(DoubleProperty('minHeight', minHeight, defaultValue: null));
2475    properties.add(DoubleProperty('maxHeight', maxHeight, defaultValue: null));
2476  }
2477}
2478
2479/// A widget that is a specific size but passes its original constraints
2480/// through to its child, which may then overflow.
2481///
2482/// See also:
2483///
2484///  * [OverflowBox], A widget that imposes different constraints on its child
2485///    than it gets from its parent, possibly allowing the child to overflow the
2486///    parent.
2487///  * [ConstrainedBox], a widget that imposes additional constraints on its
2488///    child.
2489///  * [UnconstrainedBox], a container that tries to let its child draw without
2490///    constraints.
2491///  * The [catalog of layout widgets](https://flutter.dev/widgets/layout/).
2492class SizedOverflowBox extends SingleChildRenderObjectWidget {
2493  /// Creates a widget of a given size that lets its child overflow.
2494  ///
2495  /// The [size] argument must not be null.
2496  const SizedOverflowBox({
2497    Key key,
2498    @required this.size,
2499    this.alignment = Alignment.center,
2500    Widget child,
2501  }) : assert(size != null),
2502       assert(alignment != null),
2503       super(key: key, child: child);
2504
2505  /// How to align the child.
2506  ///
2507  /// The x and y values of the alignment control the horizontal and vertical
2508  /// alignment, respectively. An x value of -1.0 means that the left edge of
2509  /// the child is aligned with the left edge of the parent whereas an x value
2510  /// of 1.0 means that the right edge of the child is aligned with the right
2511  /// edge of the parent. Other values interpolate (and extrapolate) linearly.
2512  /// For example, a value of 0.0 means that the center of the child is aligned
2513  /// with the center of the parent.
2514  ///
2515  /// Defaults to [Alignment.center].
2516  ///
2517  /// See also:
2518  ///
2519  ///  * [Alignment], a class with convenient constants typically used to
2520  ///    specify an [AlignmentGeometry].
2521  ///  * [AlignmentDirectional], like [Alignment] for specifying alignments
2522  ///    relative to text direction.
2523  final AlignmentGeometry alignment;
2524
2525  /// The size this widget should attempt to be.
2526  final Size size;
2527
2528  @override
2529  RenderSizedOverflowBox createRenderObject(BuildContext context) {
2530    return RenderSizedOverflowBox(
2531      alignment: alignment,
2532      requestedSize: size,
2533      textDirection: Directionality.of(context),
2534    );
2535  }
2536
2537  @override
2538  void updateRenderObject(BuildContext context, RenderSizedOverflowBox renderObject) {
2539    renderObject
2540      ..alignment = alignment
2541      ..requestedSize = size
2542      ..textDirection = Directionality.of(context);
2543  }
2544
2545  @override
2546  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
2547    super.debugFillProperties(properties);
2548    properties.add(DiagnosticsProperty<AlignmentGeometry>('alignment', alignment));
2549    properties.add(DiagnosticsProperty<Size>('size', size, defaultValue: null));
2550  }
2551}
2552
2553/// A widget that lays the child out as if it was in the tree, but without
2554/// painting anything, without making the child available for hit testing, and
2555/// without taking any room in the parent.
2556///
2557/// Animations continue to run in offstage children, and therefore use battery
2558/// and CPU time, regardless of whether the animations end up being visible.
2559///
2560/// [Offstage] can be used to measure the dimensions of a widget without
2561/// bringing it on screen (yet). To hide a widget from view while it is not
2562/// needed, prefer removing the widget from the tree entirely rather than
2563/// keeping it alive in an [Offstage] subtree.
2564///
2565/// See also:
2566///
2567///  * [Visibility], which can hide a child more efficiently (albeit less
2568///    subtly).
2569///  * [TickerMode], which can be used to disable animations in a subtree.
2570///  * The [catalog of layout widgets](https://flutter.dev/widgets/layout/).
2571class Offstage extends SingleChildRenderObjectWidget {
2572  /// Creates a widget that visually hides its child.
2573  const Offstage({ Key key, this.offstage = true, Widget child })
2574    : assert(offstage != null),
2575      super(key: key, child: child);
2576
2577  /// Whether the child is hidden from the rest of the tree.
2578  ///
2579  /// If true, the child is laid out as if it was in the tree, but without
2580  /// painting anything, without making the child available for hit testing, and
2581  /// without taking any room in the parent.
2582  ///
2583  /// If false, the child is included in the tree as normal.
2584  final bool offstage;
2585
2586  @override
2587  RenderOffstage createRenderObject(BuildContext context) => RenderOffstage(offstage: offstage);
2588
2589  @override
2590  void updateRenderObject(BuildContext context, RenderOffstage renderObject) {
2591    renderObject.offstage = offstage;
2592  }
2593
2594  @override
2595  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
2596    super.debugFillProperties(properties);
2597    properties.add(DiagnosticsProperty<bool>('offstage', offstage));
2598  }
2599
2600  @override
2601  _OffstageElement createElement() => _OffstageElement(this);
2602}
2603
2604class _OffstageElement extends SingleChildRenderObjectElement {
2605  _OffstageElement(Offstage widget) : super(widget);
2606
2607  @override
2608  Offstage get widget => super.widget;
2609
2610  @override
2611  void debugVisitOnstageChildren(ElementVisitor visitor) {
2612    if (!widget.offstage)
2613      super.debugVisitOnstageChildren(visitor);
2614  }
2615}
2616
2617/// A widget that attempts to size the child to a specific aspect ratio.
2618///
2619/// The widget first tries the largest width permitted by the layout
2620/// constraints. The height of the widget is determined by applying the
2621/// given aspect ratio to the width, expressed as a ratio of width to height.
2622///
2623/// {@youtube 560 315 https://www.youtube.com/watch?v=XcnP3_mO_Ms}
2624///
2625/// For example, a 16:9 width:height aspect ratio would have a value of
2626/// 16.0/9.0. If the maximum width is infinite, the initial width is determined
2627/// by applying the aspect ratio to the maximum height.
2628///
2629/// Now consider a second example, this time with an aspect ratio of 2.0 and
2630/// layout constraints that require the width to be between 0.0 and 100.0 and
2631/// the height to be between 0.0 and 100.0. We'll select a width of 100.0 (the
2632/// biggest allowed) and a height of 50.0 (to match the aspect ratio).
2633///
2634/// In that same situation, if the aspect ratio is 0.5, we'll also select a
2635/// width of 100.0 (still the biggest allowed) and we'll attempt to use a height
2636/// of 200.0. Unfortunately, that violates the constraints because the child can
2637/// be at most 100.0 pixels tall. The widget will then take that value
2638/// and apply the aspect ratio again to obtain a width of 50.0. That width is
2639/// permitted by the constraints and the child receives a width of 50.0 and a
2640/// height of 100.0. If the width were not permitted, the widget would
2641/// continue iterating through the constraints. If the widget does not
2642/// find a feasible size after consulting each constraint, the widget
2643/// will eventually select a size for the child that meets the layout
2644/// constraints but fails to meet the aspect ratio constraints.
2645///
2646/// See also:
2647///
2648///  * [Align], a widget that aligns its child within itself and optionally
2649///    sizes itself based on the child's size.
2650///  * [ConstrainedBox], a widget that imposes additional constraints on its
2651///    child.
2652///  * [UnconstrainedBox], a container that tries to let its child draw without
2653///    constraints.
2654///  * The [catalog of layout widgets](https://flutter.dev/widgets/layout/).
2655class AspectRatio extends SingleChildRenderObjectWidget {
2656  /// Creates a widget with a specific aspect ratio.
2657  ///
2658  /// The [aspectRatio] argument must not be null.
2659  const AspectRatio({
2660    Key key,
2661    @required this.aspectRatio,
2662    Widget child,
2663  }) : assert(aspectRatio != null),
2664       super(key: key, child: child);
2665
2666  /// The aspect ratio to attempt to use.
2667  ///
2668  /// The aspect ratio is expressed as a ratio of width to height. For example,
2669  /// a 16:9 width:height aspect ratio would have a value of 16.0/9.0.
2670  final double aspectRatio;
2671
2672  @override
2673  RenderAspectRatio createRenderObject(BuildContext context) => RenderAspectRatio(aspectRatio: aspectRatio);
2674
2675  @override
2676  void updateRenderObject(BuildContext context, RenderAspectRatio renderObject) {
2677    renderObject.aspectRatio = aspectRatio;
2678  }
2679
2680  @override
2681  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
2682    super.debugFillProperties(properties);
2683    properties.add(DoubleProperty('aspectRatio', aspectRatio));
2684  }
2685}
2686
2687/// A widget that sizes its child to the child's intrinsic width.
2688///
2689/// Sizes its child's width to the child's maximum intrinsic width. If
2690/// [stepWidth] is non-null, the child's width will be snapped to a multiple of
2691/// the [stepWidth]. Similarly, if [stepHeight] is non-null, the child's height
2692/// will be snapped to a multiple of the [stepHeight].
2693///
2694/// This class is useful, for example, when unlimited width is available and
2695/// you would like a child that would otherwise attempt to expand infinitely to
2696/// instead size itself to a more reasonable width.
2697///
2698/// This class is relatively expensive, because it adds a speculative layout
2699/// pass before the final layout phase. Avoid using it where possible. In the
2700/// worst case, this widget can result in a layout that is O(N²) in the depth of
2701/// the tree.
2702///
2703/// See also:
2704///
2705///  * [The catalog of layout widgets](https://flutter.dev/widgets/layout/).
2706class IntrinsicWidth extends SingleChildRenderObjectWidget {
2707  /// Creates a widget that sizes its child to the child's intrinsic width.
2708  ///
2709  /// This class is relatively expensive. Avoid using it where possible.
2710  const IntrinsicWidth({ Key key, this.stepWidth, this.stepHeight, Widget child })
2711    : assert(stepWidth == null || stepWidth >= 0.0),
2712      assert(stepHeight == null || stepHeight >= 0.0),
2713      super(key: key, child: child);
2714
2715  /// If non-null, force the child's width to be a multiple of this value.
2716  ///
2717  /// If null or 0.0 the child's width will be the same as its maximum
2718  /// intrinsic width.
2719  ///
2720  /// This value must not be negative.
2721  ///
2722  /// See also:
2723  ///
2724  ///  * [RenderBox.getMaxIntrinsicWidth], which defines a widget's max
2725  ///    intrinsic width  in general.
2726  final double stepWidth;
2727
2728  /// If non-null, force the child's height to be a multiple of this value.
2729  ///
2730  /// If null or 0.0 the child's height will not be constrained.
2731  ///
2732  /// This value must not be negative.
2733  final double stepHeight;
2734
2735  double get _stepWidth => stepWidth == 0.0 ? null : stepWidth;
2736  double get _stepHeight => stepHeight == 0.0 ? null : stepHeight;
2737
2738  @override
2739  RenderIntrinsicWidth createRenderObject(BuildContext context) {
2740    return RenderIntrinsicWidth(stepWidth: _stepWidth, stepHeight: _stepHeight);
2741  }
2742
2743  @override
2744  void updateRenderObject(BuildContext context, RenderIntrinsicWidth renderObject) {
2745    renderObject
2746      ..stepWidth = _stepWidth
2747      ..stepHeight = _stepHeight;
2748  }
2749}
2750
2751/// A widget that sizes its child to the child's intrinsic height.
2752///
2753/// This class is useful, for example, when unlimited height is available and
2754/// you would like a child that would otherwise attempt to expand infinitely to
2755/// instead size itself to a more reasonable height.
2756///
2757/// This class is relatively expensive, because it adds a speculative layout
2758/// pass before the final layout phase. Avoid using it where possible. In the
2759/// worst case, this widget can result in a layout that is O(N²) in the depth of
2760/// the tree.
2761///
2762/// See also:
2763///
2764///  * [The catalog of layout widgets](https://flutter.dev/widgets/layout/).
2765class IntrinsicHeight extends SingleChildRenderObjectWidget {
2766  /// Creates a widget that sizes its child to the child's intrinsic height.
2767  ///
2768  /// This class is relatively expensive. Avoid using it where possible.
2769  const IntrinsicHeight({ Key key, Widget child }) : super(key: key, child: child);
2770
2771  @override
2772  RenderIntrinsicHeight createRenderObject(BuildContext context) => RenderIntrinsicHeight();
2773}
2774
2775/// A widget that positions its child according to the child's baseline.
2776///
2777/// This widget shifts the child down such that the child's baseline (or the
2778/// bottom of the child, if the child has no baseline) is [baseline]
2779/// logical pixels below the top of this box, then sizes this box to
2780/// contain the child. If [baseline] is less than the distance from
2781/// the top of the child to the baseline of the child, then the child
2782/// is top-aligned instead.
2783///
2784/// See also:
2785///
2786///  * [Align], a widget that aligns its child within itself and optionally
2787///    sizes itself based on the child's size.
2788///  * [Center], a widget that centers its child within itself.
2789///  * The [catalog of layout widgets](https://flutter.dev/widgets/layout/).
2790class Baseline extends SingleChildRenderObjectWidget {
2791  /// Creates a widget that positions its child according to the child's baseline.
2792  ///
2793  /// The [baseline] and [baselineType] arguments must not be null.
2794  const Baseline({
2795    Key key,
2796    @required this.baseline,
2797    @required this.baselineType,
2798    Widget child,
2799  }) : assert(baseline != null),
2800       assert(baselineType != null),
2801       super(key: key, child: child);
2802
2803  /// The number of logical pixels from the top of this box at which to position
2804  /// the child's baseline.
2805  final double baseline;
2806
2807  /// The type of baseline to use for positioning the child.
2808  final TextBaseline baselineType;
2809
2810  @override
2811  RenderBaseline createRenderObject(BuildContext context) {
2812    return RenderBaseline(baseline: baseline, baselineType: baselineType);
2813  }
2814
2815  @override
2816  void updateRenderObject(BuildContext context, RenderBaseline renderObject) {
2817    renderObject
2818      ..baseline = baseline
2819      ..baselineType = baselineType;
2820  }
2821}
2822
2823
2824// SLIVERS
2825
2826/// A sliver that contains a single box widget.
2827///
2828/// Slivers are special-purpose widgets that can be combined using a
2829/// [CustomScrollView] to create custom scroll effects. A [SliverToBoxAdapter]
2830/// is a basic sliver that creates a bridge back to one of the usual box-based
2831/// widgets.
2832///
2833/// Rather than using multiple [SliverToBoxAdapter] widgets to display multiple
2834/// box widgets in a [CustomScrollView], consider using [SliverList],
2835/// [SliverFixedExtentList], [SliverPrototypeExtentList], or [SliverGrid],
2836/// which are more efficient because they instantiate only those children that
2837/// are actually visible through the scroll view's viewport.
2838///
2839/// See also:
2840///
2841///  * [CustomScrollView], which displays a scrollable list of slivers.
2842///  * [SliverList], which displays multiple box widgets in a linear array.
2843///  * [SliverFixedExtentList], which displays multiple box widgets with the
2844///    same main-axis extent in a linear array.
2845///  * [SliverPrototypeExtentList], which displays multiple box widgets with the
2846///    same main-axis extent as a prototype item, in a linear array.
2847///  * [SliverGrid], which displays multiple box widgets in arbitrary positions.
2848class SliverToBoxAdapter extends SingleChildRenderObjectWidget {
2849  /// Creates a sliver that contains a single box widget.
2850  const SliverToBoxAdapter({
2851    Key key,
2852    Widget child,
2853  }) : super(key: key, child: child);
2854
2855  @override
2856  RenderSliverToBoxAdapter createRenderObject(BuildContext context) => RenderSliverToBoxAdapter();
2857}
2858
2859/// A sliver that applies padding on each side of another sliver.
2860///
2861/// Slivers are special-purpose widgets that can be combined using a
2862/// [CustomScrollView] to create custom scroll effects. A [SliverPadding]
2863/// is a basic sliver that insets another sliver by applying padding on each
2864/// side.
2865///
2866/// Applying padding to anything but the most mundane sliver is likely to have
2867/// undesired effects. For example, wrapping a [SliverPersistentHeader] with
2868/// `pinned:true` will cause the app bar to overlap earlier slivers (contrary to
2869/// the normal behavior of pinned app bars), and while the app bar is pinned,
2870/// the padding will scroll away.
2871///
2872/// See also:
2873///
2874///  * [CustomScrollView], which displays a scrollable list of slivers.
2875class SliverPadding extends SingleChildRenderObjectWidget {
2876  /// Creates a sliver that applies padding on each side of another sliver.
2877  ///
2878  /// The [padding] argument must not be null.
2879  const SliverPadding({
2880    Key key,
2881    @required this.padding,
2882    Widget sliver,
2883  }) : assert(padding != null),
2884       super(key: key, child: sliver);
2885
2886  /// The amount of space by which to inset the child sliver.
2887  final EdgeInsetsGeometry padding;
2888
2889  @override
2890  RenderSliverPadding createRenderObject(BuildContext context) {
2891    return RenderSliverPadding(
2892      padding: padding,
2893      textDirection: Directionality.of(context),
2894    );
2895  }
2896
2897  @override
2898  void updateRenderObject(BuildContext context, RenderSliverPadding renderObject) {
2899    renderObject
2900      ..padding = padding
2901      ..textDirection = Directionality.of(context);
2902  }
2903
2904  @override
2905  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
2906    super.debugFillProperties(properties);
2907    properties.add(DiagnosticsProperty<EdgeInsetsGeometry>('padding', padding));
2908  }
2909}
2910
2911
2912// LAYOUT NODES
2913
2914/// Returns the [AxisDirection] in the given [Axis] in the current
2915/// [Directionality] (or the reverse if `reverse` is true).
2916///
2917/// If `axis` is [Axis.vertical], this function returns [AxisDirection.down]
2918/// unless `reverse` is true, in which case this function returns
2919/// [AxisDirection.up].
2920///
2921/// If `axis` is [Axis.horizontal], this function checks the current
2922/// [Directionality]. If the current [Directionality] is right-to-left, then
2923/// this function returns [AxisDirection.left] (unless `reverse` is true, in
2924/// which case it returns [AxisDirection.right]). Similarly, if the current
2925/// [Directionality] is left-to-right, then this function returns
2926/// [AxisDirection.right] (unless `reverse` is true, in which case it returns
2927/// [AxisDirection.left]).
2928///
2929/// This function is used by a number of scrolling widgets (e.g., [ListView],
2930/// [GridView], [PageView], and [SingleChildScrollView]) as well as [ListBody]
2931/// to translate their [Axis] and `reverse` properties into a concrete
2932/// [AxisDirection].
2933AxisDirection getAxisDirectionFromAxisReverseAndDirectionality(
2934  BuildContext context,
2935  Axis axis,
2936  bool reverse,
2937) {
2938  switch (axis) {
2939    case Axis.horizontal:
2940      assert(debugCheckHasDirectionality(context));
2941      final TextDirection textDirection = Directionality.of(context);
2942      final AxisDirection axisDirection = textDirectionToAxisDirection(textDirection);
2943      return reverse ? flipAxisDirection(axisDirection) : axisDirection;
2944    case Axis.vertical:
2945      return reverse ? AxisDirection.up : AxisDirection.down;
2946  }
2947  return null;
2948}
2949
2950/// A widget that arranges its children sequentially along a given axis, forcing
2951/// them to the dimension of the parent in the other axis.
2952///
2953/// This widget is rarely used directly. Instead, consider using [ListView],
2954/// which combines a similar layout algorithm with scrolling behavior, or
2955/// [Column], which gives you more flexible control over the layout of a
2956/// vertical set of boxes.
2957///
2958/// See also:
2959///
2960///  * [RenderListBody], which implements this layout algorithm and the
2961///    documentation for which describes some of its subtleties.
2962///  * [SingleChildScrollView], which is sometimes used with [ListBody] to
2963///    make the contents scrollable.
2964///  * [Column] and [Row], which implement a more elaborate version of
2965///    this layout algorithm (at the cost of being slightly less efficient).
2966///  * [ListView], which implements an efficient scrolling version of this
2967///    layout algorithm.
2968class ListBody extends MultiChildRenderObjectWidget {
2969  /// Creates a layout widget that arranges its children sequentially along a
2970  /// given axis.
2971  ///
2972  /// By default, the [mainAxis] is [Axis.vertical].
2973  ListBody({
2974    Key key,
2975    this.mainAxis = Axis.vertical,
2976    this.reverse = false,
2977    List<Widget> children = const <Widget>[],
2978  }) : assert(mainAxis != null),
2979       super(key: key, children: children);
2980
2981  /// The direction to use as the main axis.
2982  final Axis mainAxis;
2983
2984  /// Whether the list body positions children in the reading direction.
2985  ///
2986  /// For example, if the reading direction is left-to-right and
2987  /// [mainAxis] is [Axis.horizontal], then the list body positions children
2988  /// from left to right when [reverse] is false and from right to left when
2989  /// [reverse] is true.
2990  ///
2991  /// Similarly, if [mainAxis] is [Axis.vertical], then the list body positions
2992  /// from top to bottom when [reverse] is false and from bottom to top when
2993  /// [reverse] is true.
2994  ///
2995  /// Defaults to false.
2996  final bool reverse;
2997
2998  AxisDirection _getDirection(BuildContext context) {
2999    return getAxisDirectionFromAxisReverseAndDirectionality(context, mainAxis, reverse);
3000  }
3001
3002  @override
3003  RenderListBody createRenderObject(BuildContext context) {
3004    return RenderListBody(axisDirection: _getDirection(context));
3005  }
3006
3007  @override
3008  void updateRenderObject(BuildContext context, RenderListBody renderObject) {
3009    renderObject.axisDirection = _getDirection(context);
3010  }
3011}
3012
3013/// A widget that positions its children relative to the edges of its box.
3014///
3015/// This class is useful if you want to overlap several children in a simple
3016/// way, for example having some text and an image, overlaid with a gradient and
3017/// a button attached to the bottom.
3018///
3019/// Each child of a [Stack] widget is either _positioned_ or _non-positioned_.
3020/// Positioned children are those wrapped in a [Positioned] widget that has at
3021/// least one non-null property. The stack sizes itself to contain all the
3022/// non-positioned children, which are positioned according to [alignment]
3023/// (which defaults to the top-left corner in left-to-right environments and the
3024/// top-right corner in right-to-left environments). The positioned children are
3025/// then placed relative to the stack according to their top, right, bottom, and
3026/// left properties.
3027///
3028/// The stack paints its children in order with the first child being at the
3029/// bottom. If you want to change the order in which the children paint, you
3030/// can rebuild the stack with the children in the new order. If you reorder
3031/// the children in this way, consider giving the children non-null keys.
3032/// These keys will cause the framework to move the underlying objects for
3033/// the children to their new locations rather than recreate them at their
3034/// new location.
3035///
3036/// For more details about the stack layout algorithm, see [RenderStack].
3037///
3038/// If you want to lay a number of children out in a particular pattern, or if
3039/// you want to make a custom layout manager, you probably want to use
3040/// [CustomMultiChildLayout] instead. In particular, when using a [Stack] you
3041/// can't position children relative to their size or the stack's own size.
3042///
3043/// {@tool sample}
3044///
3045/// Using a [Stack] you can position widgets over one another.
3046///
3047/// ![A screenshot of the Stack widget](https://flutter.github.io/assets-for-api-docs/assets/widgets/stack.png)
3048///
3049/// ```dart
3050/// Stack(
3051///   children: <Widget>[
3052///     Container(
3053///       width: 100,
3054///       height: 100,
3055///       color: Colors.red,
3056///     ),
3057///     Container(
3058///       width: 90,
3059///       height: 90,
3060///       color: Colors.green,
3061///     ),
3062///     Container(
3063///       width: 80,
3064///       height: 80,
3065///       color: Colors.blue,
3066///     ),
3067///   ],
3068/// )
3069/// ```
3070/// {@end-tool}
3071///
3072/// {@tool sample}
3073///
3074/// This example shows how [Stack] can be used to enhance text visibility
3075/// by adding gradient backdrops.
3076///
3077/// ![A screenshot of the Stack widget using a gradient to enhance text visibility](https://flutter.github.io/assets-for-api-docs/assets/widgets/stack_with_gradient.png)
3078///
3079/// ```dart
3080/// SizedBox(
3081///   width: 250,
3082///   height: 250,
3083///   child: Stack(
3084///     children: <Widget>[
3085///       Container(
3086///         width: 250,
3087///         height: 250,
3088///         color: Colors.white,
3089///       ),
3090///       Container(
3091///         padding: EdgeInsets.all(5.0),
3092///         alignment: Alignment.bottomCenter,
3093///         decoration: BoxDecoration(
3094///           gradient: LinearGradient(
3095///             begin: Alignment.topCenter,
3096///             end: Alignment.bottomCenter,
3097///             colors: <Color>[
3098///               Colors.black.withAlpha(0),
3099///               Colors.black12,
3100///               Colors.black45
3101///             ],
3102///           ),
3103///         ),
3104///         child: Text(
3105///           "Foreground Text",
3106///           style: TextStyle(color: Colors.white, fontSize: 20.0),
3107///         ),
3108///       ),
3109///     ],
3110///   ),
3111/// )
3112/// ```
3113/// {@end-tool}
3114///
3115/// See also:
3116///
3117///  * [Align], which sizes itself based on its child's size and positions
3118///    the child according to an [Alignment] value.
3119///  * [CustomSingleChildLayout], which uses a delegate to control the layout of
3120///    a single child.
3121///  * [CustomMultiChildLayout], which uses a delegate to position multiple
3122///    children.
3123///  * [Flow], which provides paint-time control of its children using transform
3124///    matrices.
3125///  * The [catalog of layout widgets](https://flutter.dev/widgets/layout/).
3126class Stack extends MultiChildRenderObjectWidget {
3127  /// Creates a stack layout widget.
3128  ///
3129  /// By default, the non-positioned children of the stack are aligned by their
3130  /// top left corners.
3131  Stack({
3132    Key key,
3133    this.alignment = AlignmentDirectional.topStart,
3134    this.textDirection,
3135    this.fit = StackFit.loose,
3136    this.overflow = Overflow.clip,
3137    List<Widget> children = const <Widget>[],
3138  }) : super(key: key, children: children);
3139
3140  /// How to align the non-positioned and partially-positioned children in the
3141  /// stack.
3142  ///
3143  /// The non-positioned children are placed relative to each other such that
3144  /// the points determined by [alignment] are co-located. For example, if the
3145  /// [alignment] is [Alignment.topLeft], then the top left corner of
3146  /// each non-positioned child will be located at the same global coordinate.
3147  ///
3148  /// Partially-positioned children, those that do not specify an alignment in a
3149  /// particular axis (e.g. that have neither `top` nor `bottom` set), use the
3150  /// alignment to determine how they should be positioned in that
3151  /// under-specified axis.
3152  ///
3153  /// Defaults to [AlignmentDirectional.topStart].
3154  ///
3155  /// See also:
3156  ///
3157  ///  * [Alignment], a class with convenient constants typically used to
3158  ///    specify an [AlignmentGeometry].
3159  ///  * [AlignmentDirectional], like [Alignment] for specifying alignments
3160  ///    relative to text direction.
3161  final AlignmentGeometry alignment;
3162
3163  /// The text direction with which to resolve [alignment].
3164  ///
3165  /// Defaults to the ambient [Directionality].
3166  final TextDirection textDirection;
3167
3168  /// How to size the non-positioned children in the stack.
3169  ///
3170  /// The constraints passed into the [Stack] from its parent are either
3171  /// loosened ([StackFit.loose]) or tightened to their biggest size
3172  /// ([StackFit.expand]).
3173  final StackFit fit;
3174
3175  /// Whether overflowing children should be clipped. See [Overflow].
3176  ///
3177  /// Some children in a stack might overflow its box. When this flag is set to
3178  /// [Overflow.clip], children cannot paint outside of the stack's box.
3179  final Overflow overflow;
3180
3181  @override
3182  RenderStack createRenderObject(BuildContext context) {
3183    return RenderStack(
3184      alignment: alignment,
3185      textDirection: textDirection ?? Directionality.of(context),
3186      fit: fit,
3187      overflow: overflow,
3188    );
3189  }
3190
3191  @override
3192  void updateRenderObject(BuildContext context, RenderStack renderObject) {
3193    renderObject
3194      ..alignment = alignment
3195      ..textDirection = textDirection ?? Directionality.of(context)
3196      ..fit = fit
3197      ..overflow = overflow;
3198  }
3199
3200  @override
3201  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
3202    super.debugFillProperties(properties);
3203    properties.add(DiagnosticsProperty<AlignmentGeometry>('alignment', alignment));
3204    properties.add(EnumProperty<TextDirection>('textDirection', textDirection, defaultValue: null));
3205    properties.add(EnumProperty<StackFit>('fit', fit));
3206    properties.add(EnumProperty<Overflow>('overflow', overflow));
3207  }
3208}
3209
3210/// A [Stack] that shows a single child from a list of children.
3211///
3212/// The displayed child is the one with the given [index]. The stack is
3213/// always as big as the largest child.
3214///
3215/// If value is null, then nothing is displayed.
3216///
3217/// See also:
3218///
3219///  * [Stack], for more details about stacks.
3220///  * The [catalog of layout widgets](https://flutter.dev/widgets/layout/).
3221class IndexedStack extends Stack {
3222  /// Creates a [Stack] widget that paints a single child.
3223  ///
3224  /// The [index] argument must not be null.
3225  IndexedStack({
3226    Key key,
3227    AlignmentGeometry alignment = AlignmentDirectional.topStart,
3228    TextDirection textDirection,
3229    StackFit sizing = StackFit.loose,
3230    this.index = 0,
3231    List<Widget> children = const <Widget>[],
3232  }) : super(key: key, alignment: alignment, textDirection: textDirection, fit: sizing, children: children);
3233
3234  /// The index of the child to show.
3235  final int index;
3236
3237  @override
3238  RenderIndexedStack createRenderObject(BuildContext context) {
3239    return RenderIndexedStack(
3240      index: index,
3241      alignment: alignment,
3242      textDirection: textDirection ?? Directionality.of(context),
3243    );
3244  }
3245
3246  @override
3247  void updateRenderObject(BuildContext context, RenderIndexedStack renderObject) {
3248    renderObject
3249      ..index = index
3250      ..alignment = alignment
3251      ..textDirection = textDirection ?? Directionality.of(context);
3252  }
3253}
3254
3255/// A widget that controls where a child of a [Stack] is positioned.
3256///
3257/// A [Positioned] widget must be a descendant of a [Stack], and the path from
3258/// the [Positioned] widget to its enclosing [Stack] must contain only
3259/// [StatelessWidget]s or [StatefulWidget]s (not other kinds of widgets, like
3260/// [RenderObjectWidget]s).
3261///
3262/// {@youtube 560 315 https://www.youtube.com/watch?v=EgtPleVwxBQ}
3263///
3264/// If a widget is wrapped in a [Positioned], then it is a _positioned_ widget
3265/// in its [Stack]. If the [top] property is non-null, the top edge of this child
3266/// will be positioned [top] layout units from the top of the stack widget. The
3267/// [right], [bottom], and [left] properties work analogously.
3268///
3269/// If both the [top] and [bottom] properties are non-null, then the child will
3270/// be forced to have exactly the height required to satisfy both constraints.
3271/// Similarly, setting the [right] and [left] properties to non-null values will
3272/// force the child to have a particular width. Alternatively the [width] and
3273/// [height] properties can be used to give the dimensions, with one
3274/// corresponding position property (e.g. [top] and [height]).
3275///
3276/// If all three values on a particular axis are null, then the
3277/// [Stack.alignment] property is used to position the child.
3278///
3279/// If all six values are null, the child is a non-positioned child. The [Stack]
3280/// uses only the non-positioned children to size itself.
3281///
3282/// See also:
3283///
3284///  * [AnimatedPositioned], which automatically transitions the child's
3285///    position over a given duration whenever the given position changes.
3286///  * [PositionedTransition], which takes a provided [Animation] to transition
3287///    changes in the child's position over a given duration.
3288///  * [PositionedDirectional], which adapts to the ambient [Directionality].
3289class Positioned extends ParentDataWidget<Stack> {
3290  /// Creates a widget that controls where a child of a [Stack] is positioned.
3291  ///
3292  /// Only two out of the three horizontal values ([left], [right],
3293  /// [width]), and only two out of the three vertical values ([top],
3294  /// [bottom], [height]), can be set. In each case, at least one of
3295  /// the three must be null.
3296  ///
3297  /// See also:
3298  ///
3299  ///  * [Positioned.directional], which specifies the widget's horizontal
3300  ///    position using `start` and `end` rather than `left` and `right`.
3301  ///  * [PositionedDirectional], which is similar to [Positioned.directional]
3302  ///    but adapts to the ambient [Directionality].
3303  const Positioned({
3304    Key key,
3305    this.left,
3306    this.top,
3307    this.right,
3308    this.bottom,
3309    this.width,
3310    this.height,
3311    @required Widget child,
3312  }) : assert(left == null || right == null || width == null),
3313       assert(top == null || bottom == null || height == null),
3314       super(key: key, child: child);
3315
3316  /// Creates a Positioned object with the values from the given [Rect].
3317  ///
3318  /// This sets the [left], [top], [width], and [height] properties
3319  /// from the given [Rect]. The [right] and [bottom] properties are
3320  /// set to null.
3321  Positioned.fromRect({
3322    Key key,
3323    Rect rect,
3324    @required Widget child,
3325  }) : left = rect.left,
3326       top = rect.top,
3327       width = rect.width,
3328       height = rect.height,
3329       right = null,
3330       bottom = null,
3331       super(key: key, child: child);
3332
3333  /// Creates a Positioned object with the values from the given [RelativeRect].
3334  ///
3335  /// This sets the [left], [top], [right], and [bottom] properties from the
3336  /// given [RelativeRect]. The [height] and [width] properties are set to null.
3337  Positioned.fromRelativeRect({
3338    Key key,
3339    RelativeRect rect,
3340    @required Widget child,
3341  }) : left = rect.left,
3342       top = rect.top,
3343       right = rect.right,
3344       bottom = rect.bottom,
3345       width = null,
3346       height = null,
3347       super(key: key, child: child);
3348
3349  /// Creates a Positioned object with [left], [top], [right], and [bottom] set
3350  /// to 0.0 unless a value for them is passed.
3351  const Positioned.fill({
3352    Key key,
3353    this.left = 0.0,
3354    this.top = 0.0,
3355    this.right = 0.0,
3356    this.bottom = 0.0,
3357    @required Widget child,
3358  }) : width = null,
3359       height = null,
3360       super(key: key, child: child);
3361
3362  /// Creates a widget that controls where a child of a [Stack] is positioned.
3363  ///
3364  /// Only two out of the three horizontal values (`start`, `end`,
3365  /// [width]), and only two out of the three vertical values ([top],
3366  /// [bottom], [height]), can be set. In each case, at least one of
3367  /// the three must be null.
3368  ///
3369  /// If `textDirection` is [TextDirection.rtl], then the `start` argument is
3370  /// used for the [right] property and the `end` argument is used for the
3371  /// [left] property. Otherwise, if `textDirection` is [TextDirection.ltr],
3372  /// then the `start` argument is used for the [left] property and the `end`
3373  /// argument is used for the [right] property.
3374  ///
3375  /// The `textDirection` argument must not be null.
3376  ///
3377  /// See also:
3378  ///
3379  ///  * [PositionedDirectional], which adapts to the ambient [Directionality].
3380  factory Positioned.directional({
3381    Key key,
3382    @required TextDirection textDirection,
3383    double start,
3384    double top,
3385    double end,
3386    double bottom,
3387    double width,
3388    double height,
3389    @required Widget child,
3390  }) {
3391    assert(textDirection != null);
3392    double left;
3393    double right;
3394    switch (textDirection) {
3395      case TextDirection.rtl:
3396        left = end;
3397        right = start;
3398        break;
3399      case TextDirection.ltr:
3400        left = start;
3401        right = end;
3402        break;
3403    }
3404    return Positioned(
3405      key: key,
3406      left: left,
3407      top: top,
3408      right: right,
3409      bottom: bottom,
3410      width: width,
3411      height: height,
3412      child: child,
3413    );
3414  }
3415
3416  /// The distance that the child's left edge is inset from the left of the stack.
3417  ///
3418  /// Only two out of the three horizontal values ([left], [right], [width]) can be
3419  /// set. The third must be null.
3420  ///
3421  /// If all three are null, the [Stack.alignment] is used to position the child
3422  /// horizontally.
3423  final double left;
3424
3425  /// The distance that the child's top edge is inset from the top of the stack.
3426  ///
3427  /// Only two out of the three vertical values ([top], [bottom], [height]) can be
3428  /// set. The third must be null.
3429  ///
3430  /// If all three are null, the [Stack.alignment] is used to position the child
3431  /// vertically.
3432  final double top;
3433
3434  /// The distance that the child's right edge is inset from the right of the stack.
3435  ///
3436  /// Only two out of the three horizontal values ([left], [right], [width]) can be
3437  /// set. The third must be null.
3438  ///
3439  /// If all three are null, the [Stack.alignment] is used to position the child
3440  /// horizontally.
3441  final double right;
3442
3443  /// The distance that the child's bottom edge is inset from the bottom of the stack.
3444  ///
3445  /// Only two out of the three vertical values ([top], [bottom], [height]) can be
3446  /// set. The third must be null.
3447  ///
3448  /// If all three are null, the [Stack.alignment] is used to position the child
3449  /// vertically.
3450  final double bottom;
3451
3452  /// The child's width.
3453  ///
3454  /// Only two out of the three horizontal values ([left], [right], [width]) can be
3455  /// set. The third must be null.
3456  ///
3457  /// If all three are null, the [Stack.alignment] is used to position the child
3458  /// horizontally.
3459  final double width;
3460
3461  /// The child's height.
3462  ///
3463  /// Only two out of the three vertical values ([top], [bottom], [height]) can be
3464  /// set. The third must be null.
3465  ///
3466  /// If all three are null, the [Stack.alignment] is used to position the child
3467  /// vertically.
3468  final double height;
3469
3470  @override
3471  void applyParentData(RenderObject renderObject) {
3472    assert(renderObject.parentData is StackParentData);
3473    final StackParentData parentData = renderObject.parentData;
3474    bool needsLayout = false;
3475
3476    if (parentData.left != left) {
3477      parentData.left = left;
3478      needsLayout = true;
3479    }
3480
3481    if (parentData.top != top) {
3482      parentData.top = top;
3483      needsLayout = true;
3484    }
3485
3486    if (parentData.right != right) {
3487      parentData.right = right;
3488      needsLayout = true;
3489    }
3490
3491    if (parentData.bottom != bottom) {
3492      parentData.bottom = bottom;
3493      needsLayout = true;
3494    }
3495
3496    if (parentData.width != width) {
3497      parentData.width = width;
3498      needsLayout = true;
3499    }
3500
3501    if (parentData.height != height) {
3502      parentData.height = height;
3503      needsLayout = true;
3504    }
3505
3506    if (needsLayout) {
3507      final AbstractNode targetParent = renderObject.parent;
3508      if (targetParent is RenderObject)
3509        targetParent.markNeedsLayout();
3510    }
3511  }
3512
3513  @override
3514  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
3515    super.debugFillProperties(properties);
3516    properties.add(DoubleProperty('left', left, defaultValue: null));
3517    properties.add(DoubleProperty('top', top, defaultValue: null));
3518    properties.add(DoubleProperty('right', right, defaultValue: null));
3519    properties.add(DoubleProperty('bottom', bottom, defaultValue: null));
3520    properties.add(DoubleProperty('width', width, defaultValue: null));
3521    properties.add(DoubleProperty('height', height, defaultValue: null));
3522  }
3523}
3524
3525/// A widget that controls where a child of a [Stack] is positioned without
3526/// committing to a specific [TextDirection].
3527///
3528/// The ambient [Directionality] is used to determine whether [start] is to the
3529/// left or to the right.
3530///
3531/// A [PositionedDirectional] widget must be a descendant of a [Stack], and the
3532/// path from the [PositionedDirectional] widget to its enclosing [Stack] must
3533/// contain only [StatelessWidget]s or [StatefulWidget]s (not other kinds of
3534/// widgets, like [RenderObjectWidget]s).
3535///
3536/// If a widget is wrapped in a [PositionedDirectional], then it is a
3537/// _positioned_ widget in its [Stack]. If the [top] property is non-null, the
3538/// top edge of this child/ will be positioned [top] layout units from the top
3539/// of the stack widget. The [start], [bottom], and [end] properties work
3540/// analogously.
3541///
3542/// If both the [top] and [bottom] properties are non-null, then the child will
3543/// be forced to have exactly the height required to satisfy both constraints.
3544/// Similarly, setting the [start] and [end] properties to non-null values will
3545/// force the child to have a particular width. Alternatively the [width] and
3546/// [height] properties can be used to give the dimensions, with one
3547/// corresponding position property (e.g. [top] and [height]).
3548///
3549/// See also:
3550///
3551///  * [Positioned], which specifies the widget's position visually.
3552///  * [Positioned.directional], which also specifies the widget's horizontal
3553///    position using [start] and [end] but has an explicit [TextDirection].
3554///  * [AnimatedPositionedDirectional], which automatically transitions
3555///    the child's position over a given duration whenever the given position
3556///    changes.
3557class PositionedDirectional extends StatelessWidget {
3558  /// Creates a widget that controls where a child of a [Stack] is positioned.
3559  ///
3560  /// Only two out of the three horizontal values (`start`, `end`,
3561  /// [width]), and only two out of the three vertical values ([top],
3562  /// [bottom], [height]), can be set. In each case, at least one of
3563  /// the three must be null.
3564  ///
3565  /// See also:
3566  ///
3567  ///  * [Positioned.directional], which also specifies the widget's horizontal
3568  ///    position using [start] and [end] but has an explicit [TextDirection].
3569  const PositionedDirectional({
3570    Key key,
3571    this.start,
3572    this.top,
3573    this.end,
3574    this.bottom,
3575    this.width,
3576    this.height,
3577    @required this.child,
3578  }) : super(key: key);
3579
3580  /// The distance that the child's leading edge is inset from the leading edge
3581  /// of the stack.
3582  ///
3583  /// Only two out of the three horizontal values ([start], [end], [width]) can be
3584  /// set. The third must be null.
3585  final double start;
3586
3587  /// The distance that the child's top edge is inset from the top of the stack.
3588  ///
3589  /// Only two out of the three vertical values ([top], [bottom], [height]) can be
3590  /// set. The third must be null.
3591  final double top;
3592
3593  /// The distance that the child's trailing edge is inset from the trailing
3594  /// edge of the stack.
3595  ///
3596  /// Only two out of the three horizontal values ([start], [end], [width]) can be
3597  /// set. The third must be null.
3598  final double end;
3599
3600  /// The distance that the child's bottom edge is inset from the bottom of the stack.
3601  ///
3602  /// Only two out of the three vertical values ([top], [bottom], [height]) can be
3603  /// set. The third must be null.
3604  final double bottom;
3605
3606  /// The child's width.
3607  ///
3608  /// Only two out of the three horizontal values ([start], [end], [width]) can be
3609  /// set. The third must be null.
3610  final double width;
3611
3612  /// The child's height.
3613  ///
3614  /// Only two out of the three vertical values ([top], [bottom], [height]) can be
3615  /// set. The third must be null.
3616  final double height;
3617
3618  /// The widget below this widget in the tree.
3619  ///
3620  /// {@macro flutter.widgets.child}
3621  final Widget child;
3622
3623  @override
3624  Widget build(BuildContext context) {
3625    return Positioned.directional(
3626      textDirection: Directionality.of(context),
3627      start: start,
3628      top: top,
3629      end: end,
3630      bottom: bottom,
3631      width: width,
3632      height: height,
3633      child: child,
3634    );
3635  }
3636}
3637
3638/// A widget that displays its children in a one-dimensional array.
3639///
3640/// The [Flex] widget allows you to control the axis along which the children are
3641/// placed (horizontal or vertical). This is referred to as the _main axis_. If
3642/// you know the main axis in advance, then consider using a [Row] (if it's
3643/// horizontal) or [Column] (if it's vertical) instead, because that will be less
3644/// verbose.
3645///
3646/// To cause a child to expand to fill the available space in the [direction]
3647/// of this widget's main axis, wrap the child in an [Expanded] widget.
3648///
3649/// The [Flex] widget does not scroll (and in general it is considered an error
3650/// to have more children in a [Flex] than will fit in the available room). If
3651/// you have some widgets and want them to be able to scroll if there is
3652/// insufficient room, consider using a [ListView].
3653///
3654/// If you only have one child, then rather than using [Flex], [Row], or
3655/// [Column], consider using [Align] or [Center] to position the child.
3656///
3657/// ## Layout algorithm
3658///
3659/// _This section describes how a [Flex] is rendered by the framework._
3660/// _See [BoxConstraints] for an introduction to box layout models._
3661///
3662/// Layout for a [Flex] proceeds in six steps:
3663///
3664/// 1. Layout each child a null or zero flex factor (e.g., those that are not
3665///    [Expanded]) with unbounded main axis constraints and the incoming
3666///    cross axis constraints. If the [crossAxisAlignment] is
3667///    [CrossAxisAlignment.stretch], instead use tight cross axis constraints
3668///    that match the incoming max extent in the cross axis.
3669/// 2. Divide the remaining main axis space among the children with non-zero
3670///    flex factors (e.g., those that are [Expanded]) according to their flex
3671///    factor. For example, a child with a flex factor of 2.0 will receive twice
3672///    the amount of main axis space as a child with a flex factor of 1.0.
3673/// 3. Layout each of the remaining children with the same cross axis
3674///    constraints as in step 1, but instead of using unbounded main axis
3675///    constraints, use max axis constraints based on the amount of space
3676///    allocated in step 2. Children with [Flexible.fit] properties that are
3677///    [FlexFit.tight] are given tight constraints (i.e., forced to fill the
3678///    allocated space), and children with [Flexible.fit] properties that are
3679///    [FlexFit.loose] are given loose constraints (i.e., not forced to fill the
3680///    allocated space).
3681/// 4. The cross axis extent of the [Flex] is the maximum cross axis extent of
3682///    the children (which will always satisfy the incoming constraints).
3683/// 5. The main axis extent of the [Flex] is determined by the [mainAxisSize]
3684///    property. If the [mainAxisSize] property is [MainAxisSize.max], then the
3685///    main axis extent of the [Flex] is the max extent of the incoming main
3686///    axis constraints. If the [mainAxisSize] property is [MainAxisSize.min],
3687///    then the main axis extent of the [Flex] is the sum of the main axis
3688///    extents of the children (subject to the incoming constraints).
3689/// 6. Determine the position for each child according to the
3690///    [mainAxisAlignment] and the [crossAxisAlignment]. For example, if the
3691///    [mainAxisAlignment] is [MainAxisAlignment.spaceBetween], any main axis
3692///    space that has not been allocated to children is divided evenly and
3693///    placed between the children.
3694///
3695/// See also:
3696///
3697///  * [Row], for a version of this widget that is always horizontal.
3698///  * [Column], for a version of this widget that is always vertical.
3699///  * [Expanded], to indicate children that should take all the remaining room.
3700///  * [Flexible], to indicate children that should share the remaining room.
3701///  * [Spacer], a widget that takes up space proportional to it's flex value.
3702///    that may be sized smaller (leaving some remaining room unused).
3703///  * The [catalog of layout widgets](https://flutter.dev/widgets/layout/).
3704class Flex extends MultiChildRenderObjectWidget {
3705  /// Creates a flex layout.
3706  ///
3707  /// The [direction] is required.
3708  ///
3709  /// The [direction], [mainAxisAlignment], [crossAxisAlignment], and
3710  /// [verticalDirection] arguments must not be null. If [crossAxisAlignment] is
3711  /// [CrossAxisAlignment.baseline], then [textBaseline] must not be null.
3712  ///
3713  /// The [textDirection] argument defaults to the ambient [Directionality], if
3714  /// any. If there is no ambient directionality, and a text direction is going
3715  /// to be necessary to decide which direction to lay the children in or to
3716  /// disambiguate `start` or `end` values for the main or cross axis
3717  /// directions, the [textDirection] must not be null.
3718  Flex({
3719    Key key,
3720    @required this.direction,
3721    this.mainAxisAlignment = MainAxisAlignment.start,
3722    this.mainAxisSize = MainAxisSize.max,
3723    this.crossAxisAlignment = CrossAxisAlignment.center,
3724    this.textDirection,
3725    this.verticalDirection = VerticalDirection.down,
3726    this.textBaseline,
3727    List<Widget> children = const <Widget>[],
3728  }) : assert(direction != null),
3729       assert(mainAxisAlignment != null),
3730       assert(mainAxisSize != null),
3731       assert(crossAxisAlignment != null),
3732       assert(verticalDirection != null),
3733       assert(crossAxisAlignment != CrossAxisAlignment.baseline || textBaseline != null),
3734       super(key: key, children: children);
3735
3736  /// The direction to use as the main axis.
3737  ///
3738  /// If you know the axis in advance, then consider using a [Row] (if it's
3739  /// horizontal) or [Column] (if it's vertical) instead of a [Flex], since that
3740  /// will be less verbose. (For [Row] and [Column] this property is fixed to
3741  /// the appropriate axis.)
3742  final Axis direction;
3743
3744  /// How the children should be placed along the main axis.
3745  ///
3746  /// For example, [MainAxisAlignment.start], the default, places the children
3747  /// at the start (i.e., the left for a [Row] or the top for a [Column]) of the
3748  /// main axis.
3749  final MainAxisAlignment mainAxisAlignment;
3750
3751  /// How much space should be occupied in the main axis.
3752  ///
3753  /// After allocating space to children, there might be some remaining free
3754  /// space. This value controls whether to maximize or minimize the amount of
3755  /// free space, subject to the incoming layout constraints.
3756  ///
3757  /// If some children have a non-zero flex factors (and none have a fit of
3758  /// [FlexFit.loose]), they will expand to consume all the available space and
3759  /// there will be no remaining free space to maximize or minimize, making this
3760  /// value irrelevant to the final layout.
3761  final MainAxisSize mainAxisSize;
3762
3763  /// How the children should be placed along the cross axis.
3764  ///
3765  /// For example, [CrossAxisAlignment.center], the default, centers the
3766  /// children in the cross axis (e.g., horizontally for a [Column]).
3767  final CrossAxisAlignment crossAxisAlignment;
3768
3769  /// Determines the order to lay children out horizontally and how to interpret
3770  /// `start` and `end` in the horizontal direction.
3771  ///
3772  /// Defaults to the ambient [Directionality].
3773  ///
3774  /// If the [direction] is [Axis.horizontal], this controls the order in which
3775  /// the children are positioned (left-to-right or right-to-left), and the
3776  /// meaning of the [mainAxisAlignment] property's [MainAxisAlignment.start] and
3777  /// [MainAxisAlignment.end] values.
3778  ///
3779  /// If the [direction] is [Axis.horizontal], and either the
3780  /// [mainAxisAlignment] is either [MainAxisAlignment.start] or
3781  /// [MainAxisAlignment.end], or there's more than one child, then the
3782  /// [textDirection] (or the ambient [Directionality]) must not be null.
3783  ///
3784  /// If the [direction] is [Axis.vertical], this controls the meaning of the
3785  /// [crossAxisAlignment] property's [CrossAxisAlignment.start] and
3786  /// [CrossAxisAlignment.end] values.
3787  ///
3788  /// If the [direction] is [Axis.vertical], and the [crossAxisAlignment] is
3789  /// either [CrossAxisAlignment.start] or [CrossAxisAlignment.end], then the
3790  /// [textDirection] (or the ambient [Directionality]) must not be null.
3791  final TextDirection textDirection;
3792
3793  /// Determines the order to lay children out vertically and how to interpret
3794  /// `start` and `end` in the vertical direction.
3795  ///
3796  /// Defaults to [VerticalDirection.down].
3797  ///
3798  /// If the [direction] is [Axis.vertical], this controls which order children
3799  /// are painted in (down or up), the meaning of the [mainAxisAlignment]
3800  /// property's [MainAxisAlignment.start] and [MainAxisAlignment.end] values.
3801  ///
3802  /// If the [direction] is [Axis.vertical], and either the [mainAxisAlignment]
3803  /// is either [MainAxisAlignment.start] or [MainAxisAlignment.end], or there's
3804  /// more than one child, then the [verticalDirection] must not be null.
3805  ///
3806  /// If the [direction] is [Axis.horizontal], this controls the meaning of the
3807  /// [crossAxisAlignment] property's [CrossAxisAlignment.start] and
3808  /// [CrossAxisAlignment.end] values.
3809  ///
3810  /// If the [direction] is [Axis.horizontal], and the [crossAxisAlignment] is
3811  /// either [CrossAxisAlignment.start] or [CrossAxisAlignment.end], then the
3812  /// [verticalDirection] must not be null.
3813  final VerticalDirection verticalDirection;
3814
3815  /// If aligning items according to their baseline, which baseline to use.
3816  final TextBaseline textBaseline;
3817
3818  bool get _needTextDirection {
3819    assert(direction != null);
3820    switch (direction) {
3821      case Axis.horizontal:
3822        return true; // because it affects the layout order.
3823      case Axis.vertical:
3824        assert(crossAxisAlignment != null);
3825        return crossAxisAlignment == CrossAxisAlignment.start
3826            || crossAxisAlignment == CrossAxisAlignment.end;
3827    }
3828    return null;
3829  }
3830
3831  /// The value to pass to [RenderFlex.textDirection].
3832  ///
3833  /// This value is derived from the [textDirection] property and the ambient
3834  /// [Directionality]. The value is null if there is no need to specify the
3835  /// text direction. In practice there's always a need to specify the direction
3836  /// except for vertical flexes (e.g. [Column]s) whose [crossAxisAlignment] is
3837  /// not dependent on the text direction (not `start` or `end`). In particular,
3838  /// a [Row] always needs a text direction because the text direction controls
3839  /// its layout order. (For [Column]s, the layout order is controlled by
3840  /// [verticalDirection], which is always specified as it does not depend on an
3841  /// inherited widget and defaults to [VerticalDirection.down].)
3842  ///
3843  /// This method exists so that subclasses of [Flex] that create their own
3844  /// render objects that are derived from [RenderFlex] can do so and still use
3845  /// the logic for providing a text direction only when it is necessary.
3846  @protected
3847  TextDirection getEffectiveTextDirection(BuildContext context) {
3848    return textDirection ?? (_needTextDirection ? Directionality.of(context) : null);
3849  }
3850
3851  @override
3852  RenderFlex createRenderObject(BuildContext context) {
3853    return RenderFlex(
3854      direction: direction,
3855      mainAxisAlignment: mainAxisAlignment,
3856      mainAxisSize: mainAxisSize,
3857      crossAxisAlignment: crossAxisAlignment,
3858      textDirection: getEffectiveTextDirection(context),
3859      verticalDirection: verticalDirection,
3860      textBaseline: textBaseline,
3861    );
3862  }
3863
3864  @override
3865  void updateRenderObject(BuildContext context, covariant RenderFlex renderObject) {
3866    renderObject
3867      ..direction = direction
3868      ..mainAxisAlignment = mainAxisAlignment
3869      ..mainAxisSize = mainAxisSize
3870      ..crossAxisAlignment = crossAxisAlignment
3871      ..textDirection = getEffectiveTextDirection(context)
3872      ..verticalDirection = verticalDirection
3873      ..textBaseline = textBaseline;
3874  }
3875
3876  @override
3877  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
3878    super.debugFillProperties(properties);
3879    properties.add(EnumProperty<Axis>('direction', direction));
3880    properties.add(EnumProperty<MainAxisAlignment>('mainAxisAlignment', mainAxisAlignment));
3881    properties.add(EnumProperty<MainAxisSize>('mainAxisSize', mainAxisSize, defaultValue: MainAxisSize.max));
3882    properties.add(EnumProperty<CrossAxisAlignment>('crossAxisAlignment', crossAxisAlignment));
3883    properties.add(EnumProperty<TextDirection>('textDirection', textDirection, defaultValue: null));
3884    properties.add(EnumProperty<VerticalDirection>('verticalDirection', verticalDirection, defaultValue: VerticalDirection.down));
3885    properties.add(EnumProperty<TextBaseline>('textBaseline', textBaseline, defaultValue: null));
3886  }
3887}
3888
3889/// A widget that displays its children in a horizontal array.
3890///
3891/// To cause a child to expand to fill the available horizontal space, wrap the
3892/// child in an [Expanded] widget.
3893///
3894/// The [Row] widget does not scroll (and in general it is considered an error
3895/// to have more children in a [Row] than will fit in the available room). If
3896/// you have a line of widgets and want them to be able to scroll if there is
3897/// insufficient room, consider using a [ListView].
3898///
3899/// For a vertical variant, see [Column].
3900///
3901/// If you only have one child, then consider using [Align] or [Center] to
3902/// position the child.
3903///
3904/// {@tool sample}
3905///
3906/// This example divides the available space into three (horizontally), and
3907/// places text centered in the first two cells and the Flutter logo centered in
3908/// the third:
3909///
3910/// ![A screenshot of the Row widget](https://flutter.github.io/assets-for-api-docs/assets/widgets/row.png)
3911///
3912/// ```dart
3913/// Row(
3914///   children: <Widget>[
3915///     Expanded(
3916///       child: Text('Deliver features faster', textAlign: TextAlign.center),
3917///     ),
3918///     Expanded(
3919///       child: Text('Craft beautiful UIs', textAlign: TextAlign.center),
3920///     ),
3921///     Expanded(
3922///       child: FittedBox(
3923///         fit: BoxFit.contain, // otherwise the logo will be tiny
3924///         child: const FlutterLogo(),
3925///       ),
3926///     ),
3927///   ],
3928/// )
3929/// ```
3930/// {@end-tool}
3931///
3932/// ## Troubleshooting
3933///
3934/// ### Why does my row have a yellow and black warning stripe?
3935///
3936/// If the non-flexible contents of the row (those that are not wrapped in
3937/// [Expanded] or [Flexible] widgets) are together wider than the row itself,
3938/// then the row is said to have overflowed. When a row overflows, the row does
3939/// not have any remaining space to share between its [Expanded] and [Flexible]
3940/// children. The row reports this by drawing a yellow and black striped
3941/// warning box on the edge that is overflowing. If there is room on the outside
3942/// of the row, the amount of overflow is printed in red lettering.
3943///
3944/// #### Story time
3945///
3946/// Suppose, for instance, that you had this code:
3947///
3948/// ```dart
3949/// Row(
3950///   children: <Widget>[
3951///     const FlutterLogo(),
3952///     const Text('Flutter\'s hot reload helps you quickly and easily experiment, build UIs, add features, and fix bug faster. Experience sub-second reload times, without losing state, on emulators, simulators, and hardware for iOS and Android.'),
3953///     const Icon(Icons.sentiment_very_satisfied),
3954///   ],
3955/// )
3956/// ```
3957///
3958/// You will see this issue when you run the app:
3959///
3960/// ![A screenshot of the error using the Row widget](https://flutter.github.io/assets-for-api-docs/assets/widgets/row_error.png)
3961///
3962/// The row first asks its first child, the [FlutterLogo], to lay out, at
3963/// whatever size the logo would like. The logo is friendly and happily decides
3964/// to be 24 pixels to a side. This leaves lots of room for the next child. The
3965/// row then asks that next child, the text, to lay out, at whatever size it
3966/// thinks is best.
3967///
3968/// At this point, the text, not knowing how wide is too wide, says "Ok, I will
3969/// be thiiiiiiiiiiiiiiiiiiiis wide.", and goes well beyond the space that the
3970/// row has available, not wrapping. The row responds, "That's not fair, now I
3971/// have no more room available for my other children!", and gets angry and
3972/// sprouts a yellow and black strip.
3973///
3974/// {@tool sample}
3975/// The fix is to wrap the second child in an [Expanded] widget, which tells the
3976/// row that the child should be given the remaining room:
3977///
3978/// ![A screenshot of the Row widget after applying the fix](https://flutter.github.io/assets-for-api-docs/assets/widgets/row_fixed.png)
3979///
3980/// ```dart
3981/// Row(
3982///   children: <Widget>[
3983///     const FlutterLogo(),
3984///     const Expanded(
3985///       child: Text('Flutter\'s hot reload helps you quickly and easily experiment, build UIs, add features, and fix bug faster. Experience sub-second reload times, without losing state, on emulators, simulators, and hardware for iOS and Android.'),
3986///     ),
3987///     const Icon(Icons.sentiment_very_satisfied),
3988///   ],
3989/// )
3990/// ```
3991/// {@end-tool}
3992///
3993/// Now, the row first asks the logo to lay out, and then asks the _icon_ to lay
3994/// out. The [Icon], like the logo, is happy to take on a reasonable size (also
3995/// 24 pixels, not coincidentally, since both [FlutterLogo] and [Icon] honor the
3996/// ambient [IconTheme]). This leaves some room left over, and now the row tells
3997/// the text exactly how wide to be: the exact width of the remaining space. The
3998/// text, now happy to comply to a reasonable request, wraps the text within
3999/// that width, and you end up with a paragraph split over several lines.
4000///
4001/// ## Layout algorithm
4002///
4003/// _This section describes how a [Row] is rendered by the framework._
4004/// _See [BoxConstraints] for an introduction to box layout models._
4005///
4006/// Layout for a [Row] proceeds in six steps:
4007///
4008/// 1. Layout each child a null or zero flex factor (e.g., those that are not
4009///    [Expanded]) with unbounded horizontal constraints and the incoming
4010///    vertical constraints. If the [crossAxisAlignment] is
4011///    [CrossAxisAlignment.stretch], instead use tight vertical constraints that
4012///    match the incoming max height.
4013/// 2. Divide the remaining horizontal space among the children with non-zero
4014///    flex factors (e.g., those that are [Expanded]) according to their flex
4015///    factor. For example, a child with a flex factor of 2.0 will receive twice
4016///    the amount of horizontal space as a child with a flex factor of 1.0.
4017/// 3. Layout each of the remaining children with the same vertical constraints
4018///    as in step 1, but instead of using unbounded horizontal constraints, use
4019///    horizontal constraints based on the amount of space allocated in step 2.
4020///    Children with [Flexible.fit] properties that are [FlexFit.tight] are
4021///    given tight constraints (i.e., forced to fill the allocated space), and
4022///    children with [Flexible.fit] properties that are [FlexFit.loose] are
4023///    given loose constraints (i.e., not forced to fill the allocated space).
4024/// 4. The height of the [Row] is the maximum height of the children (which will
4025///    always satisfy the incoming vertical constraints).
4026/// 5. The width of the [Row] is determined by the [mainAxisSize] property. If
4027///    the [mainAxisSize] property is [MainAxisSize.max], then the width of the
4028///    [Row] is the max width of the incoming constraints. If the [mainAxisSize]
4029///    property is [MainAxisSize.min], then the width of the [Row] is the sum
4030///    of widths of the children (subject to the incoming constraints).
4031/// 6. Determine the position for each child according to the
4032///    [mainAxisAlignment] and the [crossAxisAlignment]. For example, if the
4033///    [mainAxisAlignment] is [MainAxisAlignment.spaceBetween], any horizontal
4034///    space that has not been allocated to children is divided evenly and
4035///    placed between the children.
4036///
4037/// See also:
4038///
4039///  * [Column], for a vertical equivalent.
4040///  * [Flex], if you don't know in advance if you want a horizontal or vertical
4041///    arrangement.
4042///  * [Expanded], to indicate children that should take all the remaining room.
4043///  * [Flexible], to indicate children that should share the remaining room but
4044///    that may by sized smaller (leaving some remaining room unused).
4045///  * [Spacer], a widget that takes up space proportional to it's flex value.
4046///  * The [catalog of layout widgets](https://flutter.dev/widgets/layout/).
4047class Row extends Flex {
4048  /// Creates a horizontal array of children.
4049  ///
4050  /// The [direction], [mainAxisAlignment], [mainAxisSize],
4051  /// [crossAxisAlignment], and [verticalDirection] arguments must not be null.
4052  /// If [crossAxisAlignment] is [CrossAxisAlignment.baseline], then
4053  /// [textBaseline] must not be null.
4054  ///
4055  /// The [textDirection] argument defaults to the ambient [Directionality], if
4056  /// any. If there is no ambient directionality, and a text direction is going
4057  /// to be necessary to determine the layout order (which is always the case
4058  /// unless the row has no children or only one child) or to disambiguate
4059  /// `start` or `end` values for the [mainAxisAlignment], the [textDirection]
4060  /// must not be null.
4061  Row({
4062    Key key,
4063    MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start,
4064    MainAxisSize mainAxisSize = MainAxisSize.max,
4065    CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center,
4066    TextDirection textDirection,
4067    VerticalDirection verticalDirection = VerticalDirection.down,
4068    TextBaseline textBaseline,
4069    List<Widget> children = const <Widget>[],
4070  }) : super(
4071    children: children,
4072    key: key,
4073    direction: Axis.horizontal,
4074    mainAxisAlignment: mainAxisAlignment,
4075    mainAxisSize: mainAxisSize,
4076    crossAxisAlignment: crossAxisAlignment,
4077    textDirection: textDirection,
4078    verticalDirection: verticalDirection,
4079    textBaseline: textBaseline,
4080  );
4081}
4082
4083/// A widget that displays its children in a vertical array.
4084///
4085/// To cause a child to expand to fill the available vertical space, wrap the
4086/// child in an [Expanded] widget.
4087///
4088/// The [Column] widget does not scroll (and in general it is considered an error
4089/// to have more children in a [Column] than will fit in the available room). If
4090/// you have a line of widgets and want them to be able to scroll if there is
4091/// insufficient room, consider using a [ListView].
4092///
4093/// For a horizontal variant, see [Row].
4094///
4095/// If you only have one child, then consider using [Align] or [Center] to
4096/// position the child.
4097///
4098/// {@tool sample}
4099///
4100/// This example uses a [Column] to arrange three widgets vertically, the last
4101/// being made to fill all the remaining space.
4102///
4103/// ![A screenshot of the Column widget](https://flutter.github.io/assets-for-api-docs/assets/widgets/column.png)
4104///
4105/// ```dart
4106/// Column(
4107///   children: <Widget>[
4108///     Text('Deliver features faster'),
4109///     Text('Craft beautiful UIs'),
4110///     Expanded(
4111///       child: FittedBox(
4112///         fit: BoxFit.contain, // otherwise the logo will be tiny
4113///         child: const FlutterLogo(),
4114///       ),
4115///     ),
4116///   ],
4117/// )
4118/// ```
4119/// {@end-tool}
4120/// {@tool sample}
4121///
4122/// In the sample above, the text and the logo are centered on each line. In the
4123/// following example, the [crossAxisAlignment] is set to
4124/// [CrossAxisAlignment.start], so that the children are left-aligned. The
4125/// [mainAxisSize] is set to [MainAxisSize.min], so that the column shrinks to
4126/// fit the children.
4127///
4128/// ![A screenshot of the Column widget with a customized crossAxisAlignment and mainAxisSize](https://flutter.github.io/assets-for-api-docs/assets/widgets/column_properties.png)
4129///
4130/// ```dart
4131/// Column(
4132///   crossAxisAlignment: CrossAxisAlignment.start,
4133///   mainAxisSize: MainAxisSize.min,
4134///   children: <Widget>[
4135///     Text('We move under cover and we move as one'),
4136///     Text('Through the night, we have one shot to live another day'),
4137///     Text('We cannot let a stray gunshot give us away'),
4138///     Text('We will fight up close, seize the moment and stay in it'),
4139///     Text('It’s either that or meet the business end of a bayonet'),
4140///     Text('The code word is ‘Rochambeau,’ dig me?'),
4141///     Text('Rochambeau!', style: DefaultTextStyle.of(context).style.apply(fontSizeFactor: 2.0)),
4142///   ],
4143/// )
4144/// ```
4145/// {@end-tool}
4146///
4147/// ## Troubleshooting
4148///
4149/// ### When the incoming vertical constraints are unbounded
4150///
4151/// When a [Column] has one or more [Expanded] or [Flexible] children, and is
4152/// placed in another [Column], or in a [ListView], or in some other context
4153/// that does not provide a maximum height constraint for the [Column], you will
4154/// get an exception at runtime saying that there are children with non-zero
4155/// flex but the vertical constraints are unbounded.
4156///
4157/// The problem, as described in the details that accompany that exception, is
4158/// that using [Flexible] or [Expanded] means that the remaining space after
4159/// laying out all the other children must be shared equally, but if the
4160/// incoming vertical constraints are unbounded, there is infinite remaining
4161/// space.
4162///
4163/// The key to solving this problem is usually to determine why the [Column] is
4164/// receiving unbounded vertical constraints.
4165///
4166/// One common reason for this to happen is that the [Column] has been placed in
4167/// another [Column] (without using [Expanded] or [Flexible] around the inner
4168/// nested [Column]). When a [Column] lays out its non-flex children (those that
4169/// have neither [Expanded] or [Flexible] around them), it gives them unbounded
4170/// constraints so that they can determine their own dimensions (passing
4171/// unbounded constraints usually signals to the child that it should
4172/// shrink-wrap its contents). The solution in this case is typically to just
4173/// wrap the inner column in an [Expanded] to indicate that it should take the
4174/// remaining space of the outer column, rather than being allowed to take any
4175/// amount of room it desires.
4176///
4177/// Another reason for this message to be displayed is nesting a [Column] inside
4178/// a [ListView] or other vertical scrollable. In that scenario, there really is
4179/// infinite vertical space (the whole point of a vertical scrolling list is to
4180/// allow infinite space vertically). In such scenarios, it is usually worth
4181/// examining why the inner [Column] should have an [Expanded] or [Flexible]
4182/// child: what size should the inner children really be? The solution in this
4183/// case is typically to remove the [Expanded] or [Flexible] widgets from around
4184/// the inner children.
4185///
4186/// For more discussion about constraints, see [BoxConstraints].
4187///
4188/// ### The yellow and black striped banner
4189///
4190/// When the contents of a [Column] exceed the amount of space available, the
4191/// [Column] overflows, and the contents are clipped. In debug mode, a yellow
4192/// and black striped bar is rendered at the overflowing edge to indicate the
4193/// problem, and a message is printed below the [Column] saying how much
4194/// overflow was detected.
4195///
4196/// The usual solution is to use a [ListView] rather than a [Column], to enable
4197/// the contents to scroll when vertical space is limited.
4198///
4199/// ## Layout algorithm
4200///
4201/// _This section describes how a [Column] is rendered by the framework._
4202/// _See [BoxConstraints] for an introduction to box layout models._
4203///
4204/// Layout for a [Column] proceeds in six steps:
4205///
4206/// 1. Layout each child a null or zero flex factor (e.g., those that are not
4207///    [Expanded]) with unbounded vertical constraints and the incoming
4208///    horizontal constraints. If the [crossAxisAlignment] is
4209///    [CrossAxisAlignment.stretch], instead use tight horizontal constraints
4210///    that match the incoming max width.
4211/// 2. Divide the remaining vertical space among the children with non-zero
4212///    flex factors (e.g., those that are [Expanded]) according to their flex
4213///    factor. For example, a child with a flex factor of 2.0 will receive twice
4214///    the amount of vertical space as a child with a flex factor of 1.0.
4215/// 3. Layout each of the remaining children with the same horizontal
4216///    constraints as in step 1, but instead of using unbounded vertical
4217///    constraints, use vertical constraints based on the amount of space
4218///    allocated in step 2. Children with [Flexible.fit] properties that are
4219///    [FlexFit.tight] are given tight constraints (i.e., forced to fill the
4220///    allocated space), and children with [Flexible.fit] properties that are
4221///    [FlexFit.loose] are given loose constraints (i.e., not forced to fill the
4222///    allocated space).
4223/// 4. The width of the [Column] is the maximum width of the children (which
4224///    will always satisfy the incoming horizontal constraints).
4225/// 5. The height of the [Column] is determined by the [mainAxisSize] property.
4226///    If the [mainAxisSize] property is [MainAxisSize.max], then the height of
4227///    the [Column] is the max height of the incoming constraints. If the
4228///    [mainAxisSize] property is [MainAxisSize.min], then the height of the
4229///    [Column] is the sum of heights of the children (subject to the incoming
4230///    constraints).
4231/// 6. Determine the position for each child according to the
4232///    [mainAxisAlignment] and the [crossAxisAlignment]. For example, if the
4233///    [mainAxisAlignment] is [MainAxisAlignment.spaceBetween], any vertical
4234///    space that has not been allocated to children is divided evenly and
4235///    placed between the children.
4236///
4237/// See also:
4238///
4239///  * [Row], for a horizontal equivalent.
4240///  * [Flex], if you don't know in advance if you want a horizontal or vertical
4241///    arrangement.
4242///  * [Expanded], to indicate children that should take all the remaining room.
4243///  * [Flexible], to indicate children that should share the remaining room but
4244///    that may size smaller (leaving some remaining room unused).
4245///  * [SingleChildScrollView], whose documentation discusses some ways to
4246///    use a [Column] inside a scrolling container.
4247///  * [Spacer], a widget that takes up space proportional to it's flex value.
4248///  * The [catalog of layout widgets](https://flutter.dev/widgets/layout/).
4249class Column extends Flex {
4250  /// Creates a vertical array of children.
4251  ///
4252  /// The [direction], [mainAxisAlignment], [mainAxisSize],
4253  /// [crossAxisAlignment], and [verticalDirection] arguments must not be null.
4254  /// If [crossAxisAlignment] is [CrossAxisAlignment.baseline], then
4255  /// [textBaseline] must not be null.
4256  ///
4257  /// The [textDirection] argument defaults to the ambient [Directionality], if
4258  /// any. If there is no ambient directionality, and a text direction is going
4259  /// to be necessary to disambiguate `start` or `end` values for the
4260  /// [crossAxisAlignment], the [textDirection] must not be null.
4261  Column({
4262    Key key,
4263    MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start,
4264    MainAxisSize mainAxisSize = MainAxisSize.max,
4265    CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center,
4266    TextDirection textDirection,
4267    VerticalDirection verticalDirection = VerticalDirection.down,
4268    TextBaseline textBaseline,
4269    List<Widget> children = const <Widget>[],
4270  }) : super(
4271    children: children,
4272    key: key,
4273    direction: Axis.vertical,
4274    mainAxisAlignment: mainAxisAlignment,
4275    mainAxisSize: mainAxisSize,
4276    crossAxisAlignment: crossAxisAlignment,
4277    textDirection: textDirection,
4278    verticalDirection: verticalDirection,
4279    textBaseline: textBaseline,
4280  );
4281}
4282
4283/// A widget that controls how a child of a [Row], [Column], or [Flex] flexes.
4284///
4285/// Using a [Flexible] widget gives a child of a [Row], [Column], or [Flex]
4286/// the flexibility to expand to fill the available space in the main axis
4287/// (e.g., horizontally for a [Row] or vertically for a [Column]), but, unlike
4288/// [Expanded], [Flexible] does not require the child to fill the available
4289/// space.
4290///
4291/// A [Flexible] widget must be a descendant of a [Row], [Column], or [Flex],
4292/// and the path from the [Flexible] widget to its enclosing [Row], [Column], or
4293/// [Flex] must contain only [StatelessWidget]s or [StatefulWidget]s (not other
4294/// kinds of widgets, like [RenderObjectWidget]s).
4295///
4296/// {@youtube 560 315 https://www.youtube.com/watch?v=CI7x0mAZiY0}
4297///
4298/// See also:
4299///
4300///  * [Expanded], which forces the child to expand to fill the available space.
4301///  * [Spacer], a widget that takes up space proportional to it's flex value.
4302///  * The [catalog of layout widgets](https://flutter.dev/widgets/layout/).
4303class Flexible extends ParentDataWidget<Flex> {
4304  /// Creates a widget that controls how a child of a [Row], [Column], or [Flex]
4305  /// flexes.
4306  const Flexible({
4307    Key key,
4308    this.flex = 1,
4309    this.fit = FlexFit.loose,
4310    @required Widget child,
4311  }) : super(key: key, child: child);
4312
4313  /// The flex factor to use for this child
4314  ///
4315  /// If null or zero, the child is inflexible and determines its own size. If
4316  /// non-zero, the amount of space the child's can occupy in the main axis is
4317  /// determined by dividing the free space (after placing the inflexible
4318  /// children) according to the flex factors of the flexible children.
4319  final int flex;
4320
4321  /// How a flexible child is inscribed into the available space.
4322  ///
4323  /// If [flex] is non-zero, the [fit] determines whether the child fills the
4324  /// space the parent makes available during layout. If the fit is
4325  /// [FlexFit.tight], the child is required to fill the available space. If the
4326  /// fit is [FlexFit.loose], the child can be at most as large as the available
4327  /// space (but is allowed to be smaller).
4328  final FlexFit fit;
4329
4330  @override
4331  void applyParentData(RenderObject renderObject) {
4332    assert(renderObject.parentData is FlexParentData);
4333    final FlexParentData parentData = renderObject.parentData;
4334    bool needsLayout = false;
4335
4336    if (parentData.flex != flex) {
4337      parentData.flex = flex;
4338      needsLayout = true;
4339    }
4340
4341    if (parentData.fit != fit) {
4342      parentData.fit = fit;
4343      needsLayout = true;
4344    }
4345
4346    if (needsLayout) {
4347      final AbstractNode targetParent = renderObject.parent;
4348      if (targetParent is RenderObject)
4349        targetParent.markNeedsLayout();
4350    }
4351  }
4352
4353  @override
4354  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
4355    super.debugFillProperties(properties);
4356    properties.add(IntProperty('flex', flex));
4357  }
4358}
4359
4360/// A widget that expands a child of a [Row], [Column], or [Flex]
4361/// so that the child fills the available space.
4362///
4363/// Using an [Expanded] widget makes a child of a [Row], [Column], or [Flex]
4364/// expand to fill the available space along the main axis (e.g., horizontally for
4365/// a [Row] or vertically for a [Column]). If multiple children are expanded,
4366/// the available space is divided among them according to the [flex] factor.
4367///
4368/// An [Expanded] widget must be a descendant of a [Row], [Column], or [Flex],
4369/// and the path from the [Expanded] widget to its enclosing [Row], [Column], or
4370/// [Flex] must contain only [StatelessWidget]s or [StatefulWidget]s (not other
4371/// kinds of widgets, like [RenderObjectWidget]s).
4372///
4373/// {@youtube 560 315 https://www.youtube.com/watch?v=_rnZaagadyo}
4374///
4375/// {@tool snippet --template=stateless_widget_material}
4376/// This example shows how to use an [Expanded] widget in a [Column] so that
4377/// it's middle child, a [Container] here, expands to fill the space.
4378///
4379/// ![An example using Expanded widget in a Column](https://flutter.github.io/assets-for-api-docs/assets/widgets/expanded_column.png)
4380///
4381/// ```dart
4382/// Widget build(BuildContext context) {
4383///   return Scaffold(
4384///     appBar: AppBar(
4385///       title: Text('Expanded Column Sample'),
4386///     ),
4387///     body: Center(
4388///        child: Column(
4389///         children: <Widget>[
4390///           Container(
4391///             color: Colors.blue,
4392///             height: 100,
4393///             width: 100,
4394///           ),
4395///           Expanded(
4396///             child: Container(
4397///               color: Colors.amber,
4398///               width: 100,
4399///             ),
4400///           ),
4401///           Container(
4402///             color: Colors.blue,
4403///             height: 100,
4404///             width: 100,
4405///           ),
4406///         ],
4407///       ),
4408///     ),
4409///   );
4410/// }
4411/// ```
4412/// {@end-tool}
4413///
4414/// {@tool snippet --template=stateless_widget_material}
4415/// This example shows how to use an [Expanded] widget in a [Row] with multiple
4416/// children expanded, utilizing the [flex] factor to prioritize available space.
4417///
4418/// ![An example using Expanded widget in a Row](https://flutter.github.io/assets-for-api-docs/assets/widgets/expanded_row.png)
4419///
4420/// ```dart
4421/// Widget build(BuildContext context) {
4422///   return Scaffold(
4423///     appBar: AppBar(
4424///       title: Text('Expanded Row Sample'),
4425///     ),
4426///     body: Center(
4427///       child: Row(
4428///         children: <Widget>[
4429///           Expanded(
4430///             flex: 2,
4431///             child: Container(
4432///               color: Colors.amber,
4433///               height: 100,
4434///             ),
4435///           ),
4436///           Container(
4437///             color: Colors.blue,
4438///             height: 100,
4439///             width: 50,
4440///           ),
4441///           Expanded(
4442///             flex: 1,
4443///             child: Container(
4444///               color: Colors.amber,
4445///               height: 100,
4446///             ),
4447///           ),
4448///         ],
4449///       ),
4450///     ),
4451///   );
4452/// }
4453/// ```
4454/// {@end-tool}
4455///
4456/// See also:
4457///
4458///  * [Flexible], which does not force the child to fill the available space.
4459///  * [Spacer], a widget that takes up space proportional to it's flex value.
4460///  * The [catalog of layout widgets](https://flutter.dev/widgets/layout/).
4461class Expanded extends Flexible {
4462  /// Creates a widget that expands a child of a [Row], [Column], or [Flex]
4463  /// so that the child fills the available space along the flex widget's
4464  /// main axis.
4465  const Expanded({
4466    Key key,
4467    int flex = 1,
4468    @required Widget child,
4469  }) : super(key: key, flex: flex, fit: FlexFit.tight, child: child);
4470}
4471
4472/// A widget that displays its children in multiple horizontal or vertical runs.
4473///
4474/// A [Wrap] lays out each child and attempts to place the child adjacent to the
4475/// previous child in the main axis, given by [direction], leaving [spacing]
4476/// space in between. If there is not enough space to fit the child, [Wrap]
4477/// creates a new _run_ adjacent to the existing children in the cross axis.
4478///
4479/// After all the children have been allocated to runs, the children within the
4480/// runs are positioned according to the [alignment] in the main axis and
4481/// according to the [crossAxisAlignment] in the cross axis.
4482///
4483/// The runs themselves are then positioned in the cross axis according to the
4484/// [runSpacing] and [runAlignment].
4485///
4486/// {@youtube 560 315 https://www.youtube.com/watch?v=z5iw2SeFx2M}
4487///
4488/// {@tool sample}
4489///
4490/// This example renders some [Chip]s representing four contacts in a [Wrap] so
4491/// that they flow across lines as necessary.
4492///
4493/// ```dart
4494/// Wrap(
4495///   spacing: 8.0, // gap between adjacent chips
4496///   runSpacing: 4.0, // gap between lines
4497///   children: <Widget>[
4498///     Chip(
4499///       avatar: CircleAvatar(backgroundColor: Colors.blue.shade900, child: Text('AH')),
4500///       label: Text('Hamilton'),
4501///     ),
4502///     Chip(
4503///       avatar: CircleAvatar(backgroundColor: Colors.blue.shade900, child: Text('ML')),
4504///       label: Text('Lafayette'),
4505///     ),
4506///     Chip(
4507///       avatar: CircleAvatar(backgroundColor: Colors.blue.shade900, child: Text('HM')),
4508///       label: Text('Mulligan'),
4509///     ),
4510///     Chip(
4511///       avatar: CircleAvatar(backgroundColor: Colors.blue.shade900, child: Text('JL')),
4512///       label: Text('Laurens'),
4513///     ),
4514///   ],
4515/// )
4516/// ```
4517/// {@end-tool}
4518///
4519/// See also:
4520///
4521///  * [Row], which places children in one line, and gives control over their
4522///    alignment and spacing.
4523///  * The [catalog of layout widgets](https://flutter.dev/widgets/layout/).
4524class Wrap extends MultiChildRenderObjectWidget {
4525  /// Creates a wrap layout.
4526  ///
4527  /// By default, the wrap layout is horizontal and both the children and the
4528  /// runs are aligned to the start.
4529  ///
4530  /// The [textDirection] argument defaults to the ambient [Directionality], if
4531  /// any. If there is no ambient directionality, and a text direction is going
4532  /// to be necessary to decide which direction to lay the children in or to
4533  /// disambiguate `start` or `end` values for the main or cross axis
4534  /// directions, the [textDirection] must not be null.
4535  Wrap({
4536    Key key,
4537    this.direction = Axis.horizontal,
4538    this.alignment = WrapAlignment.start,
4539    this.spacing = 0.0,
4540    this.runAlignment = WrapAlignment.start,
4541    this.runSpacing = 0.0,
4542    this.crossAxisAlignment = WrapCrossAlignment.start,
4543    this.textDirection,
4544    this.verticalDirection = VerticalDirection.down,
4545    List<Widget> children = const <Widget>[],
4546  }) : super(key: key, children: children);
4547
4548  /// The direction to use as the main axis.
4549  ///
4550  /// For example, if [direction] is [Axis.horizontal], the default, the
4551  /// children are placed adjacent to one another in a horizontal run until the
4552  /// available horizontal space is consumed, at which point a subsequent
4553  /// children are placed in a new run vertically adjacent to the previous run.
4554  final Axis direction;
4555
4556  /// How the children within a run should be placed in the main axis.
4557  ///
4558  /// For example, if [alignment] is [WrapAlignment.center], the children in
4559  /// each run are grouped together in the center of their run in the main axis.
4560  ///
4561  /// Defaults to [WrapAlignment.start].
4562  ///
4563  /// See also:
4564  ///
4565  ///  * [runAlignment], which controls how the runs are placed relative to each
4566  ///    other in the cross axis.
4567  ///  * [crossAxisAlignment], which controls how the children within each run
4568  ///    are placed relative to each other in the cross axis.
4569  final WrapAlignment alignment;
4570
4571  /// How much space to place between children in a run in the main axis.
4572  ///
4573  /// For example, if [spacing] is 10.0, the children will be spaced at least
4574  /// 10.0 logical pixels apart in the main axis.
4575  ///
4576  /// If there is additional free space in a run (e.g., because the wrap has a
4577  /// minimum size that is not filled or because some runs are longer than
4578  /// others), the additional free space will be allocated according to the
4579  /// [alignment].
4580  ///
4581  /// Defaults to 0.0.
4582  final double spacing;
4583
4584  /// How the runs themselves should be placed in the cross axis.
4585  ///
4586  /// For example, if [runAlignment] is [WrapAlignment.center], the runs are
4587  /// grouped together in the center of the overall [Wrap] in the cross axis.
4588  ///
4589  /// Defaults to [WrapAlignment.start].
4590  ///
4591  /// See also:
4592  ///
4593  ///  * [alignment], which controls how the children within each run are placed
4594  ///    relative to each other in the main axis.
4595  ///  * [crossAxisAlignment], which controls how the children within each run
4596  ///    are placed relative to each other in the cross axis.
4597  final WrapAlignment runAlignment;
4598
4599  /// How much space to place between the runs themselves in the cross axis.
4600  ///
4601  /// For example, if [runSpacing] is 10.0, the runs will be spaced at least
4602  /// 10.0 logical pixels apart in the cross axis.
4603  ///
4604  /// If there is additional free space in the overall [Wrap] (e.g., because
4605  /// the wrap has a minimum size that is not filled), the additional free space
4606  /// will be allocated according to the [runAlignment].
4607  ///
4608  /// Defaults to 0.0.
4609  final double runSpacing;
4610
4611  /// How the children within a run should be aligned relative to each other in
4612  /// the cross axis.
4613  ///
4614  /// For example, if this is set to [WrapCrossAlignment.end], and the
4615  /// [direction] is [Axis.horizontal], then the children within each
4616  /// run will have their bottom edges aligned to the bottom edge of the run.
4617  ///
4618  /// Defaults to [WrapCrossAlignment.start].
4619  ///
4620  /// See also:
4621  ///
4622  ///  * [alignment], which controls how the children within each run are placed
4623  ///    relative to each other in the main axis.
4624  ///  * [runAlignment], which controls how the runs are placed relative to each
4625  ///    other in the cross axis.
4626  final WrapCrossAlignment crossAxisAlignment;
4627
4628  /// Determines the order to lay children out horizontally and how to interpret
4629  /// `start` and `end` in the horizontal direction.
4630  ///
4631  /// Defaults to the ambient [Directionality].
4632  ///
4633  /// If the [direction] is [Axis.horizontal], this controls order in which the
4634  /// children are positioned (left-to-right or right-to-left), and the meaning
4635  /// of the [alignment] property's [WrapAlignment.start] and
4636  /// [WrapAlignment.end] values.
4637  ///
4638  /// If the [direction] is [Axis.horizontal], and either the
4639  /// [alignment] is either [WrapAlignment.start] or [WrapAlignment.end], or
4640  /// there's more than one child, then the [textDirection] (or the ambient
4641  /// [Directionality]) must not be null.
4642  ///
4643  /// If the [direction] is [Axis.vertical], this controls the order in which
4644  /// runs are positioned, the meaning of the [runAlignment] property's
4645  /// [WrapAlignment.start] and [WrapAlignment.end] values, as well as the
4646  /// [crossAxisAlignment] property's [WrapCrossAlignment.start] and
4647  /// [WrapCrossAlignment.end] values.
4648  ///
4649  /// If the [direction] is [Axis.vertical], and either the
4650  /// [runAlignment] is either [WrapAlignment.start] or [WrapAlignment.end], the
4651  /// [crossAxisAlignment] is either [WrapCrossAlignment.start] or
4652  /// [WrapCrossAlignment.end], or there's more than one child, then the
4653  /// [textDirection] (or the ambient [Directionality]) must not be null.
4654  final TextDirection textDirection;
4655
4656  /// Determines the order to lay children out vertically and how to interpret
4657  /// `start` and `end` in the vertical direction.
4658  ///
4659  /// If the [direction] is [Axis.vertical], this controls which order children
4660  /// are painted in (down or up), the meaning of the [alignment] property's
4661  /// [WrapAlignment.start] and [WrapAlignment.end] values.
4662  ///
4663  /// If the [direction] is [Axis.vertical], and either the [alignment]
4664  /// is either [WrapAlignment.start] or [WrapAlignment.end], or there's
4665  /// more than one child, then the [verticalDirection] must not be null.
4666  ///
4667  /// If the [direction] is [Axis.horizontal], this controls the order in which
4668  /// runs are positioned, the meaning of the [runAlignment] property's
4669  /// [WrapAlignment.start] and [WrapAlignment.end] values, as well as the
4670  /// [crossAxisAlignment] property's [WrapCrossAlignment.start] and
4671  /// [WrapCrossAlignment.end] values.
4672  ///
4673  /// If the [direction] is [Axis.horizontal], and either the
4674  /// [runAlignment] is either [WrapAlignment.start] or [WrapAlignment.end], the
4675  /// [crossAxisAlignment] is either [WrapCrossAlignment.start] or
4676  /// [WrapCrossAlignment.end], or there's more than one child, then the
4677  /// [verticalDirection] must not be null.
4678  final VerticalDirection verticalDirection;
4679
4680  @override
4681  RenderWrap createRenderObject(BuildContext context) {
4682    return RenderWrap(
4683      direction: direction,
4684      alignment: alignment,
4685      spacing: spacing,
4686      runAlignment: runAlignment,
4687      runSpacing: runSpacing,
4688      crossAxisAlignment: crossAxisAlignment,
4689      textDirection: textDirection ?? Directionality.of(context),
4690      verticalDirection: verticalDirection,
4691    );
4692  }
4693
4694  @override
4695  void updateRenderObject(BuildContext context, RenderWrap renderObject) {
4696    renderObject
4697      ..direction = direction
4698      ..alignment = alignment
4699      ..spacing = spacing
4700      ..runAlignment = runAlignment
4701      ..runSpacing = runSpacing
4702      ..crossAxisAlignment = crossAxisAlignment
4703      ..textDirection = textDirection ?? Directionality.of(context)
4704      ..verticalDirection = verticalDirection;
4705  }
4706
4707  @override
4708  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
4709    super.debugFillProperties(properties);
4710    properties.add(EnumProperty<Axis>('direction', direction));
4711    properties.add(EnumProperty<WrapAlignment>('alignment', alignment));
4712    properties.add(DoubleProperty('spacing', spacing));
4713    properties.add(EnumProperty<WrapAlignment>('runAlignment', runAlignment));
4714    properties.add(DoubleProperty('runSpacing', runSpacing));
4715    properties.add(DoubleProperty('crossAxisAlignment', runSpacing));
4716    properties.add(EnumProperty<TextDirection>('textDirection', textDirection, defaultValue: null));
4717    properties.add(EnumProperty<VerticalDirection>('verticalDirection', verticalDirection, defaultValue: VerticalDirection.down));
4718  }
4719}
4720
4721/// A widget that sizes and positions children efficiently, according to the
4722/// logic in a [FlowDelegate].
4723///
4724/// Flow layouts are optimized for repositioning children using transformation
4725/// matrices.
4726///
4727/// The flow container is sized independently from the children by the
4728/// [FlowDelegate.getSize] function of the delegate. The children are then sized
4729/// independently given the constraints from the
4730/// [FlowDelegate.getConstraintsForChild] function.
4731///
4732/// Rather than positioning the children during layout, the children are
4733/// positioned using transformation matrices during the paint phase using the
4734/// matrices from the [FlowDelegate.paintChildren] function. The children can be
4735/// repositioned efficiently by simply repainting the flow, which happens
4736/// without the children being laid out again (contrast this with a [Stack],
4737/// which does the sizing and positioning together during layout).
4738///
4739/// The most efficient way to trigger a repaint of the flow is to supply an
4740/// animation to the constructor of the [FlowDelegate]. The flow will listen to
4741/// this animation and repaint whenever the animation ticks, avoiding both the
4742/// build and layout phases of the pipeline.
4743///
4744/// See also:
4745///
4746///  * [Wrap], which provides the layout model that some other frameworks call
4747///    "flow", and is otherwise unrelated to [Flow].
4748///  * [FlowDelegate], which controls the visual presentation of the children.
4749///  * [Stack], which arranges children relative to the edges of the container.
4750///  * [CustomSingleChildLayout], which uses a delegate to control the layout of
4751///    a single child.
4752///  * [CustomMultiChildLayout], which uses a delegate to position multiple
4753///    children.
4754///  * The [catalog of layout widgets](https://flutter.dev/widgets/layout/).
4755///
4756///
4757/// {@animation 450 100 https://flutter.github.io/assets-for-api-docs/assets/widgets/flow_menu.mp4}
4758///
4759/// {@tool snippet --template=freeform}
4760///
4761/// This example uses the [Flow] widget to create a menu that opens and closes
4762/// as it is interacted with, shown above. The color of the button in the menu
4763/// changes to indicate which one has been selected.
4764///
4765/// ```dart main
4766/// import 'package:flutter/material.dart';
4767///
4768/// void main() => runApp(FlowApp());
4769///
4770/// class FlowApp extends StatelessWidget {
4771///   @override
4772///   Widget build(BuildContext context) {
4773///     return MaterialApp(
4774///       home: Scaffold(
4775///         appBar: AppBar(
4776///           title: const Text('Flow Example'),
4777///         ),
4778///         body: FlowMenu(),
4779///       ),
4780///     );
4781///   }
4782/// }
4783///
4784/// class FlowMenu extends StatefulWidget {
4785///   @override
4786///   _FlowMenuState createState() => _FlowMenuState();
4787/// }
4788///
4789/// class _FlowMenuState extends State<FlowMenu> with SingleTickerProviderStateMixin {
4790///   AnimationController menuAnimation;
4791///   IconData lastTapped = Icons.notifications;
4792///   final List<IconData> menuItems = <IconData>[
4793///     Icons.home,
4794///     Icons.new_releases,
4795///     Icons.notifications,
4796///     Icons.settings,
4797///     Icons.menu,
4798///   ];
4799///
4800///   void _updateMenu(IconData icon) {
4801///     if (icon != Icons.menu)
4802///       setState(() => lastTapped = icon);
4803///   }
4804///
4805///   @override
4806///   void initState() {
4807///     super.initState();
4808///     menuAnimation = AnimationController(
4809///       duration: const Duration(milliseconds: 250),
4810///       vsync: this,
4811///     );
4812///   }
4813///
4814///   Widget flowMenuItem(IconData icon) {
4815///     final double buttonDiameter = MediaQuery.of(context).size.width / menuItems.length;
4816///     return Padding(
4817///       padding: const EdgeInsets.symmetric(vertical: 8.0),
4818///       child: RawMaterialButton(
4819///         fillColor: lastTapped == icon ? Colors.amber[700] : Colors.blue,
4820///         splashColor: Colors.amber[100],
4821///         shape: CircleBorder(),
4822///         constraints: BoxConstraints.tight(Size(buttonDiameter, buttonDiameter)),
4823///         onPressed: () {
4824///           _updateMenu(icon);
4825///           menuAnimation.status == AnimationStatus.completed
4826///             ? menuAnimation.reverse()
4827///             : menuAnimation.forward();
4828///         },
4829///         child: Icon(
4830///           icon,
4831///           color: Colors.white,
4832///           size: 45.0,
4833///         ),
4834///       ),
4835///     );
4836///   }
4837///
4838///   @override
4839///   Widget build(BuildContext context) {
4840///     return Container(
4841///       child: Flow(
4842///         delegate: FlowMenuDelegate(menuAnimation: menuAnimation),
4843///         children: menuItems.map<Widget>((IconData icon) => flowMenuItem(icon)).toList(),
4844///       ),
4845///     );
4846///   }
4847/// }
4848///
4849/// class FlowMenuDelegate extends FlowDelegate {
4850///   FlowMenuDelegate({this.menuAnimation}) : super(repaint: menuAnimation);
4851///
4852///   final Animation<double> menuAnimation;
4853///
4854///   @override
4855///   bool shouldRepaint(FlowMenuDelegate oldDelegate) {
4856///     return menuAnimation != oldDelegate.menuAnimation;
4857///   }
4858///
4859///   @override
4860///   void paintChildren(FlowPaintingContext context) {
4861///     double dx = 0.0;
4862///     for (int i = 0; i < context.childCount; ++i) {
4863///       dx = context.getChildSize(i).width * i;
4864///       context.paintChild(
4865///         i,
4866///         transform: Matrix4.translationValues(
4867///           dx * menuAnimation.value,
4868///           0,
4869///           0,
4870///         ),
4871///       );
4872///     }
4873///   }
4874/// }
4875/// ```
4876/// {@end-tool}
4877///
4878class Flow extends MultiChildRenderObjectWidget {
4879  /// Creates a flow layout.
4880  ///
4881  /// Wraps each of the given children in a [RepaintBoundary] to avoid
4882  /// repainting the children when the flow repaints.
4883  ///
4884  /// The [delegate] argument must not be null.
4885  Flow({
4886    Key key,
4887    @required this.delegate,
4888    List<Widget> children = const <Widget>[],
4889  }) : assert(delegate != null),
4890       super(key: key, children: RepaintBoundary.wrapAll(children));
4891       // https://github.com/dart-lang/sdk/issues/29277
4892
4893  /// Creates a flow layout.
4894  ///
4895  /// Does not wrap the given children in repaint boundaries, unlike the default
4896  /// constructor. Useful when the child is trivial to paint or already contains
4897  /// a repaint boundary.
4898  ///
4899  /// The [delegate] argument must not be null.
4900  Flow.unwrapped({
4901    Key key,
4902    @required this.delegate,
4903    List<Widget> children = const <Widget>[],
4904  }) : assert(delegate != null),
4905       super(key: key, children: children);
4906
4907  /// The delegate that controls the transformation matrices of the children.
4908  final FlowDelegate delegate;
4909
4910  @override
4911  RenderFlow createRenderObject(BuildContext context) => RenderFlow(delegate: delegate);
4912
4913  @override
4914  void updateRenderObject(BuildContext context, RenderFlow renderObject) {
4915    renderObject
4916      ..delegate = delegate;
4917  }
4918}
4919
4920/// A paragraph of rich text.
4921///
4922/// The [RichText] widget displays text that uses multiple different styles. The
4923/// text to display is described using a tree of [TextSpan] objects, each of
4924/// which has an associated style that is used for that subtree. The text might
4925/// break across multiple lines or might all be displayed on the same line
4926/// depending on the layout constraints.
4927///
4928/// Text displayed in a [RichText] widget must be explicitly styled. When
4929/// picking which style to use, consider using [DefaultTextStyle.of] the current
4930/// [BuildContext] to provide defaults. For more details on how to style text in
4931/// a [RichText] widget, see the documentation for [TextStyle].
4932///
4933/// Consider using the [Text] widget to integrate with the [DefaultTextStyle]
4934/// automatically. When all the text uses the same style, the default constructor
4935/// is less verbose. The [Text.rich] constructor allows you to style multiple
4936/// spans with the default text style while still allowing specified styles per
4937/// span.
4938///
4939/// {@tool sample}
4940///
4941/// ```dart
4942/// RichText(
4943///   text: TextSpan(
4944///     text: 'Hello ',
4945///     style: DefaultTextStyle.of(context).style,
4946///     children: <TextSpan>[
4947///       TextSpan(text: 'bold', style: TextStyle(fontWeight: FontWeight.bold)),
4948///       TextSpan(text: ' world!'),
4949///     ],
4950///   ),
4951/// )
4952/// ```
4953/// {@end-tool}
4954///
4955/// See also:
4956///
4957///  * [TextStyle], which discusses how to style text.
4958///  * [TextSpan], which is used to describe the text in a paragraph.
4959///  * [Text], which automatically applies the ambient styles described by a
4960///    [DefaultTextStyle] to a single string.
4961///  * [Text.rich], a const text widget that provides similar functionality
4962///    as [RichText]. [Text.rich] will inherit [TextStyle] from [DefaultTextStyle].
4963class RichText extends MultiChildRenderObjectWidget {
4964  /// Creates a paragraph of rich text.
4965  ///
4966  /// The [text], [textAlign], [softWrap], [overflow], and [textScaleFactor]
4967  /// arguments must not be null.
4968  ///
4969  /// The [maxLines] property may be null (and indeed defaults to null), but if
4970  /// it is not null, it must be greater than zero.
4971  ///
4972  /// The [textDirection], if null, defaults to the ambient [Directionality],
4973  /// which in that case must not be null.
4974  RichText({
4975    Key key,
4976    @required this.text,
4977    this.textAlign = TextAlign.start,
4978    this.textDirection,
4979    this.softWrap = true,
4980    this.overflow = TextOverflow.clip,
4981    this.textScaleFactor = 1.0,
4982    this.maxLines,
4983    this.locale,
4984    this.strutStyle,
4985    this.textWidthBasis = TextWidthBasis.parent,
4986  }) : assert(text != null),
4987       assert(textAlign != null),
4988       assert(softWrap != null),
4989       assert(overflow != null),
4990       assert(textScaleFactor != null),
4991       assert(maxLines == null || maxLines > 0),
4992       assert(textWidthBasis != null),
4993       super(key: key, children: _extractChildren(text));
4994
4995  // Traverses the InlineSpan tree and depth-first collects the list of
4996  // child widgets that are created in WidgetSpans.
4997  static List<Widget> _extractChildren(InlineSpan span) {
4998    final List<Widget> result = <Widget>[];
4999    span.visitChildren((InlineSpan span) {
5000      if (span is WidgetSpan) {
5001        result.add(span.child);
5002      }
5003      return true;
5004    });
5005    return result;
5006  }
5007
5008  /// The text to display in this widget.
5009  final InlineSpan text;
5010
5011  /// How the text should be aligned horizontally.
5012  final TextAlign textAlign;
5013
5014  /// The directionality of the text.
5015  ///
5016  /// This decides how [textAlign] values like [TextAlign.start] and
5017  /// [TextAlign.end] are interpreted.
5018  ///
5019  /// This is also used to disambiguate how to render bidirectional text. For
5020  /// example, if the [text] is an English phrase followed by a Hebrew phrase,
5021  /// in a [TextDirection.ltr] context the English phrase will be on the left
5022  /// and the Hebrew phrase to its right, while in a [TextDirection.rtl]
5023  /// context, the English phrase will be on the right and the Hebrew phrase on
5024  /// its left.
5025  ///
5026  /// Defaults to the ambient [Directionality], if any. If there is no ambient
5027  /// [Directionality], then this must not be null.
5028  final TextDirection textDirection;
5029
5030  /// Whether the text should break at soft line breaks.
5031  ///
5032  /// If false, the glyphs in the text will be positioned as if there was unlimited horizontal space.
5033  final bool softWrap;
5034
5035  /// How visual overflow should be handled.
5036  final TextOverflow overflow;
5037
5038  /// The number of font pixels for each logical pixel.
5039  ///
5040  /// For example, if the text scale factor is 1.5, text will be 50% larger than
5041  /// the specified font size.
5042  final double textScaleFactor;
5043
5044  /// An optional maximum number of lines for the text to span, wrapping if necessary.
5045  /// If the text exceeds the given number of lines, it will be truncated according
5046  /// to [overflow].
5047  ///
5048  /// If this is 1, text will not wrap. Otherwise, text will be wrapped at the
5049  /// edge of the box.
5050  final int maxLines;
5051
5052  /// Used to select a font when the same Unicode character can
5053  /// be rendered differently, depending on the locale.
5054  ///
5055  /// It's rarely necessary to set this property. By default its value
5056  /// is inherited from the enclosing app with `Localizations.localeOf(context)`.
5057  ///
5058  /// See [RenderParagraph.locale] for more information.
5059  final Locale locale;
5060
5061  /// {@macro flutter.painting.textPainter.strutStyle}
5062  final StrutStyle strutStyle;
5063
5064  /// {@macro flutter.widgets.text.DefaultTextStyle.textWidthBasis}
5065  final TextWidthBasis textWidthBasis;
5066
5067  @override
5068  RenderParagraph createRenderObject(BuildContext context) {
5069    assert(textDirection != null || debugCheckHasDirectionality(context));
5070    return RenderParagraph(text,
5071      textAlign: textAlign,
5072      textDirection: textDirection ?? Directionality.of(context),
5073      softWrap: softWrap,
5074      overflow: overflow,
5075      textScaleFactor: textScaleFactor,
5076      maxLines: maxLines,
5077      strutStyle: strutStyle,
5078      textWidthBasis: textWidthBasis,
5079      locale: locale ?? Localizations.localeOf(context, nullOk: true),
5080    );
5081  }
5082
5083  @override
5084  void updateRenderObject(BuildContext context, RenderParagraph renderObject) {
5085    assert(textDirection != null || debugCheckHasDirectionality(context));
5086    renderObject
5087      ..text = text
5088      ..textAlign = textAlign
5089      ..textDirection = textDirection ?? Directionality.of(context)
5090      ..softWrap = softWrap
5091      ..overflow = overflow
5092      ..textScaleFactor = textScaleFactor
5093      ..maxLines = maxLines
5094      ..strutStyle = strutStyle
5095      ..textWidthBasis = textWidthBasis
5096      ..locale = locale ?? Localizations.localeOf(context, nullOk: true);
5097  }
5098
5099  @override
5100  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
5101    super.debugFillProperties(properties);
5102    properties.add(EnumProperty<TextAlign>('textAlign', textAlign, defaultValue: TextAlign.start));
5103    properties.add(EnumProperty<TextDirection>('textDirection', textDirection, defaultValue: null));
5104    properties.add(FlagProperty('softWrap', value: softWrap, ifTrue: 'wrapping at box width', ifFalse: 'no wrapping except at line break characters', showName: true));
5105    properties.add(EnumProperty<TextOverflow>('overflow', overflow, defaultValue: TextOverflow.clip));
5106    properties.add(DoubleProperty('textScaleFactor', textScaleFactor, defaultValue: 1.0));
5107    properties.add(IntProperty('maxLines', maxLines, ifNull: 'unlimited'));
5108    properties.add(EnumProperty<TextWidthBasis>('textWidthBasis', textWidthBasis, defaultValue: TextWidthBasis.parent));
5109    properties.add(StringProperty('text', text.toPlainText()));
5110  }
5111}
5112
5113/// A widget that displays a [dart:ui.Image] directly.
5114///
5115/// The image is painted using [paintImage], which describes the meanings of the
5116/// various fields on this class in more detail.
5117///
5118/// This widget is rarely used directly. Instead, consider using [Image].
5119class RawImage extends LeafRenderObjectWidget {
5120  /// Creates a widget that displays an image.
5121  ///
5122  /// The [scale], [alignment], [repeat], [matchTextDirection] and [filterQuality] arguments must
5123  /// not be null.
5124  const RawImage({
5125    Key key,
5126    this.image,
5127    this.width,
5128    this.height,
5129    this.scale = 1.0,
5130    this.color,
5131    this.colorBlendMode,
5132    this.fit,
5133    this.alignment = Alignment.center,
5134    this.repeat = ImageRepeat.noRepeat,
5135    this.centerSlice,
5136    this.matchTextDirection = false,
5137    this.invertColors = false,
5138    this.filterQuality = FilterQuality.low,
5139  }) : assert(scale != null),
5140       assert(alignment != null),
5141       assert(repeat != null),
5142       assert(matchTextDirection != null),
5143       super(key: key);
5144
5145  /// The image to display.
5146  final ui.Image image;
5147
5148  /// If non-null, require the image to have this width.
5149  ///
5150  /// If null, the image will pick a size that best preserves its intrinsic
5151  /// aspect ratio.
5152  final double width;
5153
5154  /// If non-null, require the image to have this height.
5155  ///
5156  /// If null, the image will pick a size that best preserves its intrinsic
5157  /// aspect ratio.
5158  final double height;
5159
5160  /// Specifies the image's scale.
5161  ///
5162  /// Used when determining the best display size for the image.
5163  final double scale;
5164
5165  /// If non-null, this color is blended with each image pixel using [colorBlendMode].
5166  final Color color;
5167
5168  /// Used to set the filterQuality of the image
5169  /// Use the "low" quality setting to scale the image, which corresponds to
5170  /// bilinear interpolation, rather than the default "none" which corresponds
5171  /// to nearest-neighbor.
5172  final FilterQuality filterQuality;
5173
5174  /// Used to combine [color] with this image.
5175  ///
5176  /// The default is [BlendMode.srcIn]. In terms of the blend mode, [color] is
5177  /// the source and this image is the destination.
5178  ///
5179  /// See also:
5180  ///
5181  ///  * [BlendMode], which includes an illustration of the effect of each blend mode.
5182  final BlendMode colorBlendMode;
5183
5184  /// How to inscribe the image into the space allocated during layout.
5185  ///
5186  /// The default varies based on the other fields. See the discussion at
5187  /// [paintImage].
5188  final BoxFit fit;
5189
5190  /// How to align the image within its bounds.
5191  ///
5192  /// The alignment aligns the given position in the image to the given position
5193  /// in the layout bounds. For example, an [Alignment] alignment of (-1.0,
5194  /// -1.0) aligns the image to the top-left corner of its layout bounds, while a
5195  /// [Alignment] alignment of (1.0, 1.0) aligns the bottom right of the
5196  /// image with the bottom right corner of its layout bounds. Similarly, an
5197  /// alignment of (0.0, 1.0) aligns the bottom middle of the image with the
5198  /// middle of the bottom edge of its layout bounds.
5199  ///
5200  /// To display a subpart of an image, consider using a [CustomPainter] and
5201  /// [Canvas.drawImageRect].
5202  ///
5203  /// If the [alignment] is [TextDirection]-dependent (i.e. if it is a
5204  /// [AlignmentDirectional]), then an ambient [Directionality] widget
5205  /// must be in scope.
5206  ///
5207  /// Defaults to [Alignment.center].
5208  ///
5209  /// See also:
5210  ///
5211  ///  * [Alignment], a class with convenient constants typically used to
5212  ///    specify an [AlignmentGeometry].
5213  ///  * [AlignmentDirectional], like [Alignment] for specifying alignments
5214  ///    relative to text direction.
5215  final AlignmentGeometry alignment;
5216
5217  /// How to paint any portions of the layout bounds not covered by the image.
5218  final ImageRepeat repeat;
5219
5220  /// The center slice for a nine-patch image.
5221  ///
5222  /// The region of the image inside the center slice will be stretched both
5223  /// horizontally and vertically to fit the image into its destination. The
5224  /// region of the image above and below the center slice will be stretched
5225  /// only horizontally and the region of the image to the left and right of
5226  /// the center slice will be stretched only vertically.
5227  final Rect centerSlice;
5228
5229  /// Whether to paint the image in the direction of the [TextDirection].
5230  ///
5231  /// If this is true, then in [TextDirection.ltr] contexts, the image will be
5232  /// drawn with its origin in the top left (the "normal" painting direction for
5233  /// images); and in [TextDirection.rtl] contexts, the image will be drawn with
5234  /// a scaling factor of -1 in the horizontal direction so that the origin is
5235  /// in the top right.
5236  ///
5237  /// This is occasionally used with images in right-to-left environments, for
5238  /// images that were designed for left-to-right locales. Be careful, when
5239  /// using this, to not flip images with integral shadows, text, or other
5240  /// effects that will look incorrect when flipped.
5241  ///
5242  /// If this is true, there must be an ambient [Directionality] widget in
5243  /// scope.
5244  final bool matchTextDirection;
5245
5246  /// Whether the colors of the image are inverted when drawn.
5247  ///
5248  /// inverting the colors of an image applies a new color filter to the paint.
5249  /// If there is another specified color filter, the invert will be applied
5250  /// after it. This is primarily used for implementing smart invert on iOS.
5251  ///
5252  /// See also:
5253  ///
5254  ///  * [Paint.invertColors], for the dart:ui implementation.
5255  final bool invertColors;
5256
5257  @override
5258  RenderImage createRenderObject(BuildContext context) {
5259    assert((!matchTextDirection && alignment is Alignment) || debugCheckHasDirectionality(context));
5260    return RenderImage(
5261      image: image,
5262      width: width,
5263      height: height,
5264      scale: scale,
5265      color: color,
5266      colorBlendMode: colorBlendMode,
5267      fit: fit,
5268      alignment: alignment,
5269      repeat: repeat,
5270      centerSlice: centerSlice,
5271      matchTextDirection: matchTextDirection,
5272      textDirection: matchTextDirection || alignment is! Alignment ? Directionality.of(context) : null,
5273      invertColors: invertColors,
5274      filterQuality: filterQuality,
5275    );
5276  }
5277
5278  @override
5279  void updateRenderObject(BuildContext context, RenderImage renderObject) {
5280    renderObject
5281      ..image = image
5282      ..width = width
5283      ..height = height
5284      ..scale = scale
5285      ..color = color
5286      ..colorBlendMode = colorBlendMode
5287      ..alignment = alignment
5288      ..fit = fit
5289      ..repeat = repeat
5290      ..centerSlice = centerSlice
5291      ..matchTextDirection = matchTextDirection
5292      ..textDirection = matchTextDirection || alignment is! Alignment ? Directionality.of(context) : null
5293      ..invertColors = invertColors
5294      ..filterQuality = filterQuality;
5295  }
5296
5297  @override
5298  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
5299    super.debugFillProperties(properties);
5300    properties.add(DiagnosticsProperty<ui.Image>('image', image));
5301    properties.add(DoubleProperty('width', width, defaultValue: null));
5302    properties.add(DoubleProperty('height', height, defaultValue: null));
5303    properties.add(DoubleProperty('scale', scale, defaultValue: 1.0));
5304    properties.add(ColorProperty('color', color, defaultValue: null));
5305    properties.add(EnumProperty<BlendMode>('colorBlendMode', colorBlendMode, defaultValue: null));
5306    properties.add(EnumProperty<BoxFit>('fit', fit, defaultValue: null));
5307    properties.add(DiagnosticsProperty<AlignmentGeometry>('alignment', alignment, defaultValue: null));
5308    properties.add(EnumProperty<ImageRepeat>('repeat', repeat, defaultValue: ImageRepeat.noRepeat));
5309    properties.add(DiagnosticsProperty<Rect>('centerSlice', centerSlice, defaultValue: null));
5310    properties.add(FlagProperty('matchTextDirection', value: matchTextDirection, ifTrue: 'match text direction'));
5311    properties.add(DiagnosticsProperty<bool>('invertColors', invertColors));
5312    properties.add(EnumProperty<FilterQuality>('filterQuality', filterQuality));
5313  }
5314}
5315
5316/// A widget that determines the default asset bundle for its descendants.
5317///
5318/// For example, used by [Image] to determine which bundle to use for
5319/// [AssetImage]s if no bundle is specified explicitly.
5320///
5321/// {@tool sample}
5322///
5323/// This can be used in tests to override what the current asset bundle is, thus
5324/// allowing specific resources to be injected into the widget under test.
5325///
5326/// For example, a test could create a test asset bundle like this:
5327///
5328/// ```dart
5329/// class TestAssetBundle extends CachingAssetBundle {
5330///   @override
5331///   Future<ByteData> load(String key) async {
5332///     if (key == 'resources/test')
5333///       return ByteData.view(Uint8List.fromList(utf8.encode('Hello World!')).buffer);
5334///     return null;
5335///   }
5336/// }
5337/// ```
5338/// {@end-tool}
5339/// {@tool sample}
5340///
5341/// ...then wrap the widget under test with a [DefaultAssetBundle] using this
5342/// bundle implementation:
5343///
5344/// ```dart
5345/// await tester.pumpWidget(
5346///   MaterialApp(
5347///     home: DefaultAssetBundle(
5348///       bundle: TestAssetBundle(),
5349///       child: TestWidget(),
5350///     ),
5351///   ),
5352/// );
5353/// ```
5354/// {@end-tool}
5355///
5356/// Assuming that `TestWidget` uses [DefaultAssetBundle.of] to obtain its
5357/// [AssetBundle], it will now see the [TestAssetBundle]'s "Hello World!" data
5358/// when requesting the "resources/test" asset.
5359///
5360/// See also:
5361///
5362///  * [AssetBundle], the interface for asset bundles.
5363///  * [rootBundle], the default default asset bundle.
5364class DefaultAssetBundle extends InheritedWidget {
5365  /// Creates a widget that determines the default asset bundle for its descendants.
5366  ///
5367  /// The [bundle] and [child] arguments must not be null.
5368  const DefaultAssetBundle({
5369    Key key,
5370    @required this.bundle,
5371    @required Widget child,
5372  }) : assert(bundle != null),
5373       assert(child != null),
5374       super(key: key, child: child);
5375
5376  /// The bundle to use as a default.
5377  final AssetBundle bundle;
5378
5379  /// The bundle from the closest instance of this class that encloses
5380  /// the given context.
5381  ///
5382  /// If there is no [DefaultAssetBundle] ancestor widget in the tree
5383  /// at the given context, then this will return the [rootBundle].
5384  ///
5385  /// Typical usage is as follows:
5386  ///
5387  /// ```dart
5388  /// AssetBundle bundle = DefaultAssetBundle.of(context);
5389  /// ```
5390  static AssetBundle of(BuildContext context) {
5391    final DefaultAssetBundle result = context.inheritFromWidgetOfExactType(DefaultAssetBundle);
5392    return result?.bundle ?? rootBundle;
5393  }
5394
5395  @override
5396  bool updateShouldNotify(DefaultAssetBundle oldWidget) => bundle != oldWidget.bundle;
5397}
5398
5399/// An adapter for placing a specific [RenderBox] in the widget tree.
5400///
5401/// A given render object can be placed at most once in the widget tree. This
5402/// widget enforces that restriction by keying itself using a [GlobalObjectKey]
5403/// for the given render object.
5404class WidgetToRenderBoxAdapter extends LeafRenderObjectWidget {
5405  /// Creates an adapter for placing a specific [RenderBox] in the widget tree.
5406  ///
5407  /// The [renderBox] argument must not be null.
5408  WidgetToRenderBoxAdapter({
5409    @required this.renderBox,
5410    this.onBuild,
5411  }) : assert(renderBox != null),
5412       // WidgetToRenderBoxAdapter objects are keyed to their render box. This
5413       // prevents the widget being used in the widget hierarchy in two different
5414       // places, which would cause the RenderBox to get inserted in multiple
5415       // places in the RenderObject tree.
5416       super(key: GlobalObjectKey(renderBox));
5417
5418  /// The render box to place in the widget tree.
5419  final RenderBox renderBox;
5420
5421  /// Called when it is safe to update the render box and its descendants. If
5422  /// you update the RenderObject subtree under this widget outside of
5423  /// invocations of this callback, features like hit-testing will fail as the
5424  /// tree will be dirty.
5425  final VoidCallback onBuild;
5426
5427  @override
5428  RenderBox createRenderObject(BuildContext context) => renderBox;
5429
5430  @override
5431  void updateRenderObject(BuildContext context, RenderBox renderObject) {
5432    if (onBuild != null)
5433      onBuild();
5434  }
5435}
5436
5437
5438// EVENT HANDLING
5439
5440/// A widget that calls callbacks in response to common pointer events.
5441///
5442/// It listens to events that can construct gestures, such as when the
5443/// pointer is pressed, moved, then released or canceled.
5444///
5445/// It does not listen to events that are exclusive to mouse, such as when the
5446/// mouse enters, exits or hovers a region without pressing any buttons. For
5447/// these events, use [MouseRegion].
5448///
5449/// Rather than listening for raw pointer events, consider listening for
5450/// higher-level gestures using [GestureDetector].
5451///
5452/// ## Layout behavior
5453///
5454/// _See [BoxConstraints] for an introduction to box layout models._
5455///
5456/// If it has a child, this widget defers to the child for sizing behavior. If
5457/// it does not have a child, it grows to fit the parent instead.
5458///
5459/// {@tool snippet --template=stateful_widget_scaffold}
5460/// This example makes a [Container] react to being touched, showing a count of
5461/// the number of pointer downs and ups.
5462///
5463/// ```dart imports
5464/// import 'package:flutter/widgets.dart';
5465/// ```
5466///
5467/// ```dart
5468/// int _downCounter = 0;
5469/// int _upCounter = 0;
5470/// double x = 0.0;
5471/// double y = 0.0;
5472///
5473/// void _incrementDown(PointerEvent details) {
5474///   _updateLocation(details);
5475///   setState(() {
5476///     _downCounter++;
5477///   });
5478/// }
5479/// void _incrementUp(PointerEvent details) {
5480///   _updateLocation(details);
5481///   setState(() {
5482///     _upCounter++;
5483///   });
5484/// }
5485/// void _updateLocation(PointerEvent details) {
5486///   setState(() {
5487///     x = details.position.dx;
5488///     y = details.position.dy;
5489///   });
5490/// }
5491///
5492/// @override
5493/// Widget build(BuildContext context) {
5494///   return Center(
5495///     child: ConstrainedBox(
5496///       constraints: new BoxConstraints.tight(Size(300.0, 200.0)),
5497///       child: Listener(
5498///         onPointerDown: _incrementDown,
5499///         onPointerMove: _updateLocation,
5500///         onPointerUp: _incrementUp,
5501///         child: Container(
5502///           color: Colors.lightBlueAccent,
5503///           child: Column(
5504///             mainAxisAlignment: MainAxisAlignment.center,
5505///             children: <Widget>[
5506///               Text('You have pressed or released in this area this many times:'),
5507///               Text(
5508///                 '$_downCounter presses\n$_upCounter releases',
5509///                 style: Theme.of(context).textTheme.display1,
5510///               ),
5511///               Text(
5512///                 'The cursor is here: (${x.toStringAsFixed(2)}, ${y.toStringAsFixed(2)})',
5513///               ),
5514///             ],
5515///           ),
5516///         ),
5517///       ),
5518///     ),
5519///   );
5520/// }
5521/// ```
5522/// {@end-tool}
5523class Listener extends StatelessWidget {
5524  /// Creates a widget that forwards point events to callbacks.
5525  ///
5526  /// The [behavior] argument defaults to [HitTestBehavior.deferToChild].
5527  const Listener({
5528    Key key,
5529    this.onPointerDown,
5530    this.onPointerMove,
5531    // We have to ignore the lint rule here in order to use deprecated
5532    // parameters and keep backward compatibility.
5533    // TODO(tongmu): After it goes stable, remove these 3 parameters from Listener
5534    // and Listener should no longer need an intermediate class _PointerListener.
5535    // https://github.com/flutter/flutter/issues/36085
5536    @Deprecated('Use MouseRegion.onEnter instead')
5537    this.onPointerEnter, // ignore: deprecated_member_use_from_same_package
5538    @Deprecated('Use MouseRegion.onExit instead')
5539    this.onPointerExit, // ignore: deprecated_member_use_from_same_package
5540    @Deprecated('Use MouseRegion.onHover instead')
5541    this.onPointerHover, // ignore: deprecated_member_use_from_same_package
5542    this.onPointerUp,
5543    this.onPointerCancel,
5544    this.onPointerSignal,
5545    this.behavior = HitTestBehavior.deferToChild,
5546    Widget child,
5547  }) : assert(behavior != null),
5548       _child = child,
5549       super(key: key);
5550
5551  /// Called when a pointer comes into contact with the screen (for touch
5552  /// pointers), or has its button pressed (for mouse pointers) at this widget's
5553  /// location.
5554  final PointerDownEventListener onPointerDown;
5555
5556  /// Called when a pointer that triggered an [onPointerDown] changes position.
5557  final PointerMoveEventListener onPointerMove;
5558
5559  /// Called when a pointer enters the region for this widget.
5560  ///
5561  /// This is only fired for pointers which report their location when not down
5562  /// (e.g. mouse pointers, but not most touch pointers).
5563  ///
5564  /// If this is a mouse pointer, this will fire when the mouse pointer enters
5565  /// the region defined by this widget, or when the widget appears under the
5566  /// pointer.
5567  final PointerEnterEventListener onPointerEnter;
5568
5569  /// Called when a pointer that has not triggered an [onPointerDown] changes
5570  /// position.
5571  ///
5572  /// This is only fired for pointers which report their location when not down
5573  /// (e.g. mouse pointers, but not most touch pointers).
5574  final PointerHoverEventListener onPointerHover;
5575
5576  /// Called when a pointer leaves the region for this widget.
5577  ///
5578  /// This is only fired for pointers which report their location when not down
5579  /// (e.g. mouse pointers, but not most touch pointers).
5580  ///
5581  /// If this is a mouse pointer, this will fire when the mouse pointer leaves
5582  /// the region defined by this widget, or when the widget disappears from
5583  /// under the pointer.
5584  final PointerExitEventListener onPointerExit;
5585
5586  /// Called when a pointer that triggered an [onPointerDown] is no longer in
5587  /// contact with the screen.
5588  final PointerUpEventListener onPointerUp;
5589
5590  /// Called when the input from a pointer that triggered an [onPointerDown] is
5591  /// no longer directed towards this receiver.
5592  final PointerCancelEventListener onPointerCancel;
5593
5594  /// Called when a pointer signal occurs over this object.
5595  final PointerSignalEventListener onPointerSignal;
5596
5597  /// How to behave during hit testing.
5598  final HitTestBehavior behavior;
5599
5600  // The widget listened to by the listener.
5601  //
5602  // The reason why we don't expose it is that once the deprecated methods are
5603  // removed, Listener will no longer need to store the child, but will pass
5604  // the child to `super` instead.
5605  final Widget _child;
5606
5607  @override
5608  Widget build(BuildContext context) {
5609    Widget result = _child;
5610    if (onPointerEnter != null ||
5611        onPointerExit != null ||
5612        onPointerHover != null) {
5613      result = MouseRegion(
5614        onEnter: onPointerEnter,
5615        onExit: onPointerExit,
5616        onHover: onPointerHover,
5617        child: result,
5618      );
5619    }
5620    result = _PointerListener(
5621      onPointerDown: onPointerDown,
5622      onPointerUp: onPointerUp,
5623      onPointerMove: onPointerMove,
5624      onPointerCancel: onPointerCancel,
5625      onPointerSignal: onPointerSignal,
5626      behavior: behavior,
5627      child: result,
5628    );
5629    return result;
5630  }
5631}
5632
5633class _PointerListener extends SingleChildRenderObjectWidget {
5634  const _PointerListener({
5635    Key key,
5636    this.onPointerDown,
5637    this.onPointerMove,
5638    this.onPointerUp,
5639    this.onPointerCancel,
5640    this.onPointerSignal,
5641    this.behavior = HitTestBehavior.deferToChild,
5642    Widget child,
5643  }) : assert(behavior != null),
5644       super(key: key, child: child);
5645
5646  final PointerDownEventListener onPointerDown;
5647  final PointerMoveEventListener onPointerMove;
5648  final PointerUpEventListener onPointerUp;
5649  final PointerCancelEventListener onPointerCancel;
5650  final PointerSignalEventListener onPointerSignal;
5651  final HitTestBehavior behavior;
5652
5653  @override
5654  RenderPointerListener createRenderObject(BuildContext context) {
5655    return RenderPointerListener(
5656      onPointerDown: onPointerDown,
5657      onPointerMove: onPointerMove,
5658      onPointerUp: onPointerUp,
5659      onPointerCancel: onPointerCancel,
5660      onPointerSignal: onPointerSignal,
5661      behavior: behavior,
5662    );
5663  }
5664
5665  @override
5666  void updateRenderObject(BuildContext context, RenderPointerListener renderObject) {
5667    renderObject
5668      ..onPointerDown = onPointerDown
5669      ..onPointerMove = onPointerMove
5670      ..onPointerUp = onPointerUp
5671      ..onPointerCancel = onPointerCancel
5672      ..onPointerSignal = onPointerSignal
5673      ..behavior = behavior;
5674  }
5675
5676  @override
5677  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
5678    super.debugFillProperties(properties);
5679    final List<String> listeners = <String>[];
5680    if (onPointerDown != null)
5681      listeners.add('down');
5682    if (onPointerMove != null)
5683      listeners.add('move');
5684    if (onPointerUp != null)
5685      listeners.add('up');
5686    if (onPointerCancel != null)
5687      listeners.add('cancel');
5688    if (onPointerSignal != null)
5689      listeners.add('signal');
5690    properties.add(IterableProperty<String>('listeners', listeners, ifEmpty: '<none>'));
5691    properties.add(EnumProperty<HitTestBehavior>('behavior', behavior));
5692  }
5693}
5694
5695/// A widget that tracks the movement of mice, even when no button is pressed.
5696///
5697/// It does not listen to events that can construct gestures, such as when the
5698/// pointer is pressed, moved, then released or canceled. For these events,
5699/// use [Listener], or more preferably, [GestureDetector].
5700///
5701/// ## Layout behavior
5702///
5703/// _See [BoxConstraints] for an introduction to box layout models._
5704///
5705/// If it has a child, this widget defers to the child for sizing behavior. If
5706/// it does not have a child, it grows to fit the parent instead.
5707///
5708/// {@tool snippet --template=stateful_widget_scaffold}
5709/// This example makes a [Container] react to being entered by a mouse
5710/// pointer, showing a count of the number of entries and exits.
5711///
5712/// ```dart imports
5713/// import 'package:flutter/widgets.dart';
5714/// ```
5715///
5716/// ```dart
5717/// int _enterCounter = 0;
5718/// int _exitCounter = 0;
5719/// double x = 0.0;
5720/// double y = 0.0;
5721///
5722/// void _incrementEnter(PointerEvent details) {
5723///   setState(() {
5724///     _enterCounter++;
5725///   });
5726/// }
5727/// void _incrementExit(PointerEvent details) {
5728///   setState(() {
5729///     _exitCounter++;
5730///   });
5731/// }
5732/// void _updateLocation(PointerEvent details) {
5733///   setState(() {
5734///     x = details.position.dx;
5735///     y = details.position.dy;
5736///   });
5737/// }
5738///
5739/// @override
5740/// Widget build(BuildContext context) {
5741///   return Center(
5742///     child: ConstrainedBox(
5743///       constraints: new BoxConstraints.tight(Size(300.0, 200.0)),
5744///       child: MouseRegion(
5745///         onEnter: _incrementEnter,
5746///         onHover: _updateLocation,
5747///         onExit: _incrementExit,
5748///         child: Container(
5749///           color: Colors.lightBlueAccent,
5750///           child: Column(
5751///             mainAxisAlignment: MainAxisAlignment.center,
5752///             children: <Widget>[
5753///               Text('You have entered or exited this box this many times:'),
5754///               Text(
5755///                 '$_enterCounter Entries\n$_exitCounter Exits',
5756///                 style: Theme.of(context).textTheme.display1,
5757///               ),
5758///               Text(
5759///                 'The cursor is here: (${x.toStringAsFixed(2)}, ${y.toStringAsFixed(2)})',
5760///               ),
5761///             ],
5762///           ),
5763///         ),
5764///       ),
5765///     ),
5766///   );
5767/// }
5768/// ```
5769/// {@end-tool}
5770///
5771/// See also:
5772///
5773///  * [Listener], a similar widget that tracks pointer events when the pointer
5774///    have buttons pressed.
5775class MouseRegion extends SingleChildRenderObjectWidget {
5776  /// Creates a widget that forwards mouse events to callbacks.
5777  const MouseRegion({
5778    Key key,
5779    this.onEnter,
5780    this.onExit,
5781    this.onHover,
5782    Widget child,
5783  }) : super(key: key, child: child);
5784
5785  /// Called when a mouse pointer (with or without buttons pressed) enters the
5786  /// region defined by this widget, or when the widget appears under the
5787  /// pointer.
5788  final PointerEnterEventListener onEnter;
5789
5790  /// Called when a mouse pointer (with or without buttons pressed) changes
5791  /// position, and the new position is within the region defined by this widget.
5792  final PointerHoverEventListener onHover;
5793
5794  /// Called when a mouse pointer (with or without buttons pressed) leaves the
5795  /// region defined by this widget, or when the widget disappears from under
5796  /// the pointer.
5797  final PointerExitEventListener onExit;
5798
5799  @override
5800  _ListenerElement createElement() => _ListenerElement(this);
5801
5802  @override
5803  RenderMouseRegion createRenderObject(BuildContext context) {
5804    return RenderMouseRegion(
5805      onEnter: onEnter,
5806      onHover: onHover,
5807      onExit: onExit,
5808    );
5809  }
5810
5811  @override
5812  void updateRenderObject(BuildContext context, RenderMouseRegion renderObject) {
5813    renderObject
5814      ..onEnter = onEnter
5815      ..onHover = onHover
5816      ..onExit = onExit;
5817  }
5818
5819  @override
5820  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
5821    super.debugFillProperties(properties);
5822    final List<String> listeners = <String>[];
5823    if (onEnter != null)
5824      listeners.add('enter');
5825    if (onExit != null)
5826      listeners.add('exit');
5827    if (onHover != null)
5828      listeners.add('hover');
5829    properties.add(IterableProperty<String>('listeners', listeners, ifEmpty: '<none>'));
5830  }
5831}
5832
5833class _ListenerElement extends SingleChildRenderObjectElement {
5834  _ListenerElement(SingleChildRenderObjectWidget widget) : super(widget);
5835
5836  @override
5837  void activate() {
5838    super.activate();
5839    final RenderMouseRegion renderMouseListener = renderObject;
5840    renderMouseListener.postActivate();
5841  }
5842
5843  @override
5844  void deactivate() {
5845    final RenderMouseRegion renderMouseListener = renderObject;
5846    renderMouseListener.preDeactivate();
5847    super.deactivate();
5848  }
5849}
5850
5851/// A widget that creates a separate display list for its child.
5852///
5853/// This widget creates a separate display list for its child, which
5854/// can improve performance if the subtree repaints at different times than
5855/// the surrounding parts of the tree.
5856///
5857/// This is useful since [RenderObject.paint] may be triggered even if its
5858/// associated [Widget] instances did not change or rebuild. A [RenderObject]
5859/// will repaint whenever any [RenderObject] that shares the same [Layer] is
5860/// marked as being dirty and needing paint (see [RenderObject.markNeedsPaint]),
5861/// such as when an ancestor scrolls or when an ancestor or descendant animates.
5862///
5863/// Containing [RenderObject.paint] to parts of the render subtree that are
5864/// actually visually changing using [RepaintBoundary] explicitly or implicitly
5865/// is therefore critical to minimizing redundant work and improving the app's
5866/// performance.
5867///
5868/// When a [RenderObject] is flagged as needing to paint via
5869/// [RenderObject.markNeedsPaint], the nearest ancestor [RenderObject] with
5870/// [RenderObject.isRepaintBoundary], up to possibly the root of the application,
5871/// is requested to repaint. That nearest ancestor's [RenderObject.paint] method
5872/// will cause _all_ of its descendant [RenderObject]s to repaint in the same
5873/// layer.
5874///
5875/// [RepaintBoundary] is therefore used, both while propagating the
5876/// `markNeedsPaint` flag up the render tree and while traversing down the
5877/// render tree via [RenderObject.paintChild], to strategically contain repaints
5878/// to the render subtree that visually changed for performance. This is done
5879/// because the [RepaintBoundary] widget creates a [RenderObject] that always
5880/// has a [Layer], decoupling ancestor render objects from the descendant
5881/// render objects.
5882///
5883/// [RepaintBoundary] has the further side-effect of possibly hinting to the
5884/// engine that it should further optimize animation performance if the render
5885/// subtree behind the [RepaintBoundary] is sufficiently complex and is static
5886/// while the surrounding tree changes frequently. In those cases, the engine
5887/// may choose to pay a one time cost of rasterizing and caching the pixel
5888/// values of the subtree for faster future GPU re-rendering speed.
5889///
5890/// Several framework widgets insert [RepaintBoundary] widgets to mark natural
5891/// separation points in applications. For instance, contents in Material Design
5892/// drawers typically don't change while the drawer opens and closes, so
5893/// repaints are automatically contained to regions inside or outside the drawer
5894/// when using the [Drawer] widget during transitions.
5895///
5896/// See also:
5897///
5898///  * [debugRepaintRainbowEnabled], a debugging flag to help visually monitor
5899///    render tree repaints in a running app.
5900///  * [debugProfilePaintsEnabled], a debugging flag to show render tree
5901///    repaints in the observatory's timeline view.
5902class RepaintBoundary extends SingleChildRenderObjectWidget {
5903  /// Creates a widget that isolates repaints.
5904  const RepaintBoundary({ Key key, Widget child }) : super(key: key, child: child);
5905
5906  /// Wraps the given child in a [RepaintBoundary].
5907  ///
5908  /// The key for the [RepaintBoundary] is derived either from the child's key
5909  /// (if the child has a non-null key) or from the given `childIndex`.
5910  factory RepaintBoundary.wrap(Widget child, int childIndex) {
5911    assert(child != null);
5912    final Key key = child.key != null ? ValueKey<Key>(child.key) : ValueKey<int>(childIndex);
5913    return RepaintBoundary(key: key, child: child);
5914  }
5915
5916  /// Wraps each of the given children in [RepaintBoundary]s.
5917  ///
5918  /// The key for each [RepaintBoundary] is derived either from the wrapped
5919  /// child's key (if the wrapped child has a non-null key) or from the wrapped
5920  /// child's index in the list.
5921  static List<RepaintBoundary> wrapAll(List<Widget> widgets) {
5922    final List<RepaintBoundary> result = List<RepaintBoundary>(widgets.length);
5923    for (int i = 0; i < result.length; ++i)
5924      result[i] = RepaintBoundary.wrap(widgets[i], i);
5925    return result;
5926  }
5927
5928  @override
5929  RenderRepaintBoundary createRenderObject(BuildContext context) => RenderRepaintBoundary();
5930}
5931
5932/// A widget that is invisible during hit testing.
5933///
5934/// When [ignoring] is true, this widget (and its subtree) is invisible
5935/// to hit testing. It still consumes space during layout and paints its child
5936/// as usual. It just cannot be the target of located events, because it returns
5937/// false from [RenderBox.hitTest].
5938///
5939/// When [ignoringSemantics] is true, the subtree will be invisible to
5940/// the semantics layer (and thus e.g. accessibility tools). If
5941/// [ignoringSemantics] is null, it uses the value of [ignoring].
5942///
5943/// See also:
5944///
5945///  * [AbsorbPointer], which also prevents its children from receiving pointer
5946///    events but is itself visible to hit testing.
5947class IgnorePointer extends SingleChildRenderObjectWidget {
5948  /// Creates a widget that is invisible to hit testing.
5949  ///
5950  /// The [ignoring] argument must not be null. If [ignoringSemantics], this
5951  /// render object will be ignored for semantics if [ignoring] is true.
5952  const IgnorePointer({
5953    Key key,
5954    this.ignoring = true,
5955    this.ignoringSemantics,
5956    Widget child,
5957  }) : assert(ignoring != null),
5958       super(key: key, child: child);
5959
5960  /// Whether this widget is ignored during hit testing.
5961  ///
5962  /// Regardless of whether this widget is ignored during hit testing, it will
5963  /// still consume space during layout and be visible during painting.
5964  final bool ignoring;
5965
5966  /// Whether the semantics of this widget is ignored when compiling the semantics tree.
5967  ///
5968  /// If null, defaults to value of [ignoring].
5969  ///
5970  /// See [SemanticsNode] for additional information about the semantics tree.
5971  final bool ignoringSemantics;
5972
5973  @override
5974  RenderIgnorePointer createRenderObject(BuildContext context) {
5975    return RenderIgnorePointer(
5976      ignoring: ignoring,
5977      ignoringSemantics: ignoringSemantics,
5978    );
5979  }
5980
5981  @override
5982  void updateRenderObject(BuildContext context, RenderIgnorePointer renderObject) {
5983    renderObject
5984      ..ignoring = ignoring
5985      ..ignoringSemantics = ignoringSemantics;
5986  }
5987
5988  @override
5989  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
5990    super.debugFillProperties(properties);
5991    properties.add(DiagnosticsProperty<bool>('ignoring', ignoring));
5992    properties.add(DiagnosticsProperty<bool>('ignoringSemantics', ignoringSemantics, defaultValue: null));
5993  }
5994}
5995
5996/// A widget that absorbs pointers during hit testing.
5997///
5998/// When [absorbing] is true, this widget prevents its subtree from receiving
5999/// pointer events by terminating hit testing at itself. It still consumes space
6000/// during layout and paints its child as usual. It just prevents its children
6001/// from being the target of located events, because it returns true from
6002/// [RenderBox.hitTest].
6003///
6004/// {@youtube 560 315 https://www.youtube.com/watch?v=65HoWqBboI8}
6005///
6006/// See also:
6007///
6008///  * [IgnorePointer], which also prevents its children from receiving pointer
6009///    events but is itself invisible to hit testing.
6010class AbsorbPointer extends SingleChildRenderObjectWidget {
6011  /// Creates a widget that absorbs pointers during hit testing.
6012  ///
6013  /// The [absorbing] argument must not be null
6014  const AbsorbPointer({
6015    Key key,
6016    this.absorbing = true,
6017    Widget child,
6018    this.ignoringSemantics,
6019  }) : assert(absorbing != null),
6020       super(key: key, child: child);
6021
6022  /// Whether this widget absorbs pointers during hit testing.
6023  ///
6024  /// Regardless of whether this render object absorbs pointers during hit
6025  /// testing, it will still consume space during layout and be visible during
6026  /// painting.
6027  final bool absorbing;
6028
6029  /// Whether the semantics of this render object is ignored when compiling the
6030  /// semantics tree.
6031  ///
6032  /// If null, defaults to the value of [absorbing].
6033  ///
6034  /// See [SemanticsNode] for additional information about the semantics tree.
6035  final bool ignoringSemantics;
6036
6037  @override
6038  RenderAbsorbPointer createRenderObject(BuildContext context) {
6039    return RenderAbsorbPointer(
6040      absorbing: absorbing,
6041      ignoringSemantics: ignoringSemantics,
6042    );
6043  }
6044
6045  @override
6046  void updateRenderObject(BuildContext context, RenderAbsorbPointer renderObject) {
6047    renderObject
6048      ..absorbing = absorbing
6049      ..ignoringSemantics = ignoringSemantics;
6050  }
6051
6052  @override
6053  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
6054    super.debugFillProperties(properties);
6055    properties.add(DiagnosticsProperty<bool>('absorbing', absorbing));
6056    properties.add(DiagnosticsProperty<bool>('ignoringSemantics', ignoringSemantics, defaultValue: null));
6057  }
6058}
6059
6060/// Holds opaque meta data in the render tree.
6061///
6062/// Useful for decorating the render tree with information that will be consumed
6063/// later. For example, you could store information in the render tree that will
6064/// be used when the user interacts with the render tree but has no visual
6065/// impact prior to the interaction.
6066class MetaData extends SingleChildRenderObjectWidget {
6067  /// Creates a widget that hold opaque meta data.
6068  ///
6069  /// The [behavior] argument defaults to [HitTestBehavior.deferToChild].
6070  const MetaData({
6071    Key key,
6072    this.metaData,
6073    this.behavior = HitTestBehavior.deferToChild,
6074    Widget child,
6075  }) : super(key: key, child: child);
6076
6077  /// Opaque meta data ignored by the render tree
6078  final dynamic metaData;
6079
6080  /// How to behave during hit testing.
6081  final HitTestBehavior behavior;
6082
6083  @override
6084  RenderMetaData createRenderObject(BuildContext context) {
6085    return RenderMetaData(
6086      metaData: metaData,
6087      behavior: behavior,
6088    );
6089  }
6090
6091  @override
6092  void updateRenderObject(BuildContext context, RenderMetaData renderObject) {
6093    renderObject
6094      ..metaData = metaData
6095      ..behavior = behavior;
6096  }
6097
6098  @override
6099  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
6100    super.debugFillProperties(properties);
6101    properties.add(EnumProperty<HitTestBehavior>('behavior', behavior));
6102    properties.add(DiagnosticsProperty<dynamic>('metaData', metaData));
6103  }
6104}
6105
6106
6107// UTILITY NODES
6108
6109/// A widget that annotates the widget tree with a description of the meaning of
6110/// the widgets.
6111///
6112/// Used by accessibility tools, search engines, and other semantic analysis
6113/// software to determine the meaning of the application.
6114///
6115/// See also:
6116///
6117///  * [MergeSemantics], which marks a subtree as being a single node for
6118///    accessibility purposes.
6119///  * [ExcludeSemantics], which excludes a subtree from the semantics tree
6120///    (which might be useful if it is, e.g., totally decorative and not
6121///    important to the user).
6122///  * [RenderObject.semanticsAnnotator], the rendering library API through which
6123///    the [Semantics] widget is actually implemented.
6124///  * [SemanticsNode], the object used by the rendering library to represent
6125///    semantics in the semantics tree.
6126///  * [SemanticsDebugger], an overlay to help visualize the semantics tree. Can
6127///    be enabled using [WidgetsApp.showSemanticsDebugger] or
6128///    [MaterialApp.showSemanticsDebugger].
6129@immutable
6130class Semantics extends SingleChildRenderObjectWidget {
6131  /// Creates a semantic annotation.
6132  ///
6133  /// The [container] argument must not be null. To create a `const` instance
6134  /// of [Semantics], use the [Semantics.fromProperties] constructor.
6135  ///
6136  /// See also:
6137  ///
6138  ///  * [SemanticsSortKey] for a class that determines accessibility traversal
6139  ///    order.
6140  Semantics({
6141    Key key,
6142    Widget child,
6143    bool container = false,
6144    bool explicitChildNodes = false,
6145    bool excludeSemantics = false,
6146    bool enabled,
6147    bool checked,
6148    bool selected,
6149    bool toggled,
6150    bool button,
6151    bool header,
6152    bool textField,
6153    bool readOnly,
6154    bool focused,
6155    bool inMutuallyExclusiveGroup,
6156    bool obscured,
6157    bool multiline,
6158    bool scopesRoute,
6159    bool namesRoute,
6160    bool hidden,
6161    bool image,
6162    bool liveRegion,
6163    String label,
6164    String value,
6165    String increasedValue,
6166    String decreasedValue,
6167    String hint,
6168    String onTapHint,
6169    String onLongPressHint,
6170    TextDirection textDirection,
6171    SemanticsSortKey sortKey,
6172    VoidCallback onTap,
6173    VoidCallback onLongPress,
6174    VoidCallback onScrollLeft,
6175    VoidCallback onScrollRight,
6176    VoidCallback onScrollUp,
6177    VoidCallback onScrollDown,
6178    VoidCallback onIncrease,
6179    VoidCallback onDecrease,
6180    VoidCallback onCopy,
6181    VoidCallback onCut,
6182    VoidCallback onPaste,
6183    VoidCallback onDismiss,
6184    MoveCursorHandler onMoveCursorForwardByCharacter,
6185    MoveCursorHandler onMoveCursorBackwardByCharacter,
6186    SetSelectionHandler onSetSelection,
6187    VoidCallback onDidGainAccessibilityFocus,
6188    VoidCallback onDidLoseAccessibilityFocus,
6189    Map<CustomSemanticsAction, VoidCallback> customSemanticsActions,
6190  }) : this.fromProperties(
6191    key: key,
6192    child: child,
6193    container: container,
6194    explicitChildNodes: explicitChildNodes,
6195    excludeSemantics: excludeSemantics,
6196    properties: SemanticsProperties(
6197      enabled: enabled,
6198      checked: checked,
6199      toggled: toggled,
6200      selected: selected,
6201      button: button,
6202      header: header,
6203      textField: textField,
6204      readOnly: readOnly,
6205      focused: focused,
6206      inMutuallyExclusiveGroup: inMutuallyExclusiveGroup,
6207      obscured: obscured,
6208      multiline: multiline,
6209      scopesRoute: scopesRoute,
6210      namesRoute: namesRoute,
6211      hidden: hidden,
6212      image: image,
6213      liveRegion: liveRegion,
6214      label: label,
6215      value: value,
6216      increasedValue: increasedValue,
6217      decreasedValue: decreasedValue,
6218      hint: hint,
6219      textDirection: textDirection,
6220      sortKey: sortKey,
6221      onTap: onTap,
6222      onLongPress: onLongPress,
6223      onScrollLeft: onScrollLeft,
6224      onScrollRight: onScrollRight,
6225      onScrollUp: onScrollUp,
6226      onScrollDown: onScrollDown,
6227      onIncrease: onIncrease,
6228      onDecrease: onDecrease,
6229      onCopy: onCopy,
6230      onCut: onCut,
6231      onPaste: onPaste,
6232      onMoveCursorForwardByCharacter: onMoveCursorForwardByCharacter,
6233      onMoveCursorBackwardByCharacter: onMoveCursorBackwardByCharacter,
6234      onDidGainAccessibilityFocus: onDidGainAccessibilityFocus,
6235      onDidLoseAccessibilityFocus: onDidLoseAccessibilityFocus,
6236      onDismiss: onDismiss,
6237      onSetSelection: onSetSelection,
6238      customSemanticsActions: customSemanticsActions,
6239      hintOverrides: onTapHint != null || onLongPressHint != null ?
6240        SemanticsHintOverrides(
6241          onTapHint: onTapHint,
6242          onLongPressHint: onLongPressHint,
6243        ) : null,
6244    ),
6245  );
6246
6247  /// Creates a semantic annotation using [SemanticsProperties].
6248  ///
6249  /// The [container] and [properties] arguments must not be null.
6250  const Semantics.fromProperties({
6251    Key key,
6252    Widget child,
6253    this.container = false,
6254    this.explicitChildNodes = false,
6255    this.excludeSemantics = false,
6256    @required this.properties,
6257  }) : assert(container != null),
6258       assert(properties != null),
6259       super(key: key, child: child);
6260
6261  /// Contains properties used by assistive technologies to make the application
6262  /// more accessible.
6263  final SemanticsProperties properties;
6264
6265  /// If [container] is true, this widget will introduce a new
6266  /// node in the semantics tree. Otherwise, the semantics will be
6267  /// merged with the semantics of any ancestors (if the ancestor allows that).
6268  ///
6269  /// Whether descendants of this widget can add their semantic information to the
6270  /// [SemanticsNode] introduced by this configuration is controlled by
6271  /// [explicitChildNodes].
6272  final bool container;
6273
6274  /// Whether descendants of this widget are allowed to add semantic information
6275  /// to the [SemanticsNode] annotated by this widget.
6276  ///
6277  /// When set to false descendants are allowed to annotate [SemanticNode]s of
6278  /// their parent with the semantic information they want to contribute to the
6279  /// semantic tree.
6280  /// When set to true the only way for descendants to contribute semantic
6281  /// information to the semantic tree is to introduce new explicit
6282  /// [SemanticNode]s to the tree.
6283  ///
6284  /// If the semantics properties of this node include
6285  /// [SemanticsProperties.scopesRoute] set to true, then [explicitChildNodes]
6286  /// must be true also.
6287  ///
6288  /// This setting is often used in combination with [SemanticsConfiguration.isSemanticBoundary]
6289  /// to create semantic boundaries that are either writable or not for children.
6290  final bool explicitChildNodes;
6291
6292  /// Whether to replace all child semantics with this node.
6293  ///
6294  /// Defaults to false.
6295  ///
6296  /// When this flag is set to true, all child semantics nodes are ignored.
6297  /// This can be used as a convenience for cases where a child is wrapped in
6298  /// an [ExcludeSemantics] widget and then another [Semantics] widget.
6299  final bool excludeSemantics;
6300
6301  @override
6302  RenderSemanticsAnnotations createRenderObject(BuildContext context) {
6303    return RenderSemanticsAnnotations(
6304      container: container,
6305      explicitChildNodes: explicitChildNodes,
6306      excludeSemantics: excludeSemantics,
6307      enabled: properties.enabled,
6308      checked: properties.checked,
6309      toggled: properties.toggled,
6310      selected: properties.selected,
6311      button: properties.button,
6312      header: properties.header,
6313      textField: properties.textField,
6314      readOnly: properties.readOnly,
6315      focused: properties.focused,
6316      liveRegion: properties.liveRegion,
6317      inMutuallyExclusiveGroup: properties.inMutuallyExclusiveGroup,
6318      obscured: properties.obscured,
6319      multiline: properties.multiline,
6320      scopesRoute: properties.scopesRoute,
6321      namesRoute: properties.namesRoute,
6322      hidden: properties.hidden,
6323      image: properties.image,
6324      label: properties.label,
6325      value: properties.value,
6326      increasedValue: properties.increasedValue,
6327      decreasedValue: properties.decreasedValue,
6328      hint: properties.hint,
6329      hintOverrides: properties.hintOverrides,
6330      textDirection: _getTextDirection(context),
6331      sortKey: properties.sortKey,
6332      onTap: properties.onTap,
6333      onLongPress: properties.onLongPress,
6334      onScrollLeft: properties.onScrollLeft,
6335      onScrollRight: properties.onScrollRight,
6336      onScrollUp: properties.onScrollUp,
6337      onScrollDown: properties.onScrollDown,
6338      onIncrease: properties.onIncrease,
6339      onDecrease: properties.onDecrease,
6340      onCopy: properties.onCopy,
6341      onDismiss: properties.onDismiss,
6342      onCut: properties.onCut,
6343      onPaste: properties.onPaste,
6344      onMoveCursorForwardByCharacter: properties.onMoveCursorForwardByCharacter,
6345      onMoveCursorBackwardByCharacter: properties.onMoveCursorBackwardByCharacter,
6346      onMoveCursorForwardByWord: properties.onMoveCursorForwardByWord,
6347      onMoveCursorBackwardByWord: properties.onMoveCursorBackwardByWord,
6348      onSetSelection: properties.onSetSelection,
6349      onDidGainAccessibilityFocus: properties.onDidGainAccessibilityFocus,
6350      onDidLoseAccessibilityFocus: properties.onDidLoseAccessibilityFocus,
6351      customSemanticsActions: properties.customSemanticsActions,
6352    );
6353  }
6354
6355  TextDirection _getTextDirection(BuildContext context) {
6356    if (properties.textDirection != null)
6357      return properties.textDirection;
6358
6359    final bool containsText = properties.label != null || properties.value != null || properties.hint != null;
6360
6361    if (!containsText)
6362      return null;
6363
6364    return Directionality.of(context);
6365  }
6366
6367  @override
6368  void updateRenderObject(BuildContext context, RenderSemanticsAnnotations renderObject) {
6369    renderObject
6370      ..container = container
6371      ..explicitChildNodes = explicitChildNodes
6372      ..excludeSemantics = excludeSemantics
6373      ..scopesRoute = properties.scopesRoute
6374      ..enabled = properties.enabled
6375      ..checked = properties.checked
6376      ..toggled = properties.toggled
6377      ..selected = properties.selected
6378      ..button = properties.button
6379      ..header = properties.header
6380      ..textField = properties.textField
6381      ..readOnly = properties.readOnly
6382      ..focused = properties.focused
6383      ..inMutuallyExclusiveGroup = properties.inMutuallyExclusiveGroup
6384      ..obscured = properties.obscured
6385      ..multiline = properties.multiline
6386      ..hidden = properties.hidden
6387      ..image = properties.image
6388      ..liveRegion = properties.liveRegion
6389      ..label = properties.label
6390      ..value = properties.value
6391      ..increasedValue = properties.increasedValue
6392      ..decreasedValue = properties.decreasedValue
6393      ..hint = properties.hint
6394      ..hintOverrides = properties.hintOverrides
6395      ..namesRoute = properties.namesRoute
6396      ..textDirection = _getTextDirection(context)
6397      ..sortKey = properties.sortKey
6398      ..onTap = properties.onTap
6399      ..onLongPress = properties.onLongPress
6400      ..onScrollLeft = properties.onScrollLeft
6401      ..onScrollRight = properties.onScrollRight
6402      ..onScrollUp = properties.onScrollUp
6403      ..onScrollDown = properties.onScrollDown
6404      ..onIncrease = properties.onIncrease
6405      ..onDismiss = properties.onDismiss
6406      ..onDecrease = properties.onDecrease
6407      ..onCopy = properties.onCopy
6408      ..onCut = properties.onCut
6409      ..onPaste = properties.onPaste
6410      ..onMoveCursorForwardByCharacter = properties.onMoveCursorForwardByCharacter
6411      ..onMoveCursorBackwardByCharacter = properties.onMoveCursorForwardByCharacter
6412      ..onMoveCursorForwardByWord = properties.onMoveCursorForwardByWord
6413      ..onMoveCursorBackwardByWord = properties.onMoveCursorBackwardByWord
6414      ..onSetSelection = properties.onSetSelection
6415      ..onDidGainAccessibilityFocus = properties.onDidGainAccessibilityFocus
6416      ..onDidLoseAccessibilityFocus = properties.onDidLoseAccessibilityFocus
6417      ..customSemanticsActions = properties.customSemanticsActions;
6418  }
6419
6420  @override
6421  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
6422    super.debugFillProperties(properties);
6423    properties.add(DiagnosticsProperty<bool>('container', container));
6424    properties.add(DiagnosticsProperty<SemanticsProperties>('properties', this.properties));
6425    this.properties.debugFillProperties(properties);
6426  }
6427}
6428
6429/// A widget that merges the semantics of its descendants.
6430///
6431/// Causes all the semantics of the subtree rooted at this node to be
6432/// merged into one node in the semantics tree. For example, if you
6433/// have a widget with a Text node next to a checkbox widget, this
6434/// could be used to merge the label from the Text node with the
6435/// "checked" semantic state of the checkbox into a single node that
6436/// had both the label and the checked state. Otherwise, the label
6437/// would be presented as a separate feature than the checkbox, and
6438/// the user would not be able to be sure that they were related.
6439///
6440/// Be aware that if two nodes in the subtree have conflicting
6441/// semantics, the result may be nonsensical. For example, a subtree
6442/// with a checked checkbox and an unchecked checkbox will be
6443/// presented as checked. All the labels will be merged into a single
6444/// string (with newlines separating each label from the other). If
6445/// multiple nodes in the merged subtree can handle semantic gestures,
6446/// the first one in tree order will be the one to receive the
6447/// callbacks.
6448class MergeSemantics extends SingleChildRenderObjectWidget {
6449  /// Creates a widget that merges the semantics of its descendants.
6450  const MergeSemantics({ Key key, Widget child }) : super(key: key, child: child);
6451
6452  @override
6453  RenderMergeSemantics createRenderObject(BuildContext context) => RenderMergeSemantics();
6454}
6455
6456/// A widget that drops the semantics of all widget that were painted before it
6457/// in the same semantic container.
6458///
6459/// This is useful to hide widgets from accessibility tools that are painted
6460/// behind a certain widget, e.g. an alert should usually disallow interaction
6461/// with any widget located "behind" the alert (even when they are still
6462/// partially visible). Similarly, an open [Drawer] blocks interactions with
6463/// any widget outside the drawer.
6464///
6465/// See also:
6466///
6467///  * [ExcludeSemantics] which drops all semantics of its descendants.
6468class BlockSemantics extends SingleChildRenderObjectWidget {
6469  /// Creates a widget that excludes the semantics of all widgets painted before
6470  /// it in the same semantic container.
6471  const BlockSemantics({ Key key, this.blocking = true, Widget child }) : super(key: key, child: child);
6472
6473  /// Whether this widget is blocking semantics of all widget that were painted
6474  /// before it in the same semantic container.
6475  final bool blocking;
6476
6477  @override
6478  RenderBlockSemantics createRenderObject(BuildContext context) => RenderBlockSemantics(blocking: blocking);
6479
6480  @override
6481  void updateRenderObject(BuildContext context, RenderBlockSemantics renderObject) {
6482    renderObject.blocking = blocking;
6483  }
6484
6485  @override
6486  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
6487    super.debugFillProperties(properties);
6488    properties.add(DiagnosticsProperty<bool>('blocking', blocking));
6489  }
6490}
6491
6492/// A widget that drops all the semantics of its descendants.
6493///
6494/// When [excluding] is true, this widget (and its subtree) is excluded from
6495/// the semantics tree.
6496///
6497/// This can be used to hide descendant widgets that would otherwise be
6498/// reported but that would only be confusing. For example, the
6499/// material library's [Chip] widget hides the avatar since it is
6500/// redundant with the chip label.
6501///
6502/// See also:
6503///
6504///  * [BlockSemantics] which drops semantics of widgets earlier in the tree.
6505class ExcludeSemantics extends SingleChildRenderObjectWidget {
6506  /// Creates a widget that drops all the semantics of its descendants.
6507  const ExcludeSemantics({
6508    Key key,
6509    this.excluding = true,
6510    Widget child,
6511  }) : assert(excluding != null),
6512       super(key: key, child: child);
6513
6514  /// Whether this widget is excluded in the semantics tree.
6515  final bool excluding;
6516
6517  @override
6518  RenderExcludeSemantics createRenderObject(BuildContext context) => RenderExcludeSemantics(excluding: excluding);
6519
6520  @override
6521  void updateRenderObject(BuildContext context, RenderExcludeSemantics renderObject) {
6522    renderObject.excluding = excluding;
6523  }
6524
6525  @override
6526  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
6527    super.debugFillProperties(properties);
6528    properties.add(DiagnosticsProperty<bool>('excluding', excluding));
6529  }
6530}
6531
6532/// A widget that annotates the child semantics with an index.
6533///
6534/// Semantic indexes are used by TalkBack/Voiceover to make announcements about
6535/// the current scroll state. Certain widgets like the [ListView] will
6536/// automatically provide a child index for building semantics. A user may wish
6537/// to manually provide semantic indexes if not all child of the scrollable
6538/// contribute semantics.
6539///
6540/// {@tool sample}
6541///
6542/// The example below handles spacers in a scrollable that don't contribute
6543/// semantics. The automatic indexes would give the spaces a semantic index,
6544/// causing scroll announcements to erroneously state that there are four items
6545/// visible.
6546///
6547/// ```dart
6548/// ListView(
6549///   addSemanticIndexes: false,
6550///   semanticChildCount: 2,
6551///   children: const <Widget>[
6552///     IndexedSemantics(index: 0, child: Text('First')),
6553///     Spacer(),
6554///     IndexedSemantics(index: 1, child: Text('Second')),
6555///     Spacer(),
6556///   ],
6557/// )
6558/// ```
6559/// {@end-tool}
6560///
6561/// See also:
6562///
6563///  * [CustomScrollView], for an explanation of index semantics.
6564class IndexedSemantics extends SingleChildRenderObjectWidget {
6565  /// Creates a widget that annotated the first child semantics node with an index.
6566  ///
6567  /// [index] must not be null.
6568  const IndexedSemantics({
6569    Key key,
6570    @required this.index,
6571    Widget child,
6572  }) : assert(index != null),
6573       super(key: key, child: child);
6574
6575  /// The index used to annotate the first child semantics node.
6576  final int index;
6577
6578  @override
6579  RenderIndexedSemantics createRenderObject(BuildContext context) => RenderIndexedSemantics(index: index);
6580
6581  @override
6582  void updateRenderObject(BuildContext context, RenderIndexedSemantics renderObject) {
6583    renderObject.index = index;
6584  }
6585  @override
6586  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
6587    super.debugFillProperties(properties);
6588    properties.add(DiagnosticsProperty<int>('index', index));
6589  }
6590}
6591
6592/// A widget that builds its child.
6593///
6594/// Useful for attaching a key to an existing widget.
6595class KeyedSubtree extends StatelessWidget {
6596  /// Creates a widget that builds its child.
6597  const KeyedSubtree({
6598    Key key,
6599    @required this.child,
6600  }) : assert(child != null),
6601       super(key: key);
6602
6603  /// Creates a KeyedSubtree for child with a key that's based on the child's existing key or childIndex.
6604  factory KeyedSubtree.wrap(Widget child, int childIndex) {
6605    final Key key = child.key != null ? ValueKey<Key>(child.key) : ValueKey<int>(childIndex);
6606    return KeyedSubtree(key: key, child: child);
6607  }
6608
6609  /// The widget below this widget in the tree.
6610  ///
6611  /// {@macro flutter.widgets.child}
6612  final Widget child;
6613
6614  /// Wrap each item in a KeyedSubtree whose key is based on the item's existing key or
6615  /// the sum of its list index and `baseIndex`.
6616  static List<Widget> ensureUniqueKeysForList(Iterable<Widget> items, { int baseIndex = 0 }) {
6617    if (items == null || items.isEmpty)
6618      return items;
6619
6620    final List<Widget> itemsWithUniqueKeys = <Widget>[];
6621    int itemIndex = baseIndex;
6622    for (Widget item in items) {
6623      itemsWithUniqueKeys.add(KeyedSubtree.wrap(item, itemIndex));
6624      itemIndex += 1;
6625    }
6626
6627    assert(!debugItemsHaveDuplicateKeys(itemsWithUniqueKeys));
6628    return itemsWithUniqueKeys;
6629  }
6630
6631  @override
6632  Widget build(BuildContext context) => child;
6633}
6634
6635/// A platonic widget that calls a closure to obtain its child widget.
6636///
6637/// See also:
6638///
6639///  * [StatefulBuilder], a platonic widget which also has state.
6640class Builder extends StatelessWidget {
6641  /// Creates a widget that delegates its build to a callback.
6642  ///
6643  /// The [builder] argument must not be null.
6644  const Builder({
6645    Key key,
6646    @required this.builder,
6647  }) : assert(builder != null),
6648       super(key: key);
6649
6650  /// Called to obtain the child widget.
6651  ///
6652  /// This function is called whenever this widget is included in its parent's
6653  /// build and the old widget (if any) that it synchronizes with has a distinct
6654  /// object identity. Typically the parent's build method will construct
6655  /// a new tree of widgets and so a new Builder child will not be [identical]
6656  /// to the corresponding old one.
6657  final WidgetBuilder builder;
6658
6659  @override
6660  Widget build(BuildContext context) => builder(context);
6661}
6662
6663/// Signature for the builder callback used by [StatefulBuilder].
6664///
6665/// Call [setState] to schedule the [StatefulBuilder] to rebuild.
6666typedef StatefulWidgetBuilder = Widget Function(BuildContext context, StateSetter setState);
6667
6668/// A platonic widget that both has state and calls a closure to obtain its child widget.
6669///
6670/// The [StateSetter] function passed to the [builder] is used to invoke a
6671/// rebuild instead of a typical [State]'s [State.setState].
6672///
6673/// Since the [builder] is re-invoked when the [StateSetter] is called, any
6674/// variables that represents state should be kept outside the [builder] function.
6675///
6676/// {@tool sample}
6677///
6678/// This example shows using an inline StatefulBuilder that rebuilds and that
6679/// also has state.
6680///
6681/// ```dart
6682/// await showDialog<void>(
6683///   context: context,
6684///   builder: (BuildContext context) {
6685///     int selectedRadio = 0;
6686///     return AlertDialog(
6687///       content: StatefulBuilder(
6688///         builder: (BuildContext context, StateSetter setState) {
6689///           return Column(
6690///             mainAxisSize: MainAxisSize.min,
6691///             children: List<Widget>.generate(4, (int index) {
6692///               return Radio<int>(
6693///                 value: index,
6694///                 groupValue: selectedRadio,
6695///                 onChanged: (int value) {
6696///                   setState(() => selectedRadio = value);
6697///                 },
6698///               );
6699///             }),
6700///           );
6701///         },
6702///       ),
6703///     );
6704///   },
6705/// );
6706/// ```
6707/// {@end-tool}
6708///
6709/// See also:
6710///
6711///  * [Builder], the platonic stateless widget.
6712class StatefulBuilder extends StatefulWidget {
6713  /// Creates a widget that both has state and delegates its build to a callback.
6714  ///
6715  /// The [builder] argument must not be null.
6716  const StatefulBuilder({
6717    Key key,
6718    @required this.builder,
6719  }) : assert(builder != null),
6720       super(key: key);
6721
6722  /// Called to obtain the child widget.
6723  ///
6724  /// This function is called whenever this widget is included in its parent's
6725  /// build and the old widget (if any) that it synchronizes with has a distinct
6726  /// object identity. Typically the parent's build method will construct
6727  /// a new tree of widgets and so a new Builder child will not be [identical]
6728  /// to the corresponding old one.
6729  final StatefulWidgetBuilder builder;
6730
6731  @override
6732  _StatefulBuilderState createState() => _StatefulBuilderState();
6733}
6734
6735class _StatefulBuilderState extends State<StatefulBuilder> {
6736  @override
6737  Widget build(BuildContext context) => widget.builder(context, setState);
6738}
6739