@@ -43,212 +43,6 @@ class _SingleChildScrollViewWithScrollbarState
4343 }
4444}
4545
46- /// Specifies an order in which to paint the slivers of a [CustomScrollView] .
47- ///
48- /// Whichever order the slivers are painted in,
49- /// they will be hit-tested in the opposite order.
50- ///
51- /// This can also be thought of as an ordering in the z-direction:
52- /// whichever sliver is painted last (and hit-tested first) is on top,
53- /// because it will paint over other slivers if there is overlap.
54- /// Similarly, whichever sliver is painted first (and hit-tested last)
55- /// is on the bottom.
56- enum SliverPaintOrder {
57- /// The first sliver paints on top, and the last sliver on bottom.
58- ///
59- /// The slivers are painted in the reverse order of [CustomScrollView.slivers] ,
60- /// and hit-tested in the same order as [CustomScrollView.slivers] .
61- firstIsTop,
62-
63- /// The last sliver paints on top, and the first sliver on bottom.
64- ///
65- /// The slivers are painted in the same order as [CustomScrollView.slivers] ,
66- /// and hit-tested in the reverse order.
67- lastIsTop,
68-
69- /// The default order for [CustomScrollView] : the center sliver paints on top,
70- /// and the first sliver paints on bottom.
71- ///
72- /// If [CustomScrollView.center] is null or corresponds to the first sliver
73- /// in [CustomScrollView.slivers] , this order is equivalent to [firstIsTop] .
74- /// Otherwise, the [CustomScrollView.center] sliver paints on top;
75- /// it's followed in the z-order by the slivers after it to the end
76- /// of the list, then the slivers before the center in reverse order,
77- /// with the first sliver in the list at the bottom in the z-direction.
78- centerTopFirstBottom,
79- }
80-
81- /// A [CustomScrollView] with control over the paint order, or z-order,
82- /// between slivers.
83- ///
84- /// This is just like [CustomScrollView] except it adds the [paintOrder_] field.
85- ///
86- /// (Actually there's one [CustomScrollView] feature this doesn't implement:
87- /// [shrinkWrap] always has its default value of false. That feature would be
88- /// easy to add if desired.)
89- // TODO(upstream): Pending PR: https://github.com/flutter/flutter/pull/164818
90- // Notes from before sending that PR:
91- // Add an option [ScrollView.zOrder]? (An enum, or possibly
92- // a delegate.) Or at minimum document on [ScrollView.center] the
93- // existing behavior, which is counterintuitive.
94- // Nearest related upstream feature requests I find are for a "z-index",
95- // for CustomScrollView, Column, Row, and Stack respectively:
96- // https://github.com/flutter/flutter/issues/121173#issuecomment-1712825747
97- // https://github.com/flutter/flutter/issues/121173
98- // https://github.com/flutter/flutter/issues/121173#issuecomment-1914959184
99- // https://github.com/flutter/flutter/issues/70836
100- // A delegate would give enough flexibility for that and much else,
101- // but I'm not sure how many use cases wouldn't be covered by a small enum.
102- //
103- // Ah, and here's a more on-point issue (more recently):
104- // https://github.com/flutter/flutter/issues/145592
105- //
106- // TODO: perhaps sticky_header should configure a CustomPaintOrderScrollView automatically?
107- class CustomPaintOrderScrollView extends CustomScrollView {
108- const CustomPaintOrderScrollView ({
109- super .key,
110- super .scrollDirection,
111- super .reverse,
112- super .controller,
113- super .primary,
114- super .physics,
115- super .scrollBehavior,
116- // super.shrinkWrap, // omitted, always false
117- super .center,
118- super .anchor,
119- super .cacheExtent,
120- super .slivers,
121- super .semanticChildCount,
122- super .dragStartBehavior,
123- super .keyboardDismissBehavior,
124- super .restorationId,
125- super .clipBehavior,
126- super .hitTestBehavior,
127- SliverPaintOrder paintOrder = SliverPaintOrder .centerTopFirstBottom,
128- }) : paintOrder_ = paintOrder;
129-
130- /// The order in which to paint the slivers;
131- /// equivalently, the order in which to arrange them in the z-direction.
132- ///
133- /// Whichever order the slivers are painted in,
134- /// they will be hit-tested in the opposite order.
135- ///
136- /// To think of this as an ordering in the z-direction:
137- /// whichever sliver is painted last (and hit-tested first) is on top,
138- /// because it will paint over other slivers if there is overlap.
139- /// Similarly, whichever sliver is painted first (and hit-tested last)
140- /// is on the bottom.
141- ///
142- /// This defaults to [SliverPaintOrder.centerTopFirstBottom] ,
143- /// the behavior of the [CustomScrollView] base class.
144- final SliverPaintOrder paintOrder_;
145-
146- @override
147- Widget buildViewport (BuildContext context, ViewportOffset offset,
148- AxisDirection axisDirection, List <Widget > slivers) {
149- return CustomPaintOrderViewport (
150- axisDirection: axisDirection,
151- offset: offset,
152- slivers: slivers,
153- cacheExtent: cacheExtent,
154- center: center,
155- anchor: anchor,
156- clipBehavior: clipBehavior,
157- paintOrder_: paintOrder_,
158- );
159- }
160- }
161-
162- /// The viewport configured by a [CustomPaintOrderScrollView] .
163- class CustomPaintOrderViewport extends Viewport {
164- CustomPaintOrderViewport ({
165- super .key,
166- super .axisDirection,
167- super .crossAxisDirection,
168- super .anchor,
169- required super .offset,
170- super .center,
171- super .cacheExtent,
172- super .cacheExtentStyle,
173- super .slivers,
174- super .clipBehavior,
175- required this .paintOrder_,
176- });
177-
178- final SliverPaintOrder paintOrder_;
179-
180- @override
181- RenderViewport createRenderObject (BuildContext context) {
182- return RenderCustomPaintOrderViewport (
183- axisDirection: axisDirection,
184- crossAxisDirection: crossAxisDirection
185- ?? Viewport .getDefaultCrossAxisDirection (context, axisDirection),
186- anchor: anchor,
187- offset: offset,
188- cacheExtent: cacheExtent,
189- cacheExtentStyle: cacheExtentStyle,
190- clipBehavior: clipBehavior,
191- paintOrder_: paintOrder_,
192- );
193- }
194- }
195-
196- /// The render object configured by a [CustomPaintOrderViewport] .
197- class RenderCustomPaintOrderViewport extends RenderViewport {
198- RenderCustomPaintOrderViewport ({
199- super .axisDirection,
200- required super .crossAxisDirection,
201- required super .offset,
202- super .anchor,
203- super .children,
204- super .center,
205- super .cacheExtent,
206- super .cacheExtentStyle,
207- super .clipBehavior,
208- required this .paintOrder_,
209- });
210-
211- final SliverPaintOrder paintOrder_;
212-
213- Iterable <RenderSliver > get _lastToFirst {
214- final List <RenderSliver > children = < RenderSliver > [];
215- RenderSliver ? child = lastChild;
216- while (child != null ) {
217- children.add (child);
218- child = childBefore (child);
219- }
220- return children;
221- }
222-
223- Iterable <RenderSliver > get _firstToLast {
224- final List <RenderSliver > children = < RenderSliver > [];
225- RenderSliver ? child = firstChild;
226- while (child != null ) {
227- children.add (child);
228- child = childAfter (child);
229- }
230- return children;
231- }
232-
233- @override
234- Iterable <RenderSliver > get childrenInPaintOrder {
235- return switch (paintOrder_) {
236- SliverPaintOrder .firstIsTop => _lastToFirst,
237- SliverPaintOrder .lastIsTop => _firstToLast,
238- SliverPaintOrder .centerTopFirstBottom => super .childrenInPaintOrder,
239- };
240- }
241-
242- @override
243- Iterable <RenderSliver > get childrenInHitTestOrder {
244- return switch (paintOrder_) {
245- SliverPaintOrder .firstIsTop => _firstToLast,
246- SliverPaintOrder .lastIsTop => _lastToFirst,
247- SliverPaintOrder .centerTopFirstBottom => super .childrenInHitTestOrder,
248- };
249- }
250- }
251-
25246/// A version of [ScrollPosition] adapted for the Zulip message list,
25347/// used by [MessageListScrollController] .
25448class MessageListScrollPosition extends ScrollPositionWithSingleContext {
0 commit comments