OLD | NEW |
---|---|
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 import 'dart:async'; | 5 import 'dart:async'; |
6 import 'dart:html'; | 6 import 'dart:html'; |
7 import 'dart:collection'; | |
7 import 'dart:math' as Math; | 8 import 'dart:math' as Math; |
8 import 'package:observatory/src/elements/containers/virtual_collection.dart'; | 9 import 'package:observatory/src/elements/containers/virtual_collection.dart'; |
9 import 'package:observatory/src/elements/helpers/rendering_scheduler.dart'; | 10 import 'package:observatory/src/elements/helpers/rendering_scheduler.dart'; |
10 import 'package:observatory/src/elements/helpers/tag.dart'; | 11 import 'package:observatory/src/elements/helpers/tag.dart'; |
11 | 12 |
12 typedef HtmlElement VirtualTreeCreateCallback( | 13 typedef HtmlElement VirtualTreeCreateCallback( |
13 toggle({bool autoToggleSingleChildNodes, bool autoToggleWholeTree})); | 14 toggle({bool autoToggleSingleChildNodes, bool autoToggleWholeTree})); |
14 typedef void VirtualTreeUpdateCallback(HtmlElement el, dynamic item, int depth); | 15 typedef void VirtualTreeUpdateCallback(HtmlElement el, dynamic item, int depth); |
15 typedef Iterable<dynamic> VritualTreeGetChildrenCallback(dynamic value); | 16 typedef Iterable<dynamic> VritualTreeGetChildrenCallback(dynamic value); |
16 | 17 |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
82 | 83 |
83 bool isExpanded(item) { | 84 bool isExpanded(item) { |
84 return _expanded.contains(item); | 85 return _expanded.contains(item); |
85 } | 86 } |
86 | 87 |
87 void expand(item, | 88 void expand(item, |
88 {bool autoExpandSingleChildNodes: false, | 89 {bool autoExpandSingleChildNodes: false, |
89 bool autoExpandWholeTree: false}) { | 90 bool autoExpandWholeTree: false}) { |
90 if (_expanded.add(item)) _r.dirty(); | 91 if (_expanded.add(item)) _r.dirty(); |
91 if (autoExpandWholeTree) { | 92 if (autoExpandWholeTree) { |
92 for (final child in _children(item)) { | 93 Queue toDo = new Queue(); |
rmacnak
2017/07/06 00:10:20
Maybe add a note here that the tree is potentially
cbernaschina
2017/07/06 00:33:46
Done.
| |
93 expand(child, autoExpandWholeTree: true); | 94 toDo.addAll(_children(item)); |
95 while (toDo.isNotEmpty) { | |
96 final item = toDo.removeFirst(); | |
97 if (_expanded.add(item)) _r.dirty(); | |
98 toDo.addAll(_children(item)); | |
94 } | 99 } |
95 } else if (autoExpandSingleChildNodes) { | 100 } else if (autoExpandSingleChildNodes) { |
96 var children = _children(item); | 101 var children = _children(item); |
97 while (children.length == 1) { | 102 while (children.length == 1) { |
98 _expanded.add(children.first); | 103 _expanded.add(children.first); |
99 children = _children(children.first); | 104 children = _children(children.first); |
100 } | 105 } |
101 } | 106 } |
102 } | 107 } |
103 | 108 |
104 void collapse(item, | 109 void collapse(item, |
105 {bool autoCollapseSingleChildNodes: false, | 110 {bool autoCollapseSingleChildNodes: false, |
106 bool autoCollapseWholeTree: false}) { | 111 bool autoCollapseWholeTree: false}) { |
107 if (_expanded.remove(item)) _r.dirty(); | 112 if (_expanded.remove(item)) _r.dirty(); |
108 if (autoCollapseWholeTree) { | 113 if (autoCollapseWholeTree) { |
109 for (final child in _children(item)) { | 114 Queue toDo = new Queue(); |
110 collapse(child, autoCollapseWholeTree: true); | 115 toDo.addAll(_children(item)); |
116 while (toDo.isNotEmpty) { | |
117 final item = toDo.removeFirst(); | |
118 if (_expanded.remove(item)) _r.dirty(); | |
119 toDo.addAll(_children(item)); | |
111 } | 120 } |
112 } else if (autoCollapseSingleChildNodes) { | 121 } else if (autoCollapseSingleChildNodes) { |
113 var children = _children(item); | 122 var children = _children(item); |
114 while (children.length == 1) { | 123 while (children.length == 1) { |
115 _expanded.remove(children.first); | 124 _expanded.remove(children.first); |
116 children = _children(children.first); | 125 children = _children(children.first); |
117 } | 126 } |
118 } | 127 } |
119 } | 128 } |
120 | 129 |
121 @override | 130 @override |
122 attached() { | 131 attached() { |
123 super.attached(); | 132 super.attached(); |
124 _r.enable(); | 133 _r.enable(); |
125 } | 134 } |
126 | 135 |
127 @override | 136 @override |
128 detached() { | 137 detached() { |
129 super.detached(); | 138 super.detached(); |
130 _r.disable(notify: true); | 139 _r.disable(notify: true); |
131 children = const []; | 140 children = const []; |
132 } | 141 } |
133 | 142 |
134 VirtualCollectionElement _collection; | 143 VirtualCollectionElement _collection; |
135 | 144 |
136 void render() { | 145 void render() { |
137 if (children.length == 0) { | 146 if (children.length == 0) { |
138 children = [_collection]; | 147 children = [_collection]; |
139 } | 148 } |
140 Iterable _toList(item) { | 149 |
141 if (isExpanded(item)) { | 150 final items = []; |
142 Iterable children = _children(item); | 151 final depths = new List.filled(_items.length, 0, growable: true); |
143 if (children.isNotEmpty) { | 152 |
144 return [item]..addAll(children.expand(_toList)); | 153 { |
154 final toDo = new Queue(); | |
155 | |
156 toDo.addAll(_items); | |
157 while (toDo.isNotEmpty) { | |
158 final item = toDo.removeFirst(); | |
159 | |
160 items.add(item); | |
161 if (isExpanded(item)) { | |
162 final children = _children(item); | |
163 children | |
164 .toList(growable: false) | |
165 .reversed | |
166 .forEach((c) => toDo.addFirst(c)); | |
167 final depth = depths[items.length - 1]; | |
168 depths.insertAll( | |
169 items.length, new List.filled(children.length, depth + 1)); | |
145 } | 170 } |
146 } | 171 } |
147 return [item]; | |
148 } | 172 } |
149 | 173 |
150 _collection.items = _items.expand(_toList); | 174 _depths = depths; |
151 var depth = 0; | 175 _collection.items = items; |
152 Iterable _toDepth(item) { | |
153 if (isExpanded(item)) { | |
154 Iterable children = _children(item); | |
155 if (children.isNotEmpty) { | |
156 depth++; | |
157 return children.expand(_toDepth).toList()..insert(0, --depth); | |
158 } | |
159 } | |
160 return [depth]; | |
161 } | |
162 | |
163 _depths = _items.expand(_toDepth).toList(); | |
164 } | 176 } |
165 } | 177 } |
OLD | NEW |