Support data types other than dynamic
This commit is contained in:
parent
6d8b63618b
commit
734a06452f
5 changed files with 102 additions and 98 deletions
|
@ -33,7 +33,7 @@ class Node<T> {
|
||||||
final T? data;
|
final T? data;
|
||||||
|
|
||||||
/// The sub [Node]s of this object.
|
/// The sub [Node]s of this object.
|
||||||
final List<Node> children;
|
final List<Node<T>> children;
|
||||||
|
|
||||||
/// Force the node to be a parent so that node can show expander without
|
/// Force the node to be a parent so that node can show expander without
|
||||||
/// having children node.
|
/// having children node.
|
||||||
|
@ -52,7 +52,7 @@ class Node<T> {
|
||||||
/// Creates a [Node] from a string value. It generates a unique key.
|
/// Creates a [Node] from a string value. It generates a unique key.
|
||||||
factory Node.fromLabel(String label) {
|
factory Node.fromLabel(String label) {
|
||||||
String _key = Utilities.generateRandom();
|
String _key = Utilities.generateRandom();
|
||||||
return Node(
|
return Node<T>(
|
||||||
key: '${_key}_$label',
|
key: '${_key}_$label',
|
||||||
label: label,
|
label: label,
|
||||||
);
|
);
|
||||||
|
@ -68,7 +68,7 @@ class Node<T> {
|
||||||
String? _key = map['key'];
|
String? _key = map['key'];
|
||||||
String _label = map['label'];
|
String _label = map['label'];
|
||||||
var _data = map['data'];
|
var _data = map['data'];
|
||||||
List<Node> _children = [];
|
List<Node<T>> _children = [];
|
||||||
if (_key == null) {
|
if (_key == null) {
|
||||||
_key = Utilities.generateRandom();
|
_key = Utilities.generateRandom();
|
||||||
}
|
}
|
||||||
|
@ -86,10 +86,10 @@ class Node<T> {
|
||||||
if (map['children'] != null) {
|
if (map['children'] != null) {
|
||||||
List<Map<String, dynamic>> _childrenMap = List.from(map['children']);
|
List<Map<String, dynamic>> _childrenMap = List.from(map['children']);
|
||||||
_children = _childrenMap
|
_children = _childrenMap
|
||||||
.map((Map<String, dynamic> child) => Node.fromMap(child))
|
.map((Map<String, dynamic> child) => Node<T>.fromMap(child))
|
||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
return Node(
|
return Node<T>(
|
||||||
key: '$_key',
|
key: '$_key',
|
||||||
label: _label,
|
label: _label,
|
||||||
data: _data,
|
data: _data,
|
||||||
|
@ -101,16 +101,16 @@ class Node<T> {
|
||||||
|
|
||||||
/// Creates a copy of this object but with the given fields
|
/// Creates a copy of this object but with the given fields
|
||||||
/// replaced with the new values.
|
/// replaced with the new values.
|
||||||
Node copyWith({
|
Node<T> copyWith({
|
||||||
String? key,
|
String? key,
|
||||||
String? label,
|
String? label,
|
||||||
List<Node>? children,
|
List<Node<T>>? children,
|
||||||
bool? expanded,
|
bool? expanded,
|
||||||
bool? parent,
|
bool? parent,
|
||||||
IconData? icon,
|
IconData? icon,
|
||||||
T? data,
|
T? data,
|
||||||
}) =>
|
}) =>
|
||||||
Node(
|
Node<T>(
|
||||||
key: key ?? this.key,
|
key: key ?? this.key,
|
||||||
label: label ?? this.label,
|
label: label ?? this.label,
|
||||||
icon: icon ?? this.icon,
|
icon: icon ?? this.icon,
|
||||||
|
@ -167,7 +167,7 @@ class Node<T> {
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
if (identical(this, other)) return true;
|
if (identical(this, other)) return true;
|
||||||
if (other.runtimeType != runtimeType) return false;
|
if (other.runtimeType != runtimeType) return false;
|
||||||
return other is Node &&
|
return other is Node<T> &&
|
||||||
other.key == key &&
|
other.key == key &&
|
||||||
other.label == label &&
|
other.label == label &&
|
||||||
other.icon == icon &&
|
other.icon == icon &&
|
||||||
|
|
|
@ -19,17 +19,17 @@ const double _kBorderWidth = 0.75;
|
||||||
/// __This class should not be used directly!__
|
/// __This class should not be used directly!__
|
||||||
/// The [TreeView] and [TreeViewController] handlers the data and rendering
|
/// The [TreeView] and [TreeViewController] handlers the data and rendering
|
||||||
/// of the nodes.
|
/// of the nodes.
|
||||||
class TreeNode extends StatefulWidget {
|
class TreeNode<T> extends StatefulWidget {
|
||||||
/// The node object used to display the widget state
|
/// The node object used to display the widget state
|
||||||
final Node node;
|
final Node<T> node;
|
||||||
|
|
||||||
const TreeNode({Key? key, required this.node}) : super(key: key);
|
const TreeNode({Key? key, required this.node}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_TreeNodeState createState() => _TreeNodeState();
|
_TreeNodeState<T> createState() => _TreeNodeState<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _TreeNodeState extends State<TreeNode>
|
class _TreeNodeState<T> extends State<TreeNode<T>>
|
||||||
with SingleTickerProviderStateMixin {
|
with SingleTickerProviderStateMixin {
|
||||||
static final Animatable<double> _easeInTween =
|
static final Animatable<double> _easeInTween =
|
||||||
CurveTween(curve: Curves.easeIn);
|
CurveTween(curve: Curves.easeIn);
|
||||||
|
@ -51,8 +51,10 @@ class _TreeNodeState extends State<TreeNode>
|
||||||
@override
|
@override
|
||||||
void didChangeDependencies() {
|
void didChangeDependencies() {
|
||||||
super.didChangeDependencies();
|
super.didChangeDependencies();
|
||||||
TreeView? _treeView = TreeView.of(context);
|
TreeView<T>? _treeView = TreeView.of<T>(context);
|
||||||
_controller.duration = _treeView!.theme.expandSpeed;
|
if (_treeView != null) {
|
||||||
|
_controller.duration = _treeView.theme.expandSpeed;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -62,7 +64,7 @@ class _TreeNodeState extends State<TreeNode>
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void didUpdateWidget(TreeNode oldWidget) {
|
void didUpdateWidget(TreeNode<T> oldWidget) {
|
||||||
if (widget.node.expanded != oldWidget.node.expanded) {
|
if (widget.node.expanded != oldWidget.node.expanded) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_isExpanded = widget.node.expanded;
|
_isExpanded = widget.node.expanded;
|
||||||
|
@ -82,7 +84,7 @@ class _TreeNodeState extends State<TreeNode>
|
||||||
}
|
}
|
||||||
|
|
||||||
void _handleExpand() {
|
void _handleExpand() {
|
||||||
TreeView? _treeView = TreeView.of(context);
|
TreeView<T>? _treeView = TreeView.of<T>(context);
|
||||||
assert(_treeView != null, 'TreeView must exist in context');
|
assert(_treeView != null, 'TreeView must exist in context');
|
||||||
setState(() {
|
setState(() {
|
||||||
_isExpanded = !_isExpanded;
|
_isExpanded = !_isExpanded;
|
||||||
|
@ -100,7 +102,7 @@ class _TreeNodeState extends State<TreeNode>
|
||||||
}
|
}
|
||||||
|
|
||||||
void _handleTap() {
|
void _handleTap() {
|
||||||
TreeView? _treeView = TreeView.of(context);
|
TreeView<T>? _treeView = TreeView.of<T>(context);
|
||||||
assert(_treeView != null, 'TreeView must exist in context');
|
assert(_treeView != null, 'TreeView must exist in context');
|
||||||
if (_treeView!.onNodeTap != null) {
|
if (_treeView!.onNodeTap != null) {
|
||||||
_treeView.onNodeTap!(widget.node.key);
|
_treeView.onNodeTap!(widget.node.key);
|
||||||
|
@ -108,7 +110,7 @@ class _TreeNodeState extends State<TreeNode>
|
||||||
}
|
}
|
||||||
|
|
||||||
void _handleDoubleTap() {
|
void _handleDoubleTap() {
|
||||||
TreeView? _treeView = TreeView.of(context);
|
TreeView<T>? _treeView = TreeView.of<T>(context);
|
||||||
assert(_treeView != null, 'TreeView must exist in context');
|
assert(_treeView != null, 'TreeView must exist in context');
|
||||||
if (_treeView!.onNodeDoubleTap != null) {
|
if (_treeView!.onNodeDoubleTap != null) {
|
||||||
_treeView.onNodeDoubleTap!(widget.node.key);
|
_treeView.onNodeDoubleTap!(widget.node.key);
|
||||||
|
@ -116,7 +118,7 @@ class _TreeNodeState extends State<TreeNode>
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildNodeExpander() {
|
Widget _buildNodeExpander() {
|
||||||
TreeView? _treeView = TreeView.of(context);
|
TreeView<T>? _treeView = TreeView.of<T>(context);
|
||||||
assert(_treeView != null, 'TreeView must exist in context');
|
assert(_treeView != null, 'TreeView must exist in context');
|
||||||
TreeViewTheme _theme = _treeView!.theme;
|
TreeViewTheme _theme = _treeView!.theme;
|
||||||
return widget.node.isParent
|
return widget.node.isParent
|
||||||
|
@ -132,7 +134,7 @@ class _TreeNodeState extends State<TreeNode>
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildNodeIcon() {
|
Widget _buildNodeIcon() {
|
||||||
TreeView? _treeView = TreeView.of(context);
|
TreeView<T>? _treeView = TreeView.of<T>(context);
|
||||||
assert(_treeView != null, 'TreeView must exist in context');
|
assert(_treeView != null, 'TreeView must exist in context');
|
||||||
TreeViewTheme _theme = _treeView!.theme;
|
TreeViewTheme _theme = _treeView!.theme;
|
||||||
bool isSelected = _treeView.controller.selectedKey != null &&
|
bool isSelected = _treeView.controller.selectedKey != null &&
|
||||||
|
@ -154,7 +156,7 @@ class _TreeNodeState extends State<TreeNode>
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildNodeLabel() {
|
Widget _buildNodeLabel() {
|
||||||
TreeView? _treeView = TreeView.of(context);
|
TreeView<T>? _treeView = TreeView.of<T>(context);
|
||||||
assert(_treeView != null, 'TreeView must exist in context');
|
assert(_treeView != null, 'TreeView must exist in context');
|
||||||
TreeViewTheme _theme = _treeView!.theme;
|
TreeViewTheme _theme = _treeView!.theme;
|
||||||
bool isSelected = _treeView.controller.selectedKey != null &&
|
bool isSelected = _treeView.controller.selectedKey != null &&
|
||||||
|
@ -198,7 +200,7 @@ class _TreeNodeState extends State<TreeNode>
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildNodeWidget() {
|
Widget _buildNodeWidget() {
|
||||||
TreeView? _treeView = TreeView.of(context);
|
TreeView<T>? _treeView = TreeView.of<T>(context);
|
||||||
assert(_treeView != null, 'TreeView must exist in context');
|
assert(_treeView != null, 'TreeView must exist in context');
|
||||||
TreeViewTheme _theme = _treeView!.theme;
|
TreeViewTheme _theme = _treeView!.theme;
|
||||||
bool isSelected = _treeView.controller.selectedKey != null &&
|
bool isSelected = _treeView.controller.selectedKey != null &&
|
||||||
|
@ -265,7 +267,7 @@ class _TreeNodeState extends State<TreeNode>
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
TreeView? _treeView = TreeView.of(context);
|
TreeView<T>? _treeView = TreeView.of<T>(context);
|
||||||
assert(_treeView != null, 'TreeView must exist in context');
|
assert(_treeView != null, 'TreeView must exist in context');
|
||||||
final bool closed =
|
final bool closed =
|
||||||
(!_isExpanded || !widget.node.expanded) && _controller.isDismissed;
|
(!_isExpanded || !widget.node.expanded) && _controller.isDismissed;
|
||||||
|
@ -295,8 +297,8 @@ class _TreeNodeState extends State<TreeNode>
|
||||||
_treeView.theme.iconTheme.size!),
|
_treeView.theme.iconTheme.size!),
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: widget.node.children.map((Node node) {
|
children: widget.node.children.map((Node<T> node) {
|
||||||
return TreeNode(node: node);
|
return TreeNode<T>(node: node);
|
||||||
}).toList()),
|
}).toList()),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
|
@ -25,15 +25,15 @@ import 'models/node.dart';
|
||||||
/// theme: treeViewTheme
|
/// theme: treeViewTheme
|
||||||
/// ),
|
/// ),
|
||||||
/// ```
|
/// ```
|
||||||
class TreeView extends InheritedWidget {
|
class TreeView<T> extends InheritedWidget {
|
||||||
/// The controller for the [TreeView]. It manages the data and selected key.
|
/// The controller for the [TreeView]. It manages the data and selected key.
|
||||||
final TreeViewController controller;
|
final TreeViewController<T> controller;
|
||||||
|
|
||||||
/// The tap handler for a node. Passes the node key.
|
/// The tap handler for a node. Passes the node key.
|
||||||
final Function(String)? onNodeTap;
|
final Function(String)? onNodeTap;
|
||||||
|
|
||||||
/// Custom builder for nodes. Parameters are the build context and tree node.
|
/// Custom builder for nodes. Parameters are the build context and tree node.
|
||||||
final Widget Function(BuildContext, Node)? nodeBuilder;
|
final Widget Function(BuildContext, Node<T>)? nodeBuilder;
|
||||||
|
|
||||||
/// The double tap handler for a node. Passes the node key.
|
/// The double tap handler for a node. Passes the node key.
|
||||||
final Function(String)? onNodeDoubleTap;
|
final Function(String)? onNodeDoubleTap;
|
||||||
|
@ -92,7 +92,7 @@ class TreeView extends InheritedWidget {
|
||||||
}) : this.theme = theme ?? const TreeViewTheme(),
|
}) : this.theme = theme ?? const TreeViewTheme(),
|
||||||
super(
|
super(
|
||||||
key: key,
|
key: key,
|
||||||
child: _TreeViewData(
|
child: _TreeViewData<T>(
|
||||||
controller,
|
controller,
|
||||||
shrinkWrap: shrinkWrap,
|
shrinkWrap: shrinkWrap,
|
||||||
primary: primary,
|
primary: primary,
|
||||||
|
@ -100,7 +100,7 @@ class TreeView extends InheritedWidget {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
static TreeView? of(BuildContext context) =>
|
static TreeView<T>? of<T>(BuildContext context) =>
|
||||||
context.dependOnInheritedWidgetOfExactType(aspect: TreeView);
|
context.dependOnInheritedWidgetOfExactType(aspect: TreeView);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -114,8 +114,8 @@ class TreeView extends InheritedWidget {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _TreeViewData extends StatelessWidget {
|
class _TreeViewData<T> extends StatelessWidget {
|
||||||
final TreeViewController _controller;
|
final TreeViewController<T> _controller;
|
||||||
final bool? shrinkWrap;
|
final bool? shrinkWrap;
|
||||||
final bool? primary;
|
final bool? primary;
|
||||||
final ScrollPhysics? physics;
|
final ScrollPhysics? physics;
|
||||||
|
@ -133,8 +133,8 @@ class _TreeViewData extends StatelessWidget {
|
||||||
primary: primary,
|
primary: primary,
|
||||||
physics: physics,
|
physics: physics,
|
||||||
padding: EdgeInsets.zero,
|
padding: EdgeInsets.zero,
|
||||||
children: _controller.children.map((Node node) {
|
children: _controller.children.map<TreeNode<T>>((Node<T> node) {
|
||||||
return TreeNode(node: node);
|
return TreeNode<T>(node: node);
|
||||||
}).toList(),
|
}).toList(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -30,9 +30,9 @@ enum InsertMode {
|
||||||
/// List<Node> newChildren = controller.updateNode(node.key, updatedNode);
|
/// List<Node> newChildren = controller.updateNode(node.key, updatedNode);
|
||||||
/// controller = TreeViewController(children: newChildren);
|
/// controller = TreeViewController(children: newChildren);
|
||||||
/// ```
|
/// ```
|
||||||
class TreeViewController {
|
class TreeViewController<T> {
|
||||||
/// The data for the [TreeView].
|
/// The data for the [TreeView].
|
||||||
final List<Node> children;
|
final List<Node<T>> children;
|
||||||
|
|
||||||
/// The key of the select node in the [TreeView].
|
/// The key of the select node in the [TreeView].
|
||||||
final String? selectedKey;
|
final String? selectedKey;
|
||||||
|
@ -44,8 +44,9 @@ class TreeViewController {
|
||||||
|
|
||||||
/// Creates a copy of this controller but with the given fields
|
/// Creates a copy of this controller but with the given fields
|
||||||
/// replaced with the new values.
|
/// replaced with the new values.
|
||||||
TreeViewController copyWith({List<Node>? children, String? selectedKey}) {
|
TreeViewController<T> copyWith(
|
||||||
return TreeViewController(
|
{List<Node<T>>? children, String? selectedKey}) {
|
||||||
|
return TreeViewController<T>(
|
||||||
children: children ?? this.children,
|
children: children ?? this.children,
|
||||||
selectedKey: selectedKey ?? this.selectedKey,
|
selectedKey: selectedKey ?? this.selectedKey,
|
||||||
);
|
);
|
||||||
|
@ -74,8 +75,8 @@ class TreeViewController {
|
||||||
/// });
|
/// });
|
||||||
/// ```
|
/// ```
|
||||||
TreeViewController loadMap({List<Map<String, dynamic>> list: const []}) {
|
TreeViewController loadMap({List<Map<String, dynamic>> list: const []}) {
|
||||||
List<Node> treeData =
|
List<Node<T>> treeData =
|
||||||
list.map((Map<String, dynamic> item) => Node.fromMap(item)).toList();
|
list.map((Map<String, dynamic> item) => Node<T>.fromMap(item)).toList();
|
||||||
return TreeViewController(
|
return TreeViewController(
|
||||||
children: treeData,
|
children: treeData,
|
||||||
selectedKey: this.selectedKey,
|
selectedKey: this.selectedKey,
|
||||||
|
@ -96,12 +97,12 @@ class TreeViewController {
|
||||||
/// ```
|
/// ```
|
||||||
TreeViewController withAddNode(
|
TreeViewController withAddNode(
|
||||||
String key,
|
String key,
|
||||||
Node newNode, {
|
Node<T> newNode, {
|
||||||
Node? parent,
|
Node<T>? parent,
|
||||||
int? index,
|
int? index,
|
||||||
InsertMode mode: InsertMode.append,
|
InsertMode mode: InsertMode.append,
|
||||||
}) {
|
}) {
|
||||||
List<Node> _data =
|
List<Node<T>> _data =
|
||||||
addNode(key, newNode, parent: parent, mode: mode, index: index);
|
addNode(key, newNode, parent: parent, mode: mode, index: index);
|
||||||
return TreeViewController(
|
return TreeViewController(
|
||||||
children: _data,
|
children: _data,
|
||||||
|
@ -121,8 +122,9 @@ class TreeViewController {
|
||||||
/// controller = controller.withUpdateNode(key, newNode);
|
/// controller = controller.withUpdateNode(key, newNode);
|
||||||
/// });
|
/// });
|
||||||
/// ```
|
/// ```
|
||||||
TreeViewController withUpdateNode(String key, Node newNode, {Node? parent}) {
|
TreeViewController<T> withUpdateNode(String key, Node<T> newNode,
|
||||||
List<Node> _data = updateNode(key, newNode, parent: parent);
|
{Node<T>? parent}) {
|
||||||
|
List<Node<T>> _data = updateNode(key, newNode, parent: parent);
|
||||||
return TreeViewController(
|
return TreeViewController(
|
||||||
children: _data,
|
children: _data,
|
||||||
selectedKey: this.selectedKey,
|
selectedKey: this.selectedKey,
|
||||||
|
@ -141,8 +143,8 @@ class TreeViewController {
|
||||||
/// controller = controller.withDeleteNode(key);
|
/// controller = controller.withDeleteNode(key);
|
||||||
/// });
|
/// });
|
||||||
/// ```
|
/// ```
|
||||||
TreeViewController withDeleteNode(String key, {Node? parent}) {
|
TreeViewController<T> withDeleteNode(String key, {Node<T>? parent}) {
|
||||||
List<Node> _data = deleteNode(key, parent: parent);
|
List<Node<T>> _data = deleteNode(key, parent: parent);
|
||||||
return TreeViewController(
|
return TreeViewController(
|
||||||
children: _data,
|
children: _data,
|
||||||
selectedKey: this.selectedKey,
|
selectedKey: this.selectedKey,
|
||||||
|
@ -161,8 +163,8 @@ class TreeViewController {
|
||||||
/// controller = controller.withToggleNode(key, newNode);
|
/// controller = controller.withToggleNode(key, newNode);
|
||||||
/// });
|
/// });
|
||||||
/// ```
|
/// ```
|
||||||
TreeViewController withToggleNode(String key, {Node? parent}) {
|
TreeViewController withToggleNode(String key, {Node<T>? parent}) {
|
||||||
List<Node> _data = toggleNode(key, parent: parent);
|
List<Node<T>> _data = toggleNode(key, parent: parent);
|
||||||
return TreeViewController(
|
return TreeViewController(
|
||||||
children: _data,
|
children: _data,
|
||||||
selectedKey: this.selectedKey,
|
selectedKey: this.selectedKey,
|
||||||
|
@ -182,7 +184,7 @@ class TreeViewController {
|
||||||
/// });
|
/// });
|
||||||
/// ```
|
/// ```
|
||||||
TreeViewController withExpandToNode(String key) {
|
TreeViewController withExpandToNode(String key) {
|
||||||
List<Node> _data = expandToNode(key);
|
List<Node<T>> _data = expandToNode(key);
|
||||||
return TreeViewController(
|
return TreeViewController(
|
||||||
children: _data,
|
children: _data,
|
||||||
selectedKey: this.selectedKey,
|
selectedKey: this.selectedKey,
|
||||||
|
@ -202,7 +204,7 @@ class TreeViewController {
|
||||||
/// });
|
/// });
|
||||||
/// ```
|
/// ```
|
||||||
TreeViewController withCollapseToNode(String key) {
|
TreeViewController withCollapseToNode(String key) {
|
||||||
List<Node> _data = collapseToNode(key);
|
List<Node<T>> _data = collapseToNode(key);
|
||||||
return TreeViewController(
|
return TreeViewController(
|
||||||
children: _data,
|
children: _data,
|
||||||
selectedKey: this.selectedKey,
|
selectedKey: this.selectedKey,
|
||||||
|
@ -221,8 +223,8 @@ class TreeViewController {
|
||||||
/// controller = controller.withExpandAll();
|
/// controller = controller.withExpandAll();
|
||||||
/// });
|
/// });
|
||||||
/// ```
|
/// ```
|
||||||
TreeViewController withExpandAll({Node? parent}) {
|
TreeViewController withExpandAll({Node<T>? parent}) {
|
||||||
List<Node> _data = expandAll(parent: parent);
|
List<Node<T>> _data = expandAll(parent: parent);
|
||||||
return TreeViewController(
|
return TreeViewController(
|
||||||
children: _data,
|
children: _data,
|
||||||
selectedKey: this.selectedKey,
|
selectedKey: this.selectedKey,
|
||||||
|
@ -241,8 +243,8 @@ class TreeViewController {
|
||||||
/// controller = controller.withCollapseAll();
|
/// controller = controller.withCollapseAll();
|
||||||
/// });
|
/// });
|
||||||
/// ```
|
/// ```
|
||||||
TreeViewController withCollapseAll({Node? parent}) {
|
TreeViewController withCollapseAll({Node<T>? parent}) {
|
||||||
List<Node> _data = collapseAll(parent: parent);
|
List<Node<T>> _data = collapseAll(parent: parent);
|
||||||
return TreeViewController(
|
return TreeViewController(
|
||||||
children: _data,
|
children: _data,
|
||||||
selectedKey: this.selectedKey,
|
selectedKey: this.selectedKey,
|
||||||
|
@ -250,12 +252,12 @@ class TreeViewController {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the node that has a key value equal to the specified key.
|
/// Gets the node that has a key value equal to the specified key.
|
||||||
Node? getNode(String key, {Node? parent}) {
|
Node<T>? getNode(String key, {Node<T>? parent}) {
|
||||||
Node? _found;
|
Node<T>? _found;
|
||||||
List<Node> _children = parent == null ? this.children : parent.children;
|
List<Node<T>> _children = parent == null ? this.children : parent.children;
|
||||||
Iterator iter = _children.iterator;
|
Iterator iter = _children.iterator;
|
||||||
while (iter.moveNext()) {
|
while (iter.moveNext()) {
|
||||||
Node child = iter.current;
|
Node<T> child = iter.current;
|
||||||
if (child.key == key) {
|
if (child.key == key) {
|
||||||
_found = child;
|
_found = child;
|
||||||
break;
|
break;
|
||||||
|
@ -272,12 +274,12 @@ class TreeViewController {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Expands all node that are children of the parent node parameter. If no parent is passed, uses the root node as the parent.
|
/// Expands all node that are children of the parent node parameter. If no parent is passed, uses the root node as the parent.
|
||||||
List<Node> expandAll({Node? parent}) {
|
List<Node<T>> expandAll({Node<T>? parent}) {
|
||||||
List<Node> _children = [];
|
List<Node<T>> _children = [];
|
||||||
Iterator iter =
|
Iterator iter =
|
||||||
parent == null ? this.children.iterator : parent.children.iterator;
|
parent == null ? this.children.iterator : parent.children.iterator;
|
||||||
while (iter.moveNext()) {
|
while (iter.moveNext()) {
|
||||||
Node child = iter.current;
|
Node<T> child = iter.current;
|
||||||
if (child.isParent) {
|
if (child.isParent) {
|
||||||
_children.add(child.copyWith(
|
_children.add(child.copyWith(
|
||||||
expanded: true,
|
expanded: true,
|
||||||
|
@ -291,12 +293,12 @@ class TreeViewController {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Collapses all node that are children of the parent node parameter. If no parent is passed, uses the root node as the parent.
|
/// Collapses all node that are children of the parent node parameter. If no parent is passed, uses the root node as the parent.
|
||||||
List<Node> collapseAll({Node? parent}) {
|
List<Node<T>> collapseAll({Node<T>? parent}) {
|
||||||
List<Node> _children = [];
|
List<Node<T>> _children = [];
|
||||||
Iterator iter =
|
Iterator iter =
|
||||||
parent == null ? this.children.iterator : parent.children.iterator;
|
parent == null ? this.children.iterator : parent.children.iterator;
|
||||||
while (iter.moveNext()) {
|
while (iter.moveNext()) {
|
||||||
Node child = iter.current;
|
Node<T> child = iter.current;
|
||||||
if (child.isParent) {
|
if (child.isParent) {
|
||||||
_children.add(child.copyWith(
|
_children.add(child.copyWith(
|
||||||
expanded: false,
|
expanded: false,
|
||||||
|
@ -310,12 +312,12 @@ class TreeViewController {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the parent of the node identified by specified key.
|
/// Gets the parent of the node identified by specified key.
|
||||||
Node? getParent(String key, {Node? parent}) {
|
Node<T>? getParent(String key, {Node<T>? parent}) {
|
||||||
Node? _found;
|
Node<T>? _found;
|
||||||
List<Node> _children = parent == null ? this.children : parent.children;
|
List<Node<T>> _children = parent == null ? this.children : parent.children;
|
||||||
Iterator iter = _children.iterator;
|
Iterator iter = _children.iterator;
|
||||||
while (iter.moveNext()) {
|
while (iter.moveNext()) {
|
||||||
Node child = iter.current;
|
Node<T> child = iter.current;
|
||||||
if (child.key == key) {
|
if (child.key == key) {
|
||||||
_found = parent ?? child;
|
_found = parent ?? child;
|
||||||
break;
|
break;
|
||||||
|
@ -333,23 +335,23 @@ class TreeViewController {
|
||||||
|
|
||||||
/// Expands a node and all of the node's ancestors so that the node is
|
/// Expands a node and all of the node's ancestors so that the node is
|
||||||
/// visible without the need to manually expand each node.
|
/// visible without the need to manually expand each node.
|
||||||
List<Node> expandToNode(String key) {
|
List<Node<T>> expandToNode(String key) {
|
||||||
List<String> _ancestors = [];
|
List<String> _ancestors = [];
|
||||||
String _currentKey = key;
|
String _currentKey = key;
|
||||||
|
|
||||||
_ancestors.add(_currentKey);
|
_ancestors.add(_currentKey);
|
||||||
|
|
||||||
Node? _parent = this.getParent(_currentKey);
|
Node<T>? _parent = this.getParent(_currentKey);
|
||||||
if (_parent != null) {
|
if (_parent != null) {
|
||||||
while (_parent!.key != _currentKey) {
|
while (_parent!.key != _currentKey) {
|
||||||
_currentKey = _parent.key;
|
_currentKey = _parent.key;
|
||||||
_ancestors.add(_currentKey);
|
_ancestors.add(_currentKey);
|
||||||
_parent = this.getParent(_currentKey);
|
_parent = this.getParent(_currentKey);
|
||||||
}
|
}
|
||||||
TreeViewController _this = this;
|
TreeViewController<T> _this = this;
|
||||||
_ancestors.forEach((String k) {
|
_ancestors.forEach((String k) {
|
||||||
Node _node = _this.getNode(k)!;
|
Node<T> _node = _this.getNode(k)!;
|
||||||
Node _updated = _node.copyWith(expanded: true);
|
Node<T> _updated = _node.copyWith(expanded: true);
|
||||||
_this = _this.withUpdateNode(k, _updated);
|
_this = _this.withUpdateNode(k, _updated);
|
||||||
});
|
});
|
||||||
return _this.children;
|
return _this.children;
|
||||||
|
@ -359,23 +361,23 @@ class TreeViewController {
|
||||||
|
|
||||||
/// Collapses a node and all of the node's ancestors without the need to
|
/// Collapses a node and all of the node's ancestors without the need to
|
||||||
/// manually collapse each node.
|
/// manually collapse each node.
|
||||||
List<Node> collapseToNode(String key) {
|
List<Node<T>> collapseToNode(String key) {
|
||||||
List<String> _ancestors = [];
|
List<String> _ancestors = [];
|
||||||
String _currentKey = key;
|
String _currentKey = key;
|
||||||
|
|
||||||
_ancestors.add(_currentKey);
|
_ancestors.add(_currentKey);
|
||||||
|
|
||||||
Node? _parent = this.getParent(_currentKey);
|
Node<T>? _parent = this.getParent(_currentKey);
|
||||||
if (_parent != null) {
|
if (_parent != null) {
|
||||||
while (_parent!.key != _currentKey) {
|
while (_parent!.key != _currentKey) {
|
||||||
_currentKey = _parent.key;
|
_currentKey = _parent.key;
|
||||||
_ancestors.add(_currentKey);
|
_ancestors.add(_currentKey);
|
||||||
_parent = this.getParent(_currentKey);
|
_parent = this.getParent(_currentKey);
|
||||||
}
|
}
|
||||||
TreeViewController _this = this;
|
TreeViewController<T> _this = this;
|
||||||
_ancestors.forEach((String k) {
|
_ancestors.forEach((String k) {
|
||||||
Node _node = _this.getNode(k)!;
|
Node<T> _node = _this.getNode(k)!;
|
||||||
Node _updated = _node.copyWith(expanded: false);
|
Node<T> _updated = _node.copyWith(expanded: false);
|
||||||
_this = _this.withUpdateNode(k, _updated);
|
_this = _this.withUpdateNode(k, _updated);
|
||||||
});
|
});
|
||||||
return _this.children;
|
return _this.children;
|
||||||
|
@ -387,17 +389,17 @@ class TreeViewController {
|
||||||
/// accepts an [InsertMode] and index. If no [InsertMode] is specified,
|
/// accepts an [InsertMode] and index. If no [InsertMode] is specified,
|
||||||
/// it appends the new node as a child at the end. This method returns
|
/// it appends the new node as a child at the end. This method returns
|
||||||
/// a new list with the added node.
|
/// a new list with the added node.
|
||||||
List<Node> addNode(
|
List<Node<T>> addNode(
|
||||||
String key,
|
String key,
|
||||||
Node newNode, {
|
Node<T> newNode, {
|
||||||
Node? parent,
|
Node<T>? parent,
|
||||||
int? index,
|
int? index,
|
||||||
InsertMode mode: InsertMode.append,
|
InsertMode mode: InsertMode.append,
|
||||||
}) {
|
}) {
|
||||||
List<Node> _children = parent == null ? this.children : parent.children;
|
List<Node<T>> _children = parent == null ? this.children : parent.children;
|
||||||
return _children.map((Node child) {
|
return _children.map((Node<T> child) {
|
||||||
if (child.key == key) {
|
if (child.key == key) {
|
||||||
List<Node> _children = child.children.toList(growable: true);
|
List<Node<T>> _children = child.children.toList(growable: true);
|
||||||
if (mode == InsertMode.prepend) {
|
if (mode == InsertMode.prepend) {
|
||||||
_children.insert(0, newNode);
|
_children.insert(0, newNode);
|
||||||
} else if (mode == InsertMode.insert) {
|
} else if (mode == InsertMode.insert) {
|
||||||
|
@ -422,9 +424,9 @@ class TreeViewController {
|
||||||
|
|
||||||
/// Updates an existing node identified by specified key. This method
|
/// Updates an existing node identified by specified key. This method
|
||||||
/// returns a new list with the updated node.
|
/// returns a new list with the updated node.
|
||||||
List<Node> updateNode(String key, Node newNode, {Node? parent}) {
|
List<Node<T>> updateNode(String key, Node<T> newNode, {Node<T>? parent}) {
|
||||||
List<Node> _children = parent == null ? this.children : parent.children;
|
List<Node<T>> _children = parent == null ? this.children : parent.children;
|
||||||
return _children.map((Node child) {
|
return _children.map((Node<T> child) {
|
||||||
if (child.key == key) {
|
if (child.key == key) {
|
||||||
return newNode;
|
return newNode;
|
||||||
} else {
|
} else {
|
||||||
|
@ -444,19 +446,19 @@ class TreeViewController {
|
||||||
|
|
||||||
/// Toggles an existing node identified by specified key. This method
|
/// Toggles an existing node identified by specified key. This method
|
||||||
/// returns a new list with the specified node toggled.
|
/// returns a new list with the specified node toggled.
|
||||||
List<Node> toggleNode(String key, {Node? parent}) {
|
List<Node<T>> toggleNode(String key, {Node<T>? parent}) {
|
||||||
Node? _node = getNode(key, parent: parent);
|
Node<T>? _node = getNode(key, parent: parent);
|
||||||
return updateNode(key, _node!.copyWith(expanded: !_node.expanded));
|
return updateNode(key, _node!.copyWith(expanded: !_node.expanded));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Deletes an existing node identified by specified key. This method
|
/// Deletes an existing node identified by specified key. This method
|
||||||
/// returns a new list with the specified node removed.
|
/// returns a new list with the specified node removed.
|
||||||
List<Node> deleteNode(String key, {Node? parent}) {
|
List<Node<T>> deleteNode(String key, {Node<T>? parent}) {
|
||||||
List<Node> _children = parent == null ? this.children : parent.children;
|
List<Node<T>> _children = parent == null ? this.children : parent.children;
|
||||||
List<Node> _filteredChildren = [];
|
List<Node<T>> _filteredChildren = [];
|
||||||
Iterator iter = _children.iterator;
|
Iterator iter = _children.iterator;
|
||||||
while (iter.moveNext()) {
|
while (iter.moveNext()) {
|
||||||
Node child = iter.current;
|
Node<T> child = iter.current;
|
||||||
if (child.key != key) {
|
if (child.key != key) {
|
||||||
if (child.isParent) {
|
if (child.isParent) {
|
||||||
_filteredChildren.add(child.copyWith(
|
_filteredChildren.add(child.copyWith(
|
||||||
|
@ -471,13 +473,13 @@ class TreeViewController {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the current selected node. Returns null if there is no selectedKey
|
/// Get the current selected node. Returns null if there is no selectedKey
|
||||||
Node? get selectedNode {
|
Node<T>? get selectedNode {
|
||||||
return this.selectedKey!.isEmpty ? null : getNode(this.selectedKey!);
|
return this.selectedKey!.isEmpty ? null : getNode(this.selectedKey!);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Map representation of this object
|
/// Map representation of this object
|
||||||
List<Map<String, dynamic>> get asMap {
|
List<Map<String, dynamic>> get asMap {
|
||||||
return children.map((Node child) => child.asMap).toList();
|
return children.map((Node<T> child) => child.asMap).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
name: flutter_treeview
|
name: flutter_treeview
|
||||||
description: A tree widget for Flutter that can be used to display nested, hierarchical data. It includes a number of features like styling labels, icons, and import and export utilities.
|
description: A tree widget for Flutter that can be used to display nested, hierarchical data. It includes a number of features like styling labels, icons, and import and export utilities.
|
||||||
version: 1.0.3+2
|
version: 1.0.3+16
|
||||||
homepage: https://bitbucket.org/kevinandre/flutter_treeview/src/master/
|
homepage: https://bitbucket.org/kevinandre/flutter_treeview/src/master/
|
||||||
repository: https://bitbucket.org/kevinandre/flutter_treeview/src/master/
|
repository: https://bitbucket.org/kevinandre/flutter_treeview/src/master/
|
||||||
issue_tracker: https://bitbucket.org/kevinandre/flutter_treeview/issues
|
issue_tracker: https://bitbucket.org/kevinandre/flutter_treeview/issues
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue