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...
This commit is contained in:
parent
5235a0f092
commit
027bb84444
@ -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 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// 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
|
|||||||
// [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
|
|||||||
@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
|
|||||||
/// [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 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
|||||||
}
|
}
|
||||||
|
|
||||||
@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 {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
|||||||
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
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
|||||||
///
|
///
|
||||||
/// * [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 {
|
|||||||
/// * [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';
|
|||||||
|
|
||||||
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';
|
|||||||
/// 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';
|
|||||||
///
|
///
|
||||||
/// * [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 {
|
|||||||
/// 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 {
|
|||||||
/// 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.
|
||||||
///
|
///
|
||||||
/// See [SlottedMultiChildRenderObjectWidgetMixin] for example code showcasing
|
/// The type parameter `ChildType` is the type of [RenderObject] used for the children
|
||||||
/// how this mixin is used in combination with the
|
/// (e.g. [RenderBox] or [RenderSliver]). In the typical case, `ChildType` is
|
||||||
/// [SlottedMultiChildRenderObjectWidgetMixin].
|
/// [RenderBox]. This mixin does not support having different kinds of children
|
||||||
|
/// for different slots.
|
||||||
|
///
|
||||||
|
/// See [SlottedMultiChildRenderObjectWidget] for example code showcasing how
|
||||||
|
/// this mixin is used in combination with [SlottedMultiChildRenderObjectWidget].
|
||||||
///
|
///
|
||||||
/// 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 {
|
|||||||
/// 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 {
|
|||||||
@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 {
|
|||||||
@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 {
|
|||||||
@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 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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 {
|
|||||||
@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 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@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 {
|
|||||||
|
|
||||||
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 {
|
|||||||
// 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 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@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 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@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 {
|
|||||||
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
|
|||||||
}
|
}
|
||||||
|
|
||||||
@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 {
|
|||||||
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);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user