Skip to content

Commit f87c510

Browse files
authored
Add more documentation around layers. (flutter#45648)
1 parent 59ca523 commit f87c510

File tree

5 files changed

+137
-71
lines changed

5 files changed

+137
-71
lines changed

packages/flutter/lib/src/rendering/binding.dart

+5-5
Original file line numberDiff line numberDiff line change
@@ -182,11 +182,12 @@ mixin RendererBinding on BindingBase, ServicesBinding, SchedulerBinding, Gesture
182182
@protected
183183
void handleTextScaleFactorChanged() { }
184184

185-
/// {@template on_platform_brightness_change}
186185
/// Called when the platform brightness changes.
187186
///
188-
/// The current platform brightness can be queried either from a Flutter
189-
/// binding, or from a [MediaQuery] widget.
187+
/// The current platform brightness can be queried from a Flutter binding or
188+
/// from a [MediaQuery] widget. The latter is preferred from widgets because
189+
/// it causes the widget to be automatically rebuilt when the brightness
190+
/// changes.
190191
///
191192
/// {@tool sample}
192193
/// Querying [Window.platformBrightness].
@@ -197,7 +198,7 @@ mixin RendererBinding on BindingBase, ServicesBinding, SchedulerBinding, Gesture
197198
/// {@end-tool}
198199
///
199200
/// {@tool sample}
200-
/// Querying [MediaQuery] directly.
201+
/// Querying [MediaQuery] directly. Preferred.
201202
///
202203
/// ```dart
203204
/// final Brightness brightness = MediaQuery.platformBrightnessOf(context);
@@ -214,7 +215,6 @@ mixin RendererBinding on BindingBase, ServicesBinding, SchedulerBinding, Gesture
214215
/// {@end-tool}
215216
///
216217
/// See [Window.onPlatformBrightnessChanged].
217-
/// {@endtemplate}
218218
@protected
219219
void handlePlatformBrightnessChanged() { }
220220

packages/flutter/lib/src/rendering/layer.dart

+18-1
Original file line numberDiff line numberDiff line change
@@ -1673,6 +1673,11 @@ class OpacityLayer extends ContainerLayer {
16731673
}
16741674

16751675
/// A composited layer that applies a shader to its children.
1676+
///
1677+
/// The shader is only applied inside the given [maskRect]. The shader itself
1678+
/// uses the top left of the [maskRect] as its origin.
1679+
///
1680+
/// The [maskRect] does not affect the positions of any child layers.
16761681
class ShaderMaskLayer extends ContainerLayer {
16771682
/// Creates a shader mask layer.
16781683
///
@@ -1688,8 +1693,16 @@ class ShaderMaskLayer extends ContainerLayer {
16881693

16891694
/// The shader to apply to the children.
16901695
///
1696+
/// The origin of the shader (e.g. of the coordinate system used by the `from`
1697+
/// and `to` arguments to [ui.Gradient.linear]) is at the top left of the
1698+
/// [maskRect].
1699+
///
16911700
/// The scene must be explicitly recomposited after this property is changed
16921701
/// (as described at [Layer]).
1702+
///
1703+
/// See also:
1704+
///
1705+
/// * [ui.Gradient] and [ui.ImageShader], two shader types that can be used.
16931706
Shader get shader => _shader;
16941707
Shader _shader;
16951708
set shader(Shader value) {
@@ -1699,7 +1712,10 @@ class ShaderMaskLayer extends ContainerLayer {
16991712
}
17001713
}
17011714

1702-
/// The size of the shader.
1715+
/// The position and size of the shader.
1716+
///
1717+
/// The [shader] is only rendered inside this rectangle, using the top left of
1718+
/// the rectangle as its origin.
17031719
///
17041720
/// The scene must be explicitly recomposited after this property is changed
17051721
/// (as described at [Layer]).
@@ -1730,6 +1746,7 @@ class ShaderMaskLayer extends ContainerLayer {
17301746
assert(shader != null);
17311747
assert(maskRect != null);
17321748
assert(blendMode != null);
1749+
assert(layerOffset != null);
17331750
final Rect shiftedMaskRect = layerOffset == Offset.zero ? maskRect : maskRect.shift(layerOffset);
17341751
engineLayer = builder.pushShaderMask(shader, shiftedMaskRect, blendMode, oldLayer: _engineLayer);
17351752
addChildrenToScene(builder, layerOffset);

packages/flutter/lib/src/rendering/object.dart

+108-64
Original file line numberDiff line numberDiff line change
@@ -344,8 +344,8 @@ class PaintingContext extends ClipContext {
344344
///
345345
/// See also:
346346
///
347-
/// * [pushLayer], for adding a layer and using its canvas to paint with that
348-
/// layer.
347+
/// * [pushLayer], for adding a layer and painting further contents within
348+
/// it.
349349
void addLayer(Layer layer) {
350350
stopRecordingIfNeeded();
351351
appendLayer(layer);
@@ -360,17 +360,24 @@ class PaintingContext extends ClipContext {
360360
/// object, rather than reusing an existing layer, satisfies that
361361
/// requirement.)
362362
///
363-
/// The `offset` is the offset to pass to the `painter`.
363+
/// {@template flutter.rendering.object.pushLayer.offset}
364+
/// The `offset` is the offset to pass to the `painter`. In particular, it is
365+
/// not an offset applied to the layer itself. Layers conceptually by default
366+
/// have no position or size, though they can transform their contents. For
367+
/// example, an [OffsetLayer] applies an offset to its children.
368+
/// {@endtemplate}
364369
///
365370
/// If the `childPaintBounds` are not specified then the current layer's paint
366371
/// bounds are used. This is appropriate if the child layer does not apply any
367372
/// transformation or clipping to its contents. The `childPaintBounds`, if
368-
/// specified, must be in the coordinate system of the new layer, and should
369-
/// not go outside the current layer's paint bounds.
373+
/// specified, must be in the coordinate system of the new layer (i.e. as seen
374+
/// by its children after it applies whatever transform to its contents), and
375+
/// should not go outside the current layer's paint bounds.
370376
///
371377
/// See also:
372378
///
373-
/// * [addLayer], for pushing a leaf layer whose canvas is not used.
379+
/// * [addLayer], for pushing a layer without painting further contents
380+
/// within it.
374381
void pushLayer(ContainerLayer childLayer, PaintingContextCallback painter, Offset offset, { Rect childPaintBounds }) {
375382
assert(painter != null);
376383
// If a layer is being reused, it may already contain children. We remove
@@ -385,7 +392,9 @@ class PaintingContext extends ClipContext {
385392
childContext.stopRecordingIfNeeded();
386393
}
387394

388-
/// Creates a compatible painting context to paint onto [childLayer].
395+
/// Creates a painting context configured to paint into [childLayer].
396+
///
397+
/// The `bounds` are estimated paint bounds for debugging purposes.
389398
@protected
390399
PaintingContext createChildContext(ContainerLayer childLayer, Rect bounds) {
391400
return PaintingContext(childLayer, bounds);
@@ -394,28 +403,40 @@ class PaintingContext extends ClipContext {
394403
/// Clip further painting using a rectangle.
395404
///
396405
/// {@template flutter.rendering.object.needsCompositing}
397-
/// * `needsCompositing` is whether the child needs compositing. Typically
398-
/// matches the value of [RenderObject.needsCompositing] for the caller. If
399-
/// false, this method returns null, indicating that a layer is no longer
400-
/// necessary. If a render object calling this method stores the `oldLayer`
401-
/// in its [RenderObject.layer] field, it should set that field to null.
402-
/// {@end template}
403-
/// * `offset` is the offset from the origin of the canvas' coordinate system
404-
/// to the origin of the caller's coordinate system.
405-
/// * `clipRect` is rectangle (in the caller's coordinate system) to use to
406-
/// clip the painting done by [painter].
407-
/// * `painter` is a callback that will paint with the [clipRect] applied. This
408-
/// function calls the [painter] synchronously.
409-
/// * `clipBehavior` controls how the rectangle is clipped.
406+
/// The `needsCompositing` argument specifies whether the child needs
407+
/// compositing. Typically this matches the value of
408+
/// [RenderObject.needsCompositing] for the caller. If false, this method
409+
/// returns null, indicating that a layer is no longer necessary. If a render
410+
/// object calling this method stores the `oldLayer` in its
411+
/// [RenderObject.layer] field, it should set that field to null.
412+
///
413+
/// When `needsCompositing` is false, this method will use a more efficient
414+
/// way to apply the layer effect than actually creating a layer.
415+
/// {@endtemplate}
416+
///
417+
/// {@template flutter.rendering.object.pushClipLayer.offset}
418+
/// The `offset` argument is the offset from the origin of the canvas'
419+
/// coordinate system to the origin of the caller's coordinate system.
420+
/// {@endtemplate}
421+
///
422+
/// The `clipRect` is the rectangle (in the caller's coordinate system) to use
423+
/// to clip the painting done by [painter]. It should not include the
424+
/// `offset`.
425+
///
426+
/// The `painter` callback will be called while the `clipRect` is applied. It
427+
/// is called synchronously during the call to [pushClipRect].
428+
///
429+
/// The `clipBehavior` argument controls how the rectangle is clipped.
430+
///
410431
/// {@template flutter.rendering.object.oldLayer}
411-
/// * `oldLayer` is the layer created in the previous frame. Specifying the
412-
/// old layer gives the engine more information for performance
413-
/// optimizations. Typically this is the value of [RenderObject.layer] that
414-
/// a render object creates once, then reuses for all subsequent frames
415-
/// until a layer is no longer needed (e.g. the render object no longer
416-
/// needs compositing) or until the render object changes the type of the
417-
/// layer (e.g. from opacity layer to a clip rect layer).
418-
/// {@end template}
432+
/// For the `oldLayer` argument, specify the layer created in the previous
433+
/// frame. This gives the engine more information for performance
434+
/// optimizations. Typically this is the value of [RenderObject.layer] that a
435+
/// render object creates once, then reuses for all subsequent frames until a
436+
/// layer is no longer needed (e.g. the render object no longer needs
437+
/// compositing) or until the render object changes the type of the layer
438+
/// (e.g. from opacity layer to a clip rect layer).
439+
/// {@endtemplate}
419440
ClipRectLayer pushClipRect(bool needsCompositing, Offset offset, Rect clipRect, PaintingContextCallback painter, { Clip clipBehavior = Clip.hardEdge, ClipRectLayer oldLayer }) {
420441
final Rect offsetClipRect = clipRect.shift(offset);
421442
if (needsCompositing) {
@@ -434,15 +455,21 @@ class PaintingContext extends ClipContext {
434455
/// Clip further painting using a rounded rectangle.
435456
///
436457
/// {@macro flutter.rendering.object.needsCompositing}
437-
/// * `offset` is the offset from the origin of the canvas' coordinate system
438-
/// to the origin of the caller's coordinate system.
439-
/// * `bounds` is the region of the canvas (in the caller's coordinate system)
440-
/// into which `painter` will paint in.
441-
/// * `clipRRect` is the rounded-rectangle (in the caller's coordinate system)
442-
/// to use to clip the painting done by `painter`.
443-
/// * `painter` is a callback that will paint with the `clipRRect` applied. This
444-
/// function calls the `painter` synchronously.
445-
/// * `clipBehavior` controls how the path is clipped.
458+
///
459+
/// {@macro flutter.rendering.object.pushClipLayer.offset}
460+
///
461+
/// The `bounds` argument is used to specify the region of the canvas (in the
462+
/// caller's coordinate system) into which `painter` will paint.
463+
///
464+
/// The `clipRRect` argument specifies the rounded-rectangle (in the caller's
465+
/// coordinate system) to use to clip the painting done by `painter`. It
466+
/// should not include the `offset`.
467+
///
468+
/// The `painter` callback will be called while the `clipRRect` is applied. It
469+
/// is called synchronously during the call to [pushClipRRect].
470+
///
471+
/// The `clipBehavior` argument controls how the rounded rectangle is clipped.
472+
///
446473
/// {@macro flutter.rendering.object.oldLayer}
447474
ClipRRectLayer pushClipRRect(bool needsCompositing, Offset offset, Rect bounds, RRect clipRRect, PaintingContextCallback painter, { Clip clipBehavior = Clip.antiAlias, ClipRRectLayer oldLayer }) {
448475
assert(clipBehavior != null);
@@ -464,15 +491,21 @@ class PaintingContext extends ClipContext {
464491
/// Clip further painting using a path.
465492
///
466493
/// {@macro flutter.rendering.object.needsCompositing}
467-
/// * `offset` is the offset from the origin of the canvas' coordinate system
468-
/// to the origin of the caller's coordinate system.
469-
/// * `bounds` is the region of the canvas (in the caller's coordinate system)
470-
/// into which `painter` will paint in.
471-
/// * `clipPath` is the path (in the coordinate system of the caller) to use to
472-
/// clip the painting done by `painter`.
473-
/// * `painter` is a callback that will paint with the `clipPath` applied. This
474-
/// function calls the `painter` synchronously.
475-
/// * `clipBehavior` controls how the rounded rectangle is clipped.
494+
///
495+
/// {@macro flutter.rendering.object.pushClipLayer.offset}
496+
///
497+
/// The `bounds` argument is used to specify the region of the canvas (in the
498+
/// caller's coordinate system) into which `painter` will paint.
499+
///
500+
/// The `clipPath` argument specifies the [Path] (in the caller's coordinate
501+
/// system) to use to clip the painting done by `painter`. It should not
502+
/// include the `offset`.
503+
///
504+
/// The `painter` callback will be called while the `clipPath` is applied. It
505+
/// is called synchronously during the call to [pushClipPath].
506+
///
507+
/// The `clipBehavior` argument controls how the path is clipped.
508+
///
476509
/// {@macro flutter.rendering.object.oldLayer}
477510
ClipPathLayer pushClipPath(bool needsCompositing, Offset offset, Rect bounds, Path clipPath, PaintingContextCallback painter, { Clip clipBehavior = Clip.antiAlias, ClipPathLayer oldLayer }) {
478511
assert(clipBehavior != null);
@@ -493,12 +526,14 @@ class PaintingContext extends ClipContext {
493526

494527
/// Blend further painting with a color filter.
495528
///
496-
/// * `offset` is the offset from the origin of the canvas' coordinate system
497-
/// to the origin of the caller's coordinate system.
498-
/// * `colorFilter` is the [ColorFilter] value to use when blending the
499-
/// painting done by `painter`.
500-
/// * `painter` is a callback that will paint with the `colorFilter` applied.
501-
/// This function calls the `painter` synchronously.
529+
/// {@macro flutter.rendering.object.pushLayer.offset}
530+
///
531+
/// The `colorFilter` argument is the [ColorFilter] value to use when blending
532+
/// the painting done by `painter`.
533+
///
534+
/// The `painter` callback will be called while the `colorFilter` is applied.
535+
/// It is called synchronously during the call to [pushColorFilter].
536+
///
502537
/// {@macro flutter.rendering.object.oldLayer}
503538
///
504539
/// A [RenderObject] that uses this function is very likely to require its
@@ -516,11 +551,17 @@ class PaintingContext extends ClipContext {
516551
/// Transform further painting using a matrix.
517552
///
518553
/// {@macro flutter.rendering.object.needsCompositing}
519-
/// * `offset` is the offset from the origin of the canvas' coordinate system
520-
/// to the origin of the caller's coordinate system.
521-
/// * `transform` is the matrix to apply to the painting done by `painter`.
522-
/// * `painter` is a callback that will paint with the `transform` applied. This
523-
/// function calls the `painter` synchronously.
554+
///
555+
/// The `offset` argument is the offset to pass to `painter` and the offset to
556+
/// the origin used by `transform`.
557+
///
558+
/// The `transform` argument is the [Matrix4] with which to transform the
559+
/// coordinate system while calling `painter`. It should not include `offset`.
560+
/// It is applied effectively after applying `offset`.
561+
///
562+
/// The `painter` callback will be called while the `transform` is applied. It
563+
/// is called synchronously during the call to [pushTransform].
564+
///
524565
/// {@macro flutter.rendering.object.oldLayer}
525566
TransformLayer pushTransform(bool needsCompositing, Offset offset, Matrix4 transform, PaintingContextCallback painter, { TransformLayer oldLayer }) {
526567
final Matrix4 effectiveTransform = Matrix4.translationValues(offset.dx, offset.dy, 0.0)
@@ -548,13 +589,16 @@ class PaintingContext extends ClipContext {
548589

549590
/// Blend further painting with an alpha value.
550591
///
551-
/// * `offset` is the offset from the origin of the canvas' coordinate system
552-
/// to the origin of the caller's coordinate system.
553-
/// * `alpha` is the alpha value to use when blending the painting done by
554-
/// `painter`. An alpha value of 0 means the painting is fully transparent
555-
/// and an alpha value of 255 means the painting is fully opaque.
556-
/// * `painter` is a callback that will paint with the `alpha` applied. This
557-
/// function calls the `painter` synchronously.
592+
/// The `offset` argument indicates an offset to apply to all the children
593+
/// (the rendering created by `painter`).
594+
///
595+
/// The `alpha` argument is the alpha value to use when blending the painting
596+
/// done by `painter`. An alpha value of 0 means the painting is fully
597+
/// transparent and an alpha value of 255 means the painting is fully opaque.
598+
///
599+
/// The `painter` callback will be called while the `alpha` is applied. It
600+
/// is called synchronously during the call to [pushOpacity].
601+
///
558602
/// {@macro flutter.rendering.object.oldLayer}
559603
///
560604
/// A [RenderObject] that uses this function is very likely to require its

packages/flutter/lib/src/rendering/proxy_box.dart

+3
Original file line numberDiff line numberDiff line change
@@ -968,6 +968,9 @@ class RenderShaderMask extends RenderProxyBox {
968968
///
969969
/// The shader callback is called with the current size of the child so that
970970
/// it can customize the shader to the size and location of the child.
971+
///
972+
/// The rectangle will always be at the origin when called by
973+
/// [RenderShaderMask].
971974
// TODO(abarth): Use the delegate pattern here to avoid generating spurious
972975
// repaints when the ShaderCallback changes identity.
973976
ShaderCallback get shaderCallback => _shaderCallback;

packages/flutter/lib/src/widgets/binding.dart

+3-1
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,9 @@ abstract class WidgetsBindingObserver {
214214
/// boilerplate.
215215
void didChangeTextScaleFactor() { }
216216

217-
/// {@macro on_platform_brightness_change}
217+
/// Called when the platform brightness changes.
218+
///
219+
/// This method exposes notifications from [Window.onPlatformBrightnessChanged].
218220
void didChangePlatformBrightness() { }
219221

220222
/// Called when the system tells the app that the user's locale has

0 commit comments

Comments
 (0)