Created
February 27, 2020 01:43
-
-
Save Hixie/ff07a1203684296acde4b543d7664a2f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'dart:io'; | |
import 'package:flutter/foundation.dart'; | |
import 'package:flutter/material.dart'; | |
void _enablePlatformOverrideForDesktop() { | |
if (!kIsWeb && (Platform.isWindows || Platform.isLinux)) { | |
debugDefaultTargetPlatformOverride = TargetPlatform.fuchsia; | |
} | |
} | |
void main() { | |
_enablePlatformOverrideForDesktop(); | |
runApp(MyApp()); | |
} | |
class MyApp extends StatefulWidget { | |
@override | |
_MyAppState createState() => _MyAppState(); | |
} | |
class _MyAppState extends State<MyApp> { | |
@override | |
Widget build(BuildContext context) { | |
return Directionality( | |
textDirection: TextDirection.ltr, | |
child: TreeDemo(), | |
); | |
} | |
} | |
List<SingleNode> _kTestNodes = [ | |
GroupNode('0', [1, 2, 3, 4, 5, 6]), | |
SingleNode('1'), | |
SingleNode('2'), | |
SingleNode('3'), | |
SingleNode('4'), | |
SingleNode('5'), | |
GroupNode('6', [7, 8]), | |
SingleNode('7'), | |
SingleNode('8'), | |
]; | |
class TreeDemo extends StatefulWidget { | |
@override | |
State<StatefulWidget> createState() { | |
return _TreeDemoState(); | |
} | |
} | |
class _TreeDemoState extends State<TreeDemo> { | |
TestTreeModel model = TestTreeModel(_kTestNodes); | |
@override | |
Widget build(BuildContext context) { | |
return Column( | |
children: [ | |
Tree( | |
model: model, | |
), | |
GestureDetector( | |
child: Icon(Icons.refresh), | |
onTap: () { | |
setState(() { | |
// Move node 6 to index 0 within node 0's children. | |
model.moveNode(6, 0, 0, 0); | |
}); | |
}, | |
), | |
GestureDetector( | |
child: Icon(Icons.description), | |
onTap: () { | |
debugDumpApp(); | |
}, | |
) | |
], | |
); | |
} | |
} | |
enum BorderType { box, line, none } | |
/// A widget with a tree structure. Grabs its structure and data from a [model]. | |
class Tree extends StatefulWidget { | |
Tree({ | |
Key key, | |
@required this.model, | |
}) : assert(model != null), | |
super(key: key); | |
/// The model backing the [Tree]. | |
final TestTreeModel model; | |
@override | |
_TreeState createState() => _TreeState(); | |
} | |
class _TreeState extends State<Tree> { | |
@override | |
Widget build(BuildContext context) { | |
return Column(children: _genRows(nodes: widget.model.getTopLevel()).toList()); | |
} | |
Iterable<Widget> _genRows({ | |
@required List<int> nodes, | |
double leftIndent = 0, | |
}) sync* { | |
for (int i = 0; i < nodes.length; i++) { | |
int node = nodes[i]; | |
yield Text('${">" * leftIndent.round()} $node', key: ValueKey(node)); | |
yield* _genRows(nodes: widget.model.getChildrenList(node), leftIndent: leftIndent + 1); | |
} | |
} | |
} | |
class TestTreeModel { | |
TestTreeModel(this.nodes); | |
List<SingleNode> nodes; | |
List<int> getTopLevel() { | |
return [0]; | |
} | |
List<int> getChildrenList(int node) { | |
return nodes[node] is GroupNode ? (nodes[node] as GroupNode).children : []; | |
} | |
void moveNode(int source, int sourceParent, int target, int targetParent) { | |
getChildrenList(sourceParent).remove(source); | |
List<int> targetChildren = getChildrenList(targetParent); | |
if (targetParent == target) { | |
targetChildren.insert(0, source); | |
return; | |
} | |
for (int i = 0; i < targetChildren.length; ++i) { | |
if (targetChildren[i] == target) { | |
targetChildren.insert(i, source); | |
return; | |
} | |
} | |
} | |
} | |
class SingleNode { | |
const SingleNode(this.name); | |
final String name; | |
} | |
class GroupNode extends SingleNode { | |
const GroupNode(String name, this.children) : super(name); | |
final List<int> children; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment