Unverified Commit 027bb844 authored by Ian Hickson's avatar Ian Hickson Committed by GitHub

Make SlottedMultiChildRenderObjectWidgetMixin a concrete class (#126108)

This is a proof of concept for renaming SlottedMultiChildRenderObjectWidgetMixin to SlottedMultiChildRenderObjectWidget and making it a concrete class.

I also made SlottedContainerRenderObjectMixin generic instead of being specialized to RenderBox.

I don't think this is something we can easily automigrate, but we may not need to, I don't know how common this is...
parent 5235a0f0
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
/// Flutter code sample for [SlottedMultiChildRenderObjectWidgetMixin]. /// Flutter code sample for [SlottedMultiChildRenderObjectWidget].
/// Slots used for the children of [Diagonal] and [RenderDiagonal]. /// Slots used for the children of [Diagonal] and [RenderDiagonal].
enum DiagonalSlot { enum DiagonalSlot {
...@@ -14,9 +14,9 @@ enum DiagonalSlot { ...@@ -14,9 +14,9 @@ enum DiagonalSlot {
} }
/// A widget that demonstrates the usage of /// A widget that demonstrates the usage of
/// [SlottedMultiChildRenderObjectWidgetMixin] by providing slots for two /// [SlottedMultiChildRenderObjectWidget] by providing slots for two
/// children that will be arranged diagonally. /// children that will be arranged diagonally.
class Diagonal extends RenderObjectWidget with SlottedMultiChildRenderObjectWidgetMixin<DiagonalSlot> { class Diagonal extends SlottedMultiChildRenderObjectWidget<DiagonalSlot, RenderBox> {
const Diagonal({ const Diagonal({
super.key, super.key,
this.topLeft, this.topLeft,
...@@ -49,7 +49,7 @@ class Diagonal extends RenderObjectWidget with SlottedMultiChildRenderObjectWidg ...@@ -49,7 +49,7 @@ class Diagonal extends RenderObjectWidget with SlottedMultiChildRenderObjectWidg
// [SlottedRenderObjectElement.update]. // [SlottedRenderObjectElement.update].
@override @override
SlottedContainerRenderObjectMixin<DiagonalSlot> createRenderObject( SlottedContainerRenderObjectMixin<DiagonalSlot, RenderBox> createRenderObject(
BuildContext context, BuildContext context,
) { ) {
return RenderDiagonal( return RenderDiagonal(
...@@ -60,7 +60,7 @@ class Diagonal extends RenderObjectWidget with SlottedMultiChildRenderObjectWidg ...@@ -60,7 +60,7 @@ class Diagonal extends RenderObjectWidget with SlottedMultiChildRenderObjectWidg
@override @override
void updateRenderObject( void updateRenderObject(
BuildContext context, BuildContext context,
SlottedContainerRenderObjectMixin<DiagonalSlot> renderObject, SlottedContainerRenderObjectMixin<DiagonalSlot, RenderBox> renderObject,
) { ) {
(renderObject as RenderDiagonal).backgroundColor = backgroundColor; (renderObject as RenderDiagonal).backgroundColor = backgroundColor;
} }
...@@ -70,7 +70,7 @@ class Diagonal extends RenderObjectWidget with SlottedMultiChildRenderObjectWidg ...@@ -70,7 +70,7 @@ class Diagonal extends RenderObjectWidget with SlottedMultiChildRenderObjectWidg
/// [SlottedContainerRenderObjectMixin] by providing slots for two children that /// [SlottedContainerRenderObjectMixin] by providing slots for two children that
/// will be arranged diagonally. /// will be arranged diagonally.
class RenderDiagonal extends RenderBox class RenderDiagonal extends RenderBox
with SlottedContainerRenderObjectMixin<DiagonalSlot>, DebugOverflowIndicatorMixin { with SlottedContainerRenderObjectMixin<DiagonalSlot, RenderBox>, DebugOverflowIndicatorMixin {
RenderDiagonal({Color? backgroundColor}) : _backgroundColor = backgroundColor; RenderDiagonal({Color? backgroundColor}) : _backgroundColor = backgroundColor;
// Getters and setters to configure the [RenderObject] with the configuration // Getters and setters to configure the [RenderObject] with the configuration
......
...@@ -1342,7 +1342,7 @@ class _RenderChipRedirectingHitDetection extends RenderConstrainedBox { ...@@ -1342,7 +1342,7 @@ class _RenderChipRedirectingHitDetection extends RenderConstrainedBox {
} }
} }
class _ChipRenderWidget extends RenderObjectWidget with SlottedMultiChildRenderObjectWidgetMixin<_ChipSlot> { class _ChipRenderWidget extends SlottedMultiChildRenderObjectWidget<_ChipSlot, RenderBox> {
const _ChipRenderWidget({ const _ChipRenderWidget({
required this.theme, required this.theme,
this.value, this.value,
...@@ -1393,7 +1393,7 @@ class _ChipRenderWidget extends RenderObjectWidget with SlottedMultiChildRenderO ...@@ -1393,7 +1393,7 @@ class _ChipRenderWidget extends RenderObjectWidget with SlottedMultiChildRenderO
} }
@override @override
SlottedContainerRenderObjectMixin<_ChipSlot> createRenderObject(BuildContext context) { SlottedContainerRenderObjectMixin<_ChipSlot, RenderBox> createRenderObject(BuildContext context) {
return _RenderChip( return _RenderChip(
theme: theme, theme: theme,
textDirection: Directionality.of(context), textDirection: Directionality.of(context),
...@@ -1478,7 +1478,7 @@ class _ChipRenderTheme { ...@@ -1478,7 +1478,7 @@ class _ChipRenderTheme {
); );
} }
class _RenderChip extends RenderBox with SlottedContainerRenderObjectMixin<_ChipSlot> { class _RenderChip extends RenderBox with SlottedContainerRenderObjectMixin<_ChipSlot, RenderBox> {
_RenderChip({ _RenderChip({
required _ChipRenderTheme theme, required _ChipRenderTheme theme,
required TextDirection textDirection, required TextDirection textDirection,
......
...@@ -693,7 +693,7 @@ class _RenderDecorationLayout { ...@@ -693,7 +693,7 @@ class _RenderDecorationLayout {
} }
// The workhorse: layout and paint a _Decorator widget's _Decoration. // The workhorse: layout and paint a _Decorator widget's _Decoration.
class _RenderDecoration extends RenderBox with SlottedContainerRenderObjectMixin<_DecorationSlot> { class _RenderDecoration extends RenderBox with SlottedContainerRenderObjectMixin<_DecorationSlot, RenderBox> {
_RenderDecoration({ _RenderDecoration({
required _Decoration decoration, required _Decoration decoration,
required TextDirection textDirection, required TextDirection textDirection,
...@@ -1637,7 +1637,7 @@ class _RenderDecoration extends RenderBox with SlottedContainerRenderObjectMixin ...@@ -1637,7 +1637,7 @@ class _RenderDecoration extends RenderBox with SlottedContainerRenderObjectMixin
} }
} }
class _Decorator extends RenderObjectWidget with SlottedMultiChildRenderObjectWidgetMixin<_DecorationSlot> { class _Decorator extends SlottedMultiChildRenderObjectWidget<_DecorationSlot, RenderBox> {
const _Decorator({ const _Decorator({
required this.textAlignVertical, required this.textAlignVertical,
required this.decoration, required this.decoration,
......
...@@ -967,7 +967,7 @@ enum _ListTileSlot { ...@@ -967,7 +967,7 @@ enum _ListTileSlot {
trailing, trailing,
} }
class _ListTile extends RenderObjectWidget with SlottedMultiChildRenderObjectWidgetMixin<_ListTileSlot> { class _ListTile extends SlottedMultiChildRenderObjectWidget<_ListTileSlot, RenderBox> {
const _ListTile({ const _ListTile({
this.leading, this.leading,
required this.title, required this.title,
...@@ -1049,7 +1049,7 @@ class _ListTile extends RenderObjectWidget with SlottedMultiChildRenderObjectWid ...@@ -1049,7 +1049,7 @@ class _ListTile extends RenderObjectWidget with SlottedMultiChildRenderObjectWid
} }
} }
class _RenderListTile extends RenderBox with SlottedContainerRenderObjectMixin<_ListTileSlot> { class _RenderListTile extends RenderBox with SlottedContainerRenderObjectMixin<_ListTileSlot, RenderBox> {
_RenderListTile({ _RenderListTile({
required bool isDense, required bool isDense,
required VisualDensity visualDensity, required VisualDensity visualDensity,
......
...@@ -1760,7 +1760,7 @@ abstract class InheritedWidget extends ProxyWidget { ...@@ -1760,7 +1760,7 @@ abstract class InheritedWidget extends ProxyWidget {
/// ///
/// * [MultiChildRenderObjectWidget], which configures a [RenderObject] with /// * [MultiChildRenderObjectWidget], which configures a [RenderObject] with
/// a single list of children. /// a single list of children.
/// * [SlottedMultiChildRenderObjectWidgetMixin], which configures a /// * [SlottedMultiChildRenderObjectWidget], which configures a
/// [RenderObject] that organizes its children in different named slots. /// [RenderObject] that organizes its children in different named slots.
abstract class RenderObjectWidget extends Widget { abstract class RenderObjectWidget extends Widget {
/// Abstract const constructor. This constructor enables subclasses to provide /// Abstract const constructor. This constructor enables subclasses to provide
...@@ -1854,7 +1854,7 @@ abstract class SingleChildRenderObjectWidget extends RenderObjectWidget { ...@@ -1854,7 +1854,7 @@ abstract class SingleChildRenderObjectWidget extends RenderObjectWidget {
/// * [Stack], which uses [MultiChildRenderObjectWidget]. /// * [Stack], which uses [MultiChildRenderObjectWidget].
/// * [RenderStack], for an example implementation of the associated render /// * [RenderStack], for an example implementation of the associated render
/// object. /// object.
/// * [SlottedMultiChildRenderObjectWidgetMixin], which configures a /// * [SlottedMultiChildRenderObjectWidget], which configures a
/// [RenderObject] that instead of having a single list of children organizes /// [RenderObject] that instead of having a single list of children organizes
/// its children in named slots. /// its children in named slots.
abstract class MultiChildRenderObjectWidget extends RenderObjectWidget { abstract class MultiChildRenderObjectWidget extends RenderObjectWidget {
......
...@@ -7,8 +7,8 @@ import 'package:flutter/rendering.dart'; ...@@ -7,8 +7,8 @@ import 'package:flutter/rendering.dart';
import 'framework.dart'; import 'framework.dart';
/// A mixin for a [RenderObjectWidget] that configures a [RenderObject] /// A superclass for [RenderObjectWidget]s that configure [RenderObject]
/// subclass, which organizes its children in different slots. /// subclasses that organize their children in different slots.
/// ///
/// Implementers of this mixin have to provide the list of available slots by /// Implementers of this mixin have to provide the list of available slots by
/// overriding [slots]. The list of slots must never change for a given class /// overriding [slots]. The list of slots must never change for a given class
...@@ -20,14 +20,19 @@ import 'framework.dart'; ...@@ -20,14 +20,19 @@ import 'framework.dart';
/// widget configuration for a given slot. /// widget configuration for a given slot.
/// ///
/// The [RenderObject] returned by [createRenderObject] and updated by /// The [RenderObject] returned by [createRenderObject] and updated by
/// [updateRenderObject] must implement the [SlottedContainerRenderObjectMixin]. /// [updateRenderObject] must implement [SlottedContainerRenderObjectMixin].
/// ///
/// The type parameter `S` is the type for the slots to be used by this /// The type parameter `SlotType` is the type for the slots to be used by this
/// [RenderObjectWidget] and the [RenderObject] it configures. In the typical /// [RenderObjectWidget] and the [RenderObject] it configures. In the typical
/// case, `S` is an [Enum] type. /// case, `SlotType` is an [Enum] type.
///
/// The type parameter `ChildType` is the type used for the [RenderObject] children
/// (e.g. [RenderBox] or [RenderSliver]). In the typical case, `ChildType` is
/// [RenderBox]. This class does not support having different kinds of children
/// for different slots.
/// ///
/// {@tool dartpad} /// {@tool dartpad}
/// This example uses the [SlottedMultiChildRenderObjectWidgetMixin] in /// This example uses the [SlottedMultiChildRenderObjectWidget] in
/// combination with the [SlottedContainerRenderObjectMixin] to implement a /// combination with the [SlottedContainerRenderObjectMixin] to implement a
/// widget that provides two slots: topLeft and bottomRight. The widget arranges /// widget that provides two slots: topLeft and bottomRight. The widget arranges
/// the children in those slots diagonally. /// the children in those slots diagonally.
...@@ -39,9 +44,25 @@ import 'framework.dart'; ...@@ -39,9 +44,25 @@ import 'framework.dart';
/// ///
/// * [MultiChildRenderObjectWidget], which configures a [RenderObject] /// * [MultiChildRenderObjectWidget], which configures a [RenderObject]
/// with a single list of children. /// with a single list of children.
/// * [ListTile], which uses [SlottedMultiChildRenderObjectWidgetMixin] in its /// * [ListTile], which uses [SlottedMultiChildRenderObjectWidget] in its
/// internal (private) implementation. /// internal (private) implementation.
mixin SlottedMultiChildRenderObjectWidgetMixin<S> on RenderObjectWidget { abstract class SlottedMultiChildRenderObjectWidget<SlotType, ChildType extends RenderObject> extends RenderObjectWidget with SlottedMultiChildRenderObjectWidgetMixin<SlotType, ChildType> {
/// Abstract const constructor. This constructor enables subclasses to provide
/// const constructors so that they can be used in const expressions.
const SlottedMultiChildRenderObjectWidget({ super.key });
}
/// A mixin version of [SlottedMultiChildRenderObjectWidget].
///
/// This mixin provides the same logic as extending
/// [SlottedMultiChildRenderObjectWidget] directly.
///
/// It was deprecated to simplify the process of creating slotted widgets.
@Deprecated(
'Extend SlottedMultiChildRenderObjectWidget instead of mixing in SlottedMultiChildRenderObjectWidgetMixin. '
'This feature was deprecated after v3.10.0-1.5.pre.'
)
mixin SlottedMultiChildRenderObjectWidgetMixin<SlotType, ChildType extends RenderObject> on RenderObjectWidget {
/// Returns a list of all available slots. /// Returns a list of all available slots.
/// ///
/// The list of slots must be static and must never change for a given class /// The list of slots must be static and must never change for a given class
...@@ -51,7 +72,7 @@ mixin SlottedMultiChildRenderObjectWidgetMixin<S> on RenderObjectWidget { ...@@ -51,7 +72,7 @@ mixin SlottedMultiChildRenderObjectWidgetMixin<S> on RenderObjectWidget {
/// this getter can be implemented by returning what the `values` getter /// this getter can be implemented by returning what the `values` getter
/// of the enum used returns. /// of the enum used returns.
@protected @protected
Iterable<S> get slots; Iterable<SlotType> get slots;
/// Returns the widget that is currently occupying the provided `slot`. /// Returns the widget that is currently occupying the provided `slot`.
/// ///
...@@ -59,56 +80,60 @@ mixin SlottedMultiChildRenderObjectWidgetMixin<S> on RenderObjectWidget { ...@@ -59,56 +80,60 @@ mixin SlottedMultiChildRenderObjectWidgetMixin<S> on RenderObjectWidget {
/// the [RenderObject] produced by the returned [Widget] in the provided /// the [RenderObject] produced by the returned [Widget] in the provided
/// `slot`. /// `slot`.
@protected @protected
Widget? childForSlot(S slot); Widget? childForSlot(SlotType slot);
@override @override
SlottedContainerRenderObjectMixin<S> createRenderObject(BuildContext context); SlottedContainerRenderObjectMixin<SlotType, ChildType> createRenderObject(BuildContext context);
@override @override
void updateRenderObject(BuildContext context, SlottedContainerRenderObjectMixin<S> renderObject); void updateRenderObject(BuildContext context, SlottedContainerRenderObjectMixin<SlotType, ChildType> renderObject);
@override @override
SlottedRenderObjectElement<S> createElement() => SlottedRenderObjectElement<S>(this); SlottedRenderObjectElement<SlotType, ChildType> createElement() => SlottedRenderObjectElement<SlotType, ChildType>(this);
} }
/// Mixin for a [RenderBox] configured by a [SlottedMultiChildRenderObjectWidgetMixin]. /// Mixin for a [RenderObject] configured by a [SlottedMultiChildRenderObjectWidget].
/// ///
/// The [RenderBox] child currently occupying a given slot can be obtained by /// The [RenderObject] child currently occupying a given slot can be obtained by
/// calling [childForSlot]. /// calling [childForSlot].
/// ///
/// Implementers may consider overriding [children] to return the children /// Implementers may consider overriding [children] to return the children
/// of this render object in a consistent order (e.g. hit test order). /// of this render object in a consistent order (e.g. hit test order).
/// ///
/// The type parameter `S` is the type for the slots to be used by this /// The type parameter `SlotType` is the type for the slots to be used by this
/// [RenderObject] and the [SlottedMultiChildRenderObjectWidgetMixin] it was /// [RenderObject] and the [SlottedMultiChildRenderObjectWidget] it was
/// configured by. In the typical case, `S` is an [Enum] type. /// configured by. In the typical case, `SlotType` is an [Enum] type.
///
/// The type parameter `ChildType` is the type of [RenderObject] used for the children
/// (e.g. [RenderBox] or [RenderSliver]). In the typical case, `ChildType` is
/// [RenderBox]. This mixin does not support having different kinds of children
/// for different slots.
/// ///
/// See [SlottedMultiChildRenderObjectWidgetMixin] for example code showcasing /// See [SlottedMultiChildRenderObjectWidget] for example code showcasing how
/// how this mixin is used in combination with the /// this mixin is used in combination with [SlottedMultiChildRenderObjectWidget].
/// [SlottedMultiChildRenderObjectWidgetMixin].
/// ///
/// See also: /// See also:
/// ///
/// * [ContainerRenderObjectMixin], which organizes its children in a single /// * [ContainerRenderObjectMixin], which organizes its children in a single
/// list. /// list.
mixin SlottedContainerRenderObjectMixin<S> on RenderBox { mixin SlottedContainerRenderObjectMixin<SlotType, ChildType extends RenderObject> on RenderObject {
/// Returns the [RenderBox] child that is currently occupying the provided /// Returns the [RenderObject] child that is currently occupying the provided
/// `slot`. /// `slot`.
/// ///
/// Returns null if no [RenderBox] is configured for the given slot. /// Returns null if no [RenderObject] is configured for the given slot.
@protected @protected
RenderBox? childForSlot(S slot) => _slotToChild[slot]; ChildType? childForSlot(SlotType slot) => _slotToChild[slot];
/// Returns an [Iterable] of all non-null children. /// Returns an [Iterable] of all non-null children.
/// ///
/// This getter is used by the default implementation of [attach], [detach], /// This getter is used by the default implementation of [attach], [detach],
/// [redepthChildren], [visitChildren], and [debugDescribeChildren] to iterate /// [redepthChildren], [visitChildren], and [debugDescribeChildren] to iterate
/// over the children of this [RenderBox]. The base implementation makes no /// over the children of this [RenderObject]. The base implementation makes no
/// guarantee about the order in which the children are returned. Subclasses, /// guarantee about the order in which the children are returned. Subclasses
/// for which the child order is important should override this getter and /// for which the child order is important should override this getter and
/// return the children in the desired order. /// return the children in the desired order.
@protected @protected
Iterable<RenderBox> get children => _slotToChild.values; Iterable<ChildType> get children => _slotToChild.values;
/// Returns the debug name for a given `slot`. /// Returns the debug name for a given `slot`.
/// ///
...@@ -119,7 +144,7 @@ mixin SlottedContainerRenderObjectMixin<S> on RenderBox { ...@@ -119,7 +144,7 @@ mixin SlottedContainerRenderObjectMixin<S> on RenderBox {
/// The default implementation calls [EnumName.name] on `slot` if it is an /// The default implementation calls [EnumName.name] on `slot` if it is an
/// [Enum] value and `toString` if it is not. /// [Enum] value and `toString` if it is not.
@protected @protected
String debugNameForSlot(S slot) { String debugNameForSlot(SlotType slot) {
if (slot is Enum) { if (slot is Enum) {
return slot.name; return slot.name;
} }
...@@ -129,7 +154,7 @@ mixin SlottedContainerRenderObjectMixin<S> on RenderBox { ...@@ -129,7 +154,7 @@ mixin SlottedContainerRenderObjectMixin<S> on RenderBox {
@override @override
void attach(PipelineOwner owner) { void attach(PipelineOwner owner) {
super.attach(owner); super.attach(owner);
for (final RenderBox child in children) { for (final ChildType child in children) {
child.attach(owner); child.attach(owner);
} }
} }
...@@ -137,7 +162,7 @@ mixin SlottedContainerRenderObjectMixin<S> on RenderBox { ...@@ -137,7 +162,7 @@ mixin SlottedContainerRenderObjectMixin<S> on RenderBox {
@override @override
void detach() { void detach() {
super.detach(); super.detach();
for (final RenderBox child in children) { for (final ChildType child in children) {
child.detach(); child.detach();
} }
} }
...@@ -155,24 +180,24 @@ mixin SlottedContainerRenderObjectMixin<S> on RenderBox { ...@@ -155,24 +180,24 @@ mixin SlottedContainerRenderObjectMixin<S> on RenderBox {
@override @override
List<DiagnosticsNode> debugDescribeChildren() { List<DiagnosticsNode> debugDescribeChildren() {
final List<DiagnosticsNode> value = <DiagnosticsNode>[]; final List<DiagnosticsNode> value = <DiagnosticsNode>[];
final Map<RenderBox, S> childToSlot = Map<RenderBox, S>.fromIterables( final Map<ChildType, SlotType> childToSlot = Map<ChildType, SlotType>.fromIterables(
_slotToChild.values, _slotToChild.values,
_slotToChild.keys, _slotToChild.keys,
); );
for (final RenderBox child in children) { for (final ChildType child in children) {
_addDiagnostics(child, value, debugNameForSlot(childToSlot[child] as S)); _addDiagnostics(child, value, debugNameForSlot(childToSlot[child] as SlotType));
} }
return value; return value;
} }
void _addDiagnostics(RenderBox child, List<DiagnosticsNode> value, String name) { void _addDiagnostics(ChildType child, List<DiagnosticsNode> value, String name) {
value.add(child.toDiagnosticsNode(name: name)); value.add(child.toDiagnosticsNode(name: name));
} }
final Map<S, RenderBox> _slotToChild = <S, RenderBox>{}; final Map<SlotType, ChildType> _slotToChild = <SlotType, ChildType>{};
void _setChild(RenderBox? child, S slot) { void _setChild(ChildType? child, SlotType slot) {
final RenderBox? oldChild = _slotToChild[slot]; final ChildType? oldChild = _slotToChild[slot];
if (oldChild != null) { if (oldChild != null) {
dropChild(oldChild); dropChild(oldChild);
_slotToChild.remove(slot); _slotToChild.remove(slot);
...@@ -183,9 +208,9 @@ mixin SlottedContainerRenderObjectMixin<S> on RenderBox { ...@@ -183,9 +208,9 @@ mixin SlottedContainerRenderObjectMixin<S> on RenderBox {
} }
} }
void _moveChild(RenderBox child, S slot, S oldSlot) { void _moveChild(ChildType child, SlotType slot, SlotType oldSlot) {
assert(slot != oldSlot); assert(slot != oldSlot);
final RenderBox? oldChild = _slotToChild[oldSlot]; final ChildType? oldChild = _slotToChild[oldSlot];
if (oldChild == child) { if (oldChild == child) {
_setChild(null, oldSlot); _setChild(null, oldSlot);
} }
...@@ -193,16 +218,16 @@ mixin SlottedContainerRenderObjectMixin<S> on RenderBox { ...@@ -193,16 +218,16 @@ mixin SlottedContainerRenderObjectMixin<S> on RenderBox {
} }
} }
/// Element used by the [SlottedMultiChildRenderObjectWidgetMixin]. /// Element used by the [SlottedMultiChildRenderObjectWidget].
class SlottedRenderObjectElement<S> extends RenderObjectElement { class SlottedRenderObjectElement<SlotType, ChildType extends RenderObject> extends RenderObjectElement {
/// Creates an element that uses the given widget as its configuration. /// Creates an element that uses the given widget as its configuration.
SlottedRenderObjectElement(SlottedMultiChildRenderObjectWidgetMixin<S> super.widget); SlottedRenderObjectElement(SlottedMultiChildRenderObjectWidgetMixin<SlotType, ChildType> super.widget);
Map<S, Element> _slotToChild = <S, Element>{}; Map<SlotType, Element> _slotToChild = <SlotType, Element>{};
Map<Key, Element> _keyedChildren = <Key, Element>{}; Map<Key, Element> _keyedChildren = <Key, Element>{};
@override @override
SlottedContainerRenderObjectMixin<S> get renderObject => super.renderObject as SlottedContainerRenderObjectMixin<S>; SlottedContainerRenderObjectMixin<SlotType, ChildType> get renderObject => super.renderObject as SlottedContainerRenderObjectMixin<SlotType, ChildType>;
@override @override
void visitChildren(ElementVisitor visitor) { void visitChildren(ElementVisitor visitor) {
...@@ -212,7 +237,7 @@ class SlottedRenderObjectElement<S> extends RenderObjectElement { ...@@ -212,7 +237,7 @@ class SlottedRenderObjectElement<S> extends RenderObjectElement {
@override @override
void forgetChild(Element child) { void forgetChild(Element child) {
assert(_slotToChild.containsValue(child)); assert(_slotToChild.containsValue(child));
assert(child.slot is S); assert(child.slot is SlotType);
assert(_slotToChild.containsKey(child.slot)); assert(_slotToChild.containsKey(child.slot));
_slotToChild.remove(child.slot); _slotToChild.remove(child.slot);
super.forgetChild(child); super.forgetChild(child);
...@@ -225,16 +250,16 @@ class SlottedRenderObjectElement<S> extends RenderObjectElement { ...@@ -225,16 +250,16 @@ class SlottedRenderObjectElement<S> extends RenderObjectElement {
} }
@override @override
void update(SlottedMultiChildRenderObjectWidgetMixin<S> newWidget) { void update(SlottedMultiChildRenderObjectWidgetMixin<SlotType, ChildType> newWidget) {
super.update(newWidget); super.update(newWidget);
assert(widget == newWidget); assert(widget == newWidget);
_updateChildren(); _updateChildren();
} }
List<S>? _debugPreviousSlots; List<SlotType>? _debugPreviousSlots;
void _updateChildren() { void _updateChildren() {
final SlottedMultiChildRenderObjectWidgetMixin<S> slottedMultiChildRenderObjectWidgetMixin = widget as SlottedMultiChildRenderObjectWidgetMixin<S>; final SlottedMultiChildRenderObjectWidgetMixin<SlotType, ChildType> slottedMultiChildRenderObjectWidgetMixin = widget as SlottedMultiChildRenderObjectWidgetMixin<SlotType, ChildType>;
assert(() { assert(() {
_debugPreviousSlots ??= slottedMultiChildRenderObjectWidgetMixin.slots.toList(); _debugPreviousSlots ??= slottedMultiChildRenderObjectWidgetMixin.slots.toList();
return listEquals(_debugPreviousSlots, slottedMultiChildRenderObjectWidgetMixin.slots.toList()); return listEquals(_debugPreviousSlots, slottedMultiChildRenderObjectWidgetMixin.slots.toList());
...@@ -243,12 +268,12 @@ class SlottedRenderObjectElement<S> extends RenderObjectElement { ...@@ -243,12 +268,12 @@ class SlottedRenderObjectElement<S> extends RenderObjectElement {
final Map<Key, Element> oldKeyedElements = _keyedChildren; final Map<Key, Element> oldKeyedElements = _keyedChildren;
_keyedChildren = <Key, Element>{}; _keyedChildren = <Key, Element>{};
final Map<S, Element> oldSlotToChild = _slotToChild; final Map<SlotType, Element> oldSlotToChild = _slotToChild;
_slotToChild = <S, Element>{}; _slotToChild = <SlotType, Element>{};
Map<Key, List<Element>>? debugDuplicateKeys; Map<Key, List<Element>>? debugDuplicateKeys;
for (final S slot in slottedMultiChildRenderObjectWidgetMixin.slots) { for (final SlotType slot in slottedMultiChildRenderObjectWidgetMixin.slots) {
final Widget? widget = slottedMultiChildRenderObjectWidgetMixin.childForSlot(slot); final Widget? widget = slottedMultiChildRenderObjectWidgetMixin.childForSlot(slot);
final Key? newWidgetKey = widget?.key; final Key? newWidgetKey = widget?.key;
...@@ -259,7 +284,7 @@ class SlottedRenderObjectElement<S> extends RenderObjectElement { ...@@ -259,7 +284,7 @@ class SlottedRenderObjectElement<S> extends RenderObjectElement {
// If key matching fails, resort to `oldSlotChild` from the same slot. // If key matching fails, resort to `oldSlotChild` from the same slot.
final Element? fromElement; final Element? fromElement;
if (oldKeyChild != null) { if (oldKeyChild != null) {
fromElement = oldSlotToChild.remove(oldKeyChild.slot as S); fromElement = oldSlotToChild.remove(oldKeyChild.slot as SlotType);
} else if (oldSlotChild?.widget.key == null) { } else if (oldSlotChild?.widget.key == null) {
fromElement = oldSlotToChild.remove(slot); fromElement = oldSlotToChild.remove(slot);
} else { } else {
...@@ -311,13 +336,13 @@ class SlottedRenderObjectElement<S> extends RenderObjectElement { ...@@ -311,13 +336,13 @@ class SlottedRenderObjectElement<S> extends RenderObjectElement {
} }
@override @override
void insertRenderObjectChild(RenderBox child, S slot) { void insertRenderObjectChild(ChildType child, SlotType slot) {
renderObject._setChild(child, slot); renderObject._setChild(child, slot);
assert(renderObject._slotToChild[slot] == child); assert(renderObject._slotToChild[slot] == child);
} }
@override @override
void removeRenderObjectChild(RenderBox child, S slot) { void removeRenderObjectChild(ChildType child, SlotType slot) {
if (renderObject._slotToChild[slot] == child) { if (renderObject._slotToChild[slot] == child) {
renderObject._setChild(null, slot); renderObject._setChild(null, slot);
assert(renderObject._slotToChild[slot] == null); assert(renderObject._slotToChild[slot] == null);
...@@ -325,7 +350,7 @@ class SlottedRenderObjectElement<S> extends RenderObjectElement { ...@@ -325,7 +350,7 @@ class SlottedRenderObjectElement<S> extends RenderObjectElement {
} }
@override @override
void moveRenderObjectChild(RenderBox child, S oldSlot, S newSlot) { void moveRenderObjectChild(ChildType child, SlotType oldSlot, SlotType newSlot) {
renderObject._moveChild(child, newSlot, oldSlot); renderObject._moveChild(child, newSlot, oldSlot);
} }
} }
...@@ -269,7 +269,7 @@ enum _DiagonalSlot { ...@@ -269,7 +269,7 @@ enum _DiagonalSlot {
bottomRight, bottomRight,
} }
class _Diagonal extends RenderObjectWidget with SlottedMultiChildRenderObjectWidgetMixin<_DiagonalSlot?> { class _Diagonal extends RenderObjectWidget with SlottedMultiChildRenderObjectWidgetMixin<_DiagonalSlot?, RenderBox> {
const _Diagonal({ const _Diagonal({
this.topLeft, this.topLeft,
this.bottomRight, this.bottomRight,
...@@ -296,14 +296,14 @@ class _Diagonal extends RenderObjectWidget with SlottedMultiChildRenderObjectWid ...@@ -296,14 +296,14 @@ class _Diagonal extends RenderObjectWidget with SlottedMultiChildRenderObjectWid
} }
@override @override
SlottedContainerRenderObjectMixin<_DiagonalSlot?> createRenderObject( SlottedContainerRenderObjectMixin<_DiagonalSlot?, RenderBox> createRenderObject(
BuildContext context, BuildContext context,
) { ) {
return _RenderDiagonal(); return _RenderDiagonal();
} }
} }
class _RenderDiagonal extends RenderBox with SlottedContainerRenderObjectMixin<_DiagonalSlot?> { class _RenderDiagonal extends RenderBox with SlottedContainerRenderObjectMixin<_DiagonalSlot?, RenderBox> {
RenderBox? get _topLeft => childForSlot(_DiagonalSlot.topLeft); RenderBox? get _topLeft => childForSlot(_DiagonalSlot.topLeft);
RenderBox? get _bottomRight => childForSlot(_DiagonalSlot.bottomRight); RenderBox? get _bottomRight => childForSlot(_DiagonalSlot.bottomRight);
RenderBox? get _nullSlot => childForSlot(null); RenderBox? get _nullSlot => childForSlot(null);
...@@ -370,6 +370,6 @@ class _Slot { ...@@ -370,6 +370,6 @@ class _Slot {
String toString() => describeIdentity(this); String toString() => describeIdentity(this);
} }
class _RenderTest extends RenderBox with SlottedContainerRenderObjectMixin<_Slot> { class _RenderTest extends RenderBox with SlottedContainerRenderObjectMixin<_Slot, RenderBox> {
String publicNameForSlot(_Slot slot) => debugNameForSlot(slot); String publicNameForSlot(_Slot slot) => debugNameForSlot(slot);
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment