Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(649)

Side by Side Diff: runtime/observatory/lib/src/app/view_model.dart

Issue 2310003004: Removed polymer & mirror from Observatory (Closed)
Patch Set: Fixed crash in heap-map page Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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 part of app; 5 part of app;
6 6
7 abstract class TableTreeRow extends Observable {
8 static const arrowRight = '\u2192';
9 static const arrowDownRight = '\u21b3';
10 // Number of ems each subtree is indented.
11 static const subtreeIndent = 2;
12
13 TableTreeRow(this.tree, TableTreeRow parent) :
14 parent = parent,
15 depth = parent != null ? parent.depth + 1 : 0 {
16 }
17
18 final TableTree tree;
19 final TableTreeRow parent;
20 final int depth;
21 final List<TableTreeRow> children = new List<TableTreeRow>();
22 final List<TableCellElement> _tableColumns = new List<TableCellElement>();
23 final List<DivElement> flexColumns = new List<DivElement>();
24 final List<StreamSubscription> listeners = new List<StreamSubscription>();
25
26 SpanElement _expander;
27 TableRowElement _tr;
28 TableRowElement get tr => _tr;
29 bool _expanded = false;
30 bool get expanded => _expanded;
31 set expanded(bool expanded) {
32 var changed = _expanded != expanded;
33 _expanded = expanded;
34 if (changed) {
35 // If the state has changed, fire callbacks.
36 if (_expanded) {
37 _onExpand();
38 } else {
39 _onCollapse();
40 }
41 }
42 }
43
44 /// Fired when the tree row is being expanded.
45 void _onExpand() {
46 _updateExpanderView();
47 }
48
49 /// Fired when the tree row is being collapsed.
50 void _onCollapse() {
51 for (var child in children) {
52 child.onHide();
53 }
54 _updateExpanderView();
55 }
56
57 bool toggle() {
58 expanded = !expanded;
59 return expanded;
60 }
61
62 HtmlElement _makeColorBlock(String backgroundColor) {
63 var colorBlock = new DivElement();
64 colorBlock.style.minWidth = '2px';
65 colorBlock.style.backgroundColor = backgroundColor;
66 return colorBlock;
67 }
68
69 HtmlElement _makeExpander() {
70 var expander = new SpanElement();
71 expander.style.minWidth = '24px';
72 expander.style.minHeight = '24px';
73 listeners.add(expander.onClick.listen(onClick));
74 return expander;
75 }
76
77 void _cleanUpListeners() {
78 for (var i = 0; i < listeners.length; i++) {
79 listeners[i].cancel();
80 }
81 listeners.clear();
82 }
83
84 void onClick(Event e) {
85 e.stopPropagation();
86 tree.toggle(this);
87 }
88
89 static const redColor = '#F44336';
90 static const blueColor = '#3F51B5';
91 static const purpleColor = '#673AB7';
92 static const greenColor = '#4CAF50';
93 static const orangeColor = '#FF9800';
94 static const lightGrayColor = '#FAFAFA';
95
96 void _buildRow() {
97 const List backgroundColors = const [
98 purpleColor,
99 redColor,
100 greenColor,
101 blueColor,
102 orangeColor,
103 ];
104 _tr = new TableRowElement();
105 for (var i = 0; i < tree.columnCount; i++) {
106 var cell = _tr.insertCell(-1);
107 _tableColumns.add(cell);
108 var flex = new DivElement();
109 flex.classes.add('flex-row');
110 cell.children.add(flex);
111 flexColumns.add(flex);
112 }
113 var firstColumn = flexColumns[0];
114 _tableColumns[0].style.paddingLeft = '${(depth - 1) * subtreeIndent}em';
115 var backgroundColor = lightGrayColor;
116 if (depth > 1) {
117 var colorIndex = (depth - 1) % backgroundColors.length;
118 backgroundColor = backgroundColors[colorIndex];
119 }
120 var colorBlock = _makeColorBlock(backgroundColor);
121 firstColumn.children.add(colorBlock);
122 _expander = _makeExpander();
123 firstColumn.children.add(_expander);
124 // Enable expansion by clicking anywhere on the first column.
125 listeners.add(firstColumn.onClick.listen(onClick));
126 _updateExpanderView();
127 }
128
129 void _updateExpanderView() {
130 if (_expander == null) {
131 return;
132 }
133 if (!hasChildren()) {
134 _expander.style.visibility = 'hidden';
135 _expander.classes.remove('pointer');
136 return;
137 } else {
138 _expander.style.visibility = 'visible';
139 _expander.classes.add('pointer');
140 }
141 _expander.children.clear();
142 _expander.children.add(expanded ?
143 new Element.tag('icon-expand-more') :
144 new Element.tag('icon-chevron-right'));
145 }
146
147 bool hasChildren();
148
149 /// Fired when the tree row is being shown.
150 /// Populate tr and add logical children here.
151 void onShow() {
152 assert(_tr == null);
153 _buildRow();
154 }
155
156 /// Fired when the tree row is being hidden.
157 void onHide() {
158 _tr = null;
159 _expander = null;
160 if (_tableColumns != null) {
161 _tableColumns.clear();
162 }
163 if (flexColumns != null) {
164 flexColumns.clear();
165 }
166 _cleanUpListeners();
167 }
168 }
169
170 class TableTree extends Observable {
171 final TableSectionElement tableBody;
172 final List<TableTreeRow> rows = [];
173 final int columnCount;
174 Future _pendingOperation;
175 /// Create a table tree with column [headers].
176 TableTree(this.tableBody, this.columnCount);
177
178 void clear() {
179 tableBody.children.clear();
180 for (var i = 0; i < rows.length; i++) {
181 rows[i]._cleanUpListeners();
182 }
183 rows.clear();
184 }
185
186 /// Initialize the table tree with the list of root children.
187 void initialize(TableTreeRow root) {
188 clear();
189 root.onShow();
190 toggle(root);
191 }
192
193 /// Toggle expansion of row in tree.
194 toggle(TableTreeRow row) async {
195 if (_pendingOperation != null) {
196 return;
197 }
198 if (row.toggle()) {
199 document.body.classes.add('busy');
200 _pendingOperation = _expand(row);
201 await _pendingOperation;
202 _pendingOperation = null;
203 document.body.classes.remove('busy');
204 if (row.children.length == 1) {
205 // Auto expand single child.
206 await toggle(row.children[0]);
207 }
208 } else {
209 document.body.classes.add('busy');
210 _pendingOperation = _collapse(row);
211 await _pendingOperation;
212 _pendingOperation = null;
213 document.body.classes.remove('busy');
214 }
215 }
216
217 int _index(TableTreeRow row) => rows.indexOf(row);
218
219 _insertRow(index, child) {
220 rows.insert(index, child);
221 tableBody.children.insert(index, child.tr);
222 }
223
224 _expand(TableTreeRow row) async {
225 int index = _index(row);
226 if ((index == -1) && (rows.length != 0)) {
227 return;
228 }
229 assert((index != -1) || (rows.length == 0));
230 var i = 0;
231 var addPerIteration = 10;
232 while (i < row.children.length) {
233 await window.animationFrame;
234 for (var j = 0; j < addPerIteration; j++) {
235 if (i == row.children.length) {
236 break;
237 }
238 var child = row.children[i];
239 child.onShow();
240 child._updateExpanderView();
241 _insertRow(index + i + 1, child);
242 i++;
243 }
244 }
245 }
246
247 _collapseSync(TableTreeRow row) {
248 var childCount = row.children.length;
249 if (childCount == 0) {
250 return;
251 }
252 for (var i = 0; i < childCount; i++) {
253 // Close all inner rows.
254 if (row.children[i].expanded) {
255 _collapseSync(row.children[i]);
256 }
257 }
258 // Collapse this row.
259 row.expanded = false;
260 // Remove all children.
261 int index = _index(row);
262 for (var i = 0; i < childCount; i++) {
263 rows.removeAt(index + 1);
264 tableBody.children.removeAt(index + 1);
265 }
266 }
267
268 _collapse(TableTreeRow row) async {
269 _collapseSync(row);
270 }
271 }
272
273 typedef String ValueFormatter(dynamic value); 7 typedef String ValueFormatter(dynamic value);
274 8
275 class SortedTableColumn { 9 class SortedTableColumn {
276 static String toStringFormatter(dynamic v) { 10 static String toStringFormatter(dynamic v) {
277 return v != null ? v.toString() : '<null>'; 11 return v != null ? v.toString() : '<null>';
278 } 12 }
279 final String label; 13 final String label;
280 final ValueFormatter formatter; 14 final ValueFormatter formatter;
281 SortedTableColumn.withFormatter(this.label, this.formatter); 15 SortedTableColumn.withFormatter(this.label, this.formatter);
282 SortedTableColumn(this.label) 16 SortedTableColumn(this.label)
283 : formatter = toStringFormatter; 17 : formatter = toStringFormatter;
284 } 18 }
285 19
286 class SortedTableRow { 20 class SortedTableRow {
287 final List values; 21 final List values;
288 SortedTableRow(this.values); 22 SortedTableRow(this.values);
289 } 23 }
290 24
291 class SortedTable extends Observable { 25 class SortedTable {
292 final List<SortedTableColumn> columns; 26 final List<SortedTableColumn> columns;
293 final List<SortedTableRow> rows = new List<SortedTableRow>(); 27 final List<SortedTableRow> rows = new List<SortedTableRow>();
294 final List<int> sortedRows = []; 28 final List<int> sortedRows = [];
295 29
296 SortedTable(this.columns); 30 SortedTable(this.columns);
297 31
298 int _sortColumnIndex = 0; 32 int _sortColumnIndex = 0;
299 set sortColumnIndex(var index) { 33 set sortColumnIndex(var index) {
300 assert(index >= 0); 34 assert(index >= 0);
301 assert(index < columns.length); 35 assert(index < columns.length);
302 _sortColumnIndex = index; 36 _sortColumnIndex = index;
303 notifyPropertyChange(#getColumnLabel, 0, 1);
304 } 37 }
305 int get sortColumnIndex => _sortColumnIndex; 38 int get sortColumnIndex => _sortColumnIndex;
306 bool _sortDescending = true; 39 bool _sortDescending = true;
307 bool get sortDescending => _sortDescending; 40 bool get sortDescending => _sortDescending;
308 set sortDescending(var descending) { 41 set sortDescending(var descending) {
309 _sortDescending = descending; 42 _sortDescending = descending;
310 notifyPropertyChange(#getColumnLabel, 0, 1);
311 } 43 }
312 44
313 45
314 dynamic getSortKeyFor(int row, int col) { 46 dynamic getSortKeyFor(int row, int col) {
315 return rows[row].values[col]; 47 return rows[row].values[col];
316 } 48 }
317 49
318 int _sortFuncDescending(int i, int j) { 50 int _sortFuncDescending(int i, int j) {
319 var a = getSortKeyFor(i, _sortColumnIndex); 51 var a = getSortKeyFor(i, _sortColumnIndex);
320 var b = getSortKeyFor(j, _sortColumnIndex); 52 var b = getSortKeyFor(j, _sortColumnIndex);
(...skipping 25 matching lines...) Expand all
346 sortedRows.add(rows.length); 78 sortedRows.add(rows.length);
347 rows.add(row); 79 rows.add(row);
348 } 80 }
349 81
350 String getFormattedValue(int row, int column) { 82 String getFormattedValue(int row, int column) {
351 var value = getValue(row, column); 83 var value = getValue(row, column);
352 var formatter = columns[column].formatter; 84 var formatter = columns[column].formatter;
353 return formatter(value); 85 return formatter(value);
354 } 86 }
355 87
356 @observable String getColumnLabel(int column) { 88 String getColumnLabel(int column) {
357 assert(column >= 0); 89 assert(column >= 0);
358 assert(column < columns.length); 90 assert(column < columns.length);
359 // TODO(johnmccutchan): Move expander display decisions into html once 91 // TODO(johnmccutchan): Move expander display decisions into html once
360 // tables and templates are better supported. 92 // tables and templates are better supported.
361 const arrowUp = '\u25BC'; 93 const arrowUp = '\u25BC';
362 const arrowDown = '\u25B2'; 94 const arrowDown = '\u25B2';
363 if (column != _sortColumnIndex) { 95 if (column != _sortColumnIndex) {
364 return columns[column].label + '\u2003'; 96 return columns[column].label + '\u2003';
365 } 97 }
366 return columns[column].label + (_sortDescending ? arrowUp : arrowDown); 98 return columns[column].label + (_sortDescending ? arrowUp : arrowDown);
367 } 99 }
368 100
369 dynamic getValue(int row, int column) { 101 dynamic getValue(int row, int column) {
370 return rows[row].values[column]; 102 return rows[row].values[column];
371 } 103 }
372 } 104 }
OLDNEW
« no previous file with comments | « runtime/observatory/lib/src/app/page.dart ('k') | runtime/observatory/lib/src/elements/action_link.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698