Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 { | 7 abstract class TableTreeRow extends Observable { |
| 8 final TableTreeRow parent; | |
| 9 @observable final int depth; | |
| 10 @observable final List<TableTreeRow> children = new List<TableTreeRow>(); | |
| 11 @observable final List<String> columns = []; | |
| 12 static const arrowRight = '\u2192'; | 8 static const arrowRight = '\u2192'; |
| 13 static const arrowDownRight = '\u21b3'; | 9 static const arrowDownRight = '\u21b3'; |
| 14 static const showExpanderStyle = 'cursor: pointer;'; | 10 // Number of pixels each subtree is indented. |
| 15 static const hideExpanderStyle = 'visibility:hidden;'; | 11 static const subtreeIndent = 16; |
| 16 | 12 |
| 17 // TODO(johnmccutchan): Move expander display decisions into html once | 13 final TableTree tree; |
| 18 // tables and templates are better supported. | 14 final TableTreeRow parent; |
| 19 @observable String expander = arrowRight; | 15 final int depth; |
| 20 @observable String expanderStyle = showExpanderStyle; | 16 final List<TableTreeRow> children = new List<TableTreeRow>(); |
| 17 final List<TableCellElement> tableColumns = new List<TableCellElement>(); | |
| 18 SpanElement _expander; | |
| 19 TableRowElement _tr; | |
| 20 TableRowElement get tr { | |
| 21 assert(_tr != null); | |
| 22 return _tr; | |
| 23 } | |
| 21 | 24 |
| 22 TableTreeRow(TableTreeRow parent) : | 25 TableTreeRow(this.tree, TableTreeRow parent) : |
| 23 parent = parent, | 26 parent = parent, |
| 24 depth = parent != null ? parent.depth+1 : 0 { | 27 depth = parent != null ? parent.depth+1 : 0 { |
| 25 if (!hasChildren()) { | |
| 26 expanderStyle = hideExpanderStyle; | |
| 27 } | |
| 28 } | 28 } |
| 29 | 29 |
| 30 bool _expanded = false; | 30 bool _expanded = false; |
| 31 bool get expanded => _expanded; | 31 bool get expanded => _expanded; |
| 32 set expanded(bool expanded) { | 32 set expanded(bool expanded) { |
| 33 var changed = _expanded != expanded; | 33 var changed = _expanded != expanded; |
| 34 _expanded = expanded; | 34 _expanded = expanded; |
| 35 if (changed) { | 35 if (changed) { |
| 36 // If the state has changed, fire callbacks. | 36 // If the state has changed, fire callbacks. |
| 37 if (_expanded) { | 37 if (_expanded) { |
| 38 expander = arrowDownRight; | 38 _onExpand(); |
| 39 onShow(); | |
| 40 } else { | 39 } else { |
| 41 expander = arrowRight; | 40 _onCollapse(); |
| 42 onHide(); | |
| 43 } | 41 } |
| 44 } | 42 } |
| 45 } | 43 } |
| 46 | 44 |
| 47 bool toggle() { | 45 bool expandOrCollapse() { |
| 48 expanded = !expanded; | 46 expanded = !expanded; |
| 49 return expanded; | 47 return expanded; |
| 50 } | 48 } |
| 51 | 49 |
| 52 bool hasChildren(); | 50 bool hasChildren(); |
| 53 | 51 |
| 54 /// Fired when the tree row is expanded. Add children rows here. | 52 String _colorForRow() { |
|
rmacnak
2015/01/09 21:55:50
classForRow?
Cutch
2015/01/09 22:00:42
backgroundColorClassForRow
| |
| 55 void onShow(); | 53 const colors = const ['rowColor0', 'rowColor1', 'rowColor2', 'rowColor3', |
| 54 'rowColor4', 'rowColor5', 'rowColor6', 'rowColor7', | |
| 55 'rowColor8']; | |
| 56 var index = (depth - 1) % colors.length; | |
| 57 return colors[index]; | |
| 58 } | |
| 56 | 59 |
| 57 /// Fired when the tree row is collapsed. | 60 void _buildRow() { |
| 58 void onHide(); | 61 _tr = new TableRowElement(); |
| 62 for (var i = 0; i < tree.columnCount; i++) { | |
| 63 var cell = _tr.insertCell(-1); | |
| 64 cell.classes.add(_colorForRow()); | |
| 65 tableColumns.add(cell); | |
| 66 } | |
| 67 var firstColumn = tableColumns[0]; | |
| 68 _expander = new SpanElement(); | |
| 69 _expander.style.display = 'inline-block'; | |
| 70 _expander.style.minWidth = '1.5em'; | |
| 71 _expander.onClick.listen(onClick); | |
| 72 firstColumn.children.add(_expander); | |
| 73 firstColumn.style.paddingLeft = '${depth * subtreeIndent}px'; | |
| 74 updateExpanderView(); | |
| 75 } | |
| 76 | |
| 77 void updateExpanderView() { | |
| 78 if (_expander == null) { | |
| 79 return; | |
| 80 } | |
| 81 if (!hasChildren()) { | |
| 82 _expander.style.visibility = 'hidden'; | |
| 83 _expander.style.cursor = 'auto'; | |
| 84 return; | |
| 85 } else { | |
| 86 _expander.style.visibility = 'visible'; | |
| 87 _expander.style.cursor = 'pointer'; | |
| 88 } | |
| 89 _expander.text = expanded ? arrowDownRight : arrowRight; | |
| 90 } | |
| 91 | |
| 92 /// Fired when the tree row is being shown. | |
| 93 /// Populate tr and add logical children here. | |
| 94 void onShow() { | |
| 95 assert(_tr == null); | |
| 96 _buildRow(); | |
| 97 } | |
| 98 | |
| 99 /// Fired when the tree row is being hidden. | |
| 100 void onHide() { | |
| 101 assert(_tr != null); | |
| 102 _tr = null; | |
| 103 tableColumns.clear(); | |
| 104 _expander = null; | |
| 105 } | |
| 106 | |
| 107 /// Fired when the tree row is being expanded. | |
| 108 void _onExpand() { | |
| 109 for (var child in children) { | |
| 110 child.onShow(); | |
| 111 child.updateExpanderView(); | |
| 112 } | |
| 113 updateExpanderView(); | |
| 114 } | |
| 115 | |
| 116 /// Fired when the tree row is being collapsed. | |
| 117 void _onCollapse() { | |
| 118 for (var child in children) { | |
| 119 child.onHide(); | |
| 120 } | |
| 121 updateExpanderView(); | |
| 122 } | |
| 123 | |
| 124 void onClick(Event e) { | |
| 125 tree.toggle(this); | |
| 126 e.stopPropagation(); | |
| 127 } | |
| 59 } | 128 } |
| 60 | 129 |
| 61 class TableTree extends Observable { | 130 class TableTree extends Observable { |
| 62 @observable final List<TableTreeRow> rows = toObservable([]); | 131 final TableSectionElement tableBody; |
| 132 final List<TableTreeRow> rows = []; | |
| 133 final int columnCount; | |
| 63 | 134 |
| 64 /// Create a table tree with column [headers]. | 135 /// Create a table tree with column [headers]. |
| 65 TableTree(); | 136 TableTree(this.tableBody, this.columnCount); |
| 66 | 137 |
| 67 /// Initialize the table tree with the list of root children. | 138 /// Initialize the table tree with the list of root children. |
| 68 void initialize(TableTreeRow root) { | 139 void initialize(TableTreeRow root) { |
| 140 tableBody.children.clear(); | |
| 69 rows.clear(); | 141 rows.clear(); |
| 70 root.onShow(); | 142 root.onShow(); |
| 71 rows.addAll(root.children); | 143 rows.addAll(root.children); |
| 144 for (var i = 0; i < rows.length; i++) { | |
| 145 rows[i].onShow(); | |
| 146 tableBody.children.add(rows[i].tr); | |
| 147 } | |
| 72 } | 148 } |
| 73 | 149 |
| 74 /// Toggle expansion of row at [rowIndex]. | 150 /// Toggle expansion of row in tree. |
| 75 void toggle(int rowIndex) { | 151 void toggle(TableTreeRow row) { |
| 76 assert(rowIndex >= 0); | 152 if (row.expandOrCollapse()) { |
| 77 assert(rowIndex < rows.length); | |
| 78 var row = rows[rowIndex]; | |
| 79 if (row.toggle()) { | |
| 80 _expand(row); | 153 _expand(row); |
| 81 } else { | 154 } else { |
| 82 _collapse(row); | 155 _collapse(row); |
| 83 } | 156 } |
| 84 } | 157 } |
| 85 | 158 |
| 86 int _index(TableTreeRow row) => rows.indexOf(row); | 159 int _index(TableTreeRow row) => rows.indexOf(row); |
| 87 | 160 |
| 88 void _expand(TableTreeRow row) { | 161 void _expand(TableTreeRow row) { |
| 89 int index = _index(row); | 162 int index = _index(row); |
| 90 assert(index != -1); | 163 assert(index != -1); |
| 91 rows.insertAll(index + 1, row.children); | 164 rows.insertAll(index + 1, row.children); |
| 165 for (var i = 0; i < row.children.length; i++) { | |
| 166 tableBody.children.insert(index + i + 1, row.children[i].tr); | |
| 167 } | |
| 92 } | 168 } |
| 93 | 169 |
| 94 void _collapse(TableTreeRow row) { | 170 void _collapse(TableTreeRow row) { |
| 95 var childCount = row.children.length; | 171 var childCount = row.children.length; |
| 96 if (childCount == 0) { | 172 if (childCount == 0) { |
| 97 return; | 173 return; |
| 98 } | 174 } |
| 99 for (var i = 0; i < childCount; i++) { | 175 for (var i = 0; i < childCount; i++) { |
| 100 // Close all inner rows. | 176 // Close all inner rows. |
| 101 if (row.children[i].expanded) { | 177 if (row.children[i].expanded) { |
| 102 _collapse(row.children[i]); | 178 _collapse(row.children[i]); |
| 103 } | 179 } |
| 104 } | 180 } |
| 105 // Collapse this row. | 181 // Collapse this row. |
| 106 row.expanded = false; | 182 row.expanded = false; |
| 107 // Remove all children. | 183 // Remove all children. |
| 108 int index = _index(row); | 184 int index = _index(row); |
| 109 rows.removeRange(index + 1, index + 1 + childCount); | 185 rows.removeRange(index + 1, index + 1 + childCount); |
| 186 for (var i = 0; i < childCount; i++) { | |
| 187 tableBody.children.removeAt(index + 1); | |
| 188 } | |
| 110 } | 189 } |
| 111 } | 190 } |
| 112 | 191 |
| 113 typedef String ValueFormatter(dynamic value); | 192 typedef String ValueFormatter(dynamic value); |
| 114 | 193 |
| 115 class SortedTableColumn { | 194 class SortedTableColumn { |
| 116 static String toStringFormatter(dynamic v) { | 195 static String toStringFormatter(dynamic v) { |
| 117 return v != null ? v.toString() : '<null>'; | 196 return v != null ? v.toString() : '<null>'; |
| 118 } | 197 } |
| 119 final String label; | 198 final String label; |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 204 if (column != _sortColumnIndex) { | 283 if (column != _sortColumnIndex) { |
| 205 return columns[column].label + '\u2003'; | 284 return columns[column].label + '\u2003'; |
| 206 } | 285 } |
| 207 return columns[column].label + (_sortDescending ? arrowUp : arrowDown); | 286 return columns[column].label + (_sortDescending ? arrowUp : arrowDown); |
| 208 } | 287 } |
| 209 | 288 |
| 210 dynamic getValue(int row, int column) { | 289 dynamic getValue(int row, int column) { |
| 211 return rows[row].values[column]; | 290 return rows[row].values[column]; |
| 212 } | 291 } |
| 213 } | 292 } |
| OLD | NEW |