1// Copyright 2014 The Flutter 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 'object.dart';
6import 'proxy_box.dart';
7import 'proxy_sliver.dart';
8import 'sliver.dart';
9
10/// Paints a [Decoration] either before or after its child paints.
11///
12/// If the child has infinite scroll extent, then the [Decoration] paints itself up to the
13/// bottom cache extent.
14class RenderDecoratedSliver extends RenderProxySliver {
15 /// Creates a decorated sliver.
16 ///
17 /// The [decoration], [position], and [configuration] arguments must not be
18 /// null. By default the decoration paints behind the child.
19 ///
20 /// The [ImageConfiguration] will be passed to the decoration (with the size
21 /// filled in) to let it resolve images.
22 RenderDecoratedSliver({
23 required Decoration decoration,
24 DecorationPosition position = DecorationPosition.background,
25 ImageConfiguration configuration = ImageConfiguration.empty,
26 }) : _decoration = decoration,
27 _position = position,
28 _configuration = configuration;
29
30 /// What decoration to paint.
31 ///
32 /// Commonly a [BoxDecoration].
33 Decoration get decoration => _decoration;
34 Decoration _decoration;
35 set decoration(Decoration value) {
36 if (value == decoration) {
37 return;
38 }
39 _decoration = value;
40 _painter?.dispose();
41 _painter = decoration.createBoxPainter(markNeedsPaint);
42 markNeedsPaint();
43 }
44
45 /// Whether to paint the box decoration behind or in front of the child.
46 DecorationPosition get position => _position;
47 DecorationPosition _position;
48 set position(DecorationPosition value) {
49 if (value == position) {
50 return;
51 }
52 _position = value;
53 markNeedsPaint();
54 }
55
56 /// The settings to pass to the decoration when painting, so that it can
57 /// resolve images appropriately. See [ImageProvider.resolve] and
58 /// [BoxPainter.paint].
59 ///
60 /// The [ImageConfiguration.textDirection] field is also used by
61 /// direction-sensitive [Decoration]s for painting and hit-testing.
62 ImageConfiguration get configuration => _configuration;
63 ImageConfiguration _configuration;
64 set configuration(ImageConfiguration value) {
65 if (value == configuration) {
66 return;
67 }
68 _configuration = value;
69 markNeedsPaint();
70 }
71
72 BoxPainter? _painter;
73
74 @override
75 void attach(covariant PipelineOwner owner) {
76 _painter = decoration.createBoxPainter(markNeedsPaint);
77 super.attach(owner);
78 }
79
80 @override
81 void detach() {
82 _painter?.dispose();
83 _painter = null;
84 super.detach();
85 }
86
87 @override
88 void dispose() {
89 _painter?.dispose();
90 _painter = null;
91 super.dispose();
92 }
93
94 @override
95 void paint(PaintingContext context, Offset offset) {
96 if (child == null || !child!.geometry!.visible) {
97 return;
98 }
99 // In the case where the child sliver has infinite scroll extent, the decoration
100 // should only extend down to the bottom cache extent.
101 final double cappedMainAxisExtent = child!.geometry!.scrollExtent.isInfinite
102 ? constraints.scrollOffset + child!.geometry!.cacheExtent + constraints.cacheOrigin
103 : child!.geometry!.scrollExtent;
104 final (Size childSize, Offset scrollOffset) = switch (constraints.axis) {
105 Axis.horizontal => (
106 Size(cappedMainAxisExtent, constraints.crossAxisExtent),
107 Offset(-constraints.scrollOffset, 0.0),
108 ),
109 Axis.vertical => (
110 Size(constraints.crossAxisExtent, cappedMainAxisExtent),
111 Offset(0.0, -constraints.scrollOffset),
112 ),
113 };
114 offset += (child!.parentData! as SliverPhysicalParentData).paintOffset;
115 void paintDecoration() => _painter!.paint(
116 context.canvas,
117 offset + scrollOffset,
118 configuration.copyWith(size: childSize),
119 );
120 switch (position) {
121 case DecorationPosition.background:
122 paintDecoration();
123 context.paintChild(child!, offset);
124 case DecorationPosition.foreground:
125 context.paintChild(child!, offset);
126 paintDecoration();
127 }
128 }
129}
130

Provided by KDAB

Privacy Policy
Learn more about Flutter for embedded and desktop on industrialflutter.com