feat: pass BuildContext to NodeWidgetBuilder

This commit is contained in:
Lucas.Xu 2022-07-13 10:51:05 +08:00
parent 88f73bfbd4
commit 05786d1255
5 changed files with 55 additions and 30 deletions

View File

@ -88,8 +88,11 @@ class _MyHomePageState extends State<MyHomePage> {
} else {
final data = Map<String, Object>.from(json.decode(snapshot.data!));
final stateTree = StateTree.fromJson(data);
return renderPlugins.buildWidgetWithNode(
stateTree.root,
return renderPlugins.buildWidget(
NodeWidgetContext(
buildContext: context,
node: stateTree.root,
),
);
}
},

View File

@ -8,14 +8,26 @@ class ImageNodeBuilder extends NodeWidgetBuilder {
String get src => node.attributes['image_src'] as String;
@override
Widget build() {
final childrenWidget = buildChildren();
Widget build(BuildContext buildContext) {
final image = Image.network(src);
if (childrenWidget != null) {
Widget? children;
if (node.children.isNotEmpty) {
children = Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: node.children
.map(
(e) => renderPlugins.buildWidget(
NodeWidgetContext(buildContext: buildContext, node: e),
),
)
.toList(),
);
}
if (children != null) {
return Column(
children: [
image,
childrenWidget,
children,
],
);
} else {

View File

@ -8,19 +8,33 @@ class TextNodeBuilder extends NodeWidgetBuilder {
String get content => node.attributes['content'] as String;
@override
Widget build() {
final childrenWidget = buildChildren();
Widget build(BuildContext buildContext) {
final richText = SelectableText.rich(
TextSpan(
text: node.attributes['content'] as String,
style: node.attributes.toTextStyle(),
),
);
if (childrenWidget != null) {
Widget? children;
if (node.children.isNotEmpty) {
children = Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: node.children
.map(
(e) => renderPlugins.buildWidget(
NodeWidgetContext(buildContext: buildContext, node: e),
),
)
.toList(),
);
}
if (children != null) {
return Column(
children: [
richText,
childrenWidget,
children,
],
);
} else {

View File

@ -9,21 +9,9 @@ class NodeWidgetBuilder<T extends Node> {
NodeWidgetBuilder.create({required this.node, required this.renderPlugins});
Widget call() => build();
Widget build() => throw UnimplementedError();
Widget? buildChildren() {
if (node.children.isEmpty) {
return null;
}
Widget call(BuildContext buildContext) => build(buildContext);
// default layout
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: node.children
.map(
(e) => renderPlugins.buildWidgetWithNode(e),
)
.toList(),
);
}
/// Render the current [Node]
/// and the layout style of [Node.Children].
Widget build(BuildContext buildContext) => throw UnimplementedError();
}

View File

@ -2,6 +2,12 @@ import 'package:flutter/material.dart';
import '../document/node.dart';
import 'node_widget_builder.dart';
class NodeWidgetContext {
BuildContext buildContext;
Node node;
NodeWidgetContext({required this.buildContext, required this.node});
}
typedef NodeWidgetBuilderF<T extends Node, A extends NodeWidgetBuilder> = A
Function({
required T node,
@ -28,13 +34,15 @@ class RenderPlugins {
nodeWidgetBuilders.removeWhere((key, _) => key == name);
}
Widget buildWidgetWithNode(Node node) {
final nodeWidgetBuilder = _nodeWidgetBuilder(node.type);
return nodeWidgetBuilder(node: node, renderPlugins: this)();
Widget buildWidget(NodeWidgetContext context) {
final nodeWidgetBuilder = _nodeWidgetBuilder(context.node.type);
return nodeWidgetBuilder(node: context.node, renderPlugins: this)(
context.buildContext);
}
NodeWidgetBuilderF _nodeWidgetBuilder(String name) {
assert(nodeWidgetBuilders.containsKey(name));
assert(nodeWidgetBuilders.containsKey(name),
'Could not query the builder with this $name');
return nodeWidgetBuilders[name]!;
}
}