| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | |
| 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. | |
| 4 | |
| 5 // This file has classes representing the grid tracks and grid template | |
| 6 | |
| 7 /** | |
| 8 * The data structure representing the grid-rows or grid-columns | |
| 9 * properties. | |
| 10 */ | |
| 11 class GridTrackList { | |
| 12 /** The set of tracks defined in CSS via grid-rows and grid-columns */ | |
| 13 final List<GridTrack> tracks; | |
| 14 | |
| 15 /** | |
| 16 * Maps edge names to the corresponding track. Depending on whether the index | |
| 17 * is used as a start or end, it might be interpreted exclusively or | |
| 18 * inclusively. | |
| 19 */ | |
| 20 final Map<String, int> lineNames; | |
| 21 | |
| 22 GridTrackList(this.tracks, this.lineNames) {} | |
| 23 } | |
| 24 | |
| 25 | |
| 26 /** Represents a row or a column. */ | |
| 27 class GridTrack { | |
| 28 /** | |
| 29 * The start position of this track. Equal to the sum of previous track's | |
| 30 * usedBreadth. | |
| 31 */ | |
| 32 num start; | |
| 33 | |
| 34 /** The final computed breadth of this track. */ | |
| 35 num usedBreadth; | |
| 36 | |
| 37 // Fields used internally by the sizing algorithm | |
| 38 num maxBreadth; | |
| 39 num updatedBreadth; | |
| 40 num tempBreadth; | |
| 41 | |
| 42 final TrackSizing sizing; | |
| 43 | |
| 44 GridTrack(this.sizing) {} | |
| 45 | |
| 46 /** | |
| 47 * Support for the feature that repeats rows and columns, e.g. | |
| 48 * [:grid-columns: 10px ("content" 250px 10px)[4]:] | |
| 49 */ | |
| 50 GridTrack clone() => new GridTrack(sizing.clone()); | |
| 51 | |
| 52 /** The min sizing function for the track. */ | |
| 53 SizingFunction get minSizing() => sizing.min; | |
| 54 | |
| 55 /** The min sizing function for the track. */ | |
| 56 SizingFunction get maxSizing() => sizing.max; | |
| 57 | |
| 58 num get end() => start + usedBreadth; | |
| 59 | |
| 60 bool get isFractional() => minSizing.isFraction || maxSizing.isFraction; | |
| 61 } | |
| 62 | |
| 63 | |
| 64 /** Represents the grid-row-align or grid-column-align. */ | |
| 65 class GridItemAlignment { | |
| 66 // TODO(jmesserly): should this be stored as an int for performance? | |
| 67 final String value; | |
| 68 | |
| 69 // 'start' | 'end' | 'center' | 'stretch' | |
| 70 GridItemAlignment.fromString(String value) | |
| 71 : this.value = (value == null) ? 'stretch' : value { | |
| 72 | |
| 73 switch (this.value) { | |
| 74 case 'start': case 'end': case 'center': case 'stretch': | |
| 75 break; | |
| 76 default: | |
| 77 throw new UnsupportedOperationException( | |
| 78 'invalid row/column alignment "$value"'); | |
| 79 } | |
| 80 } | |
| 81 | |
| 82 _GridLocation align(_GridLocation span, int size) { | |
| 83 switch (value) { | |
| 84 case 'start': | |
| 85 return new _GridLocation(span.start, size); | |
| 86 case 'end': | |
| 87 return new _GridLocation(span.end - size, size); | |
| 88 case 'center': | |
| 89 size = Math.min(size, span.length); | |
| 90 num center = span.start + span.length / 2; | |
| 91 num left = center - size / 2; | |
| 92 return new _GridLocation(left.round().toInt(), size); | |
| 93 case 'stretch': | |
| 94 return span; | |
| 95 } | |
| 96 } | |
| 97 } | |
| 98 | |
| 99 | |
| 100 /** | |
| 101 * Represents a grid-template. Used in conjunction with a grid-cell to | |
| 102 * place cells in the grid, without needing to specify the exact row/column. | |
| 103 */ | |
| 104 class GridTemplate { | |
| 105 final Map<int, _GridTemplateRect> _rects; | |
| 106 final int _numRows; | |
| 107 | |
| 108 GridTemplate(List<String> rows) | |
| 109 : _rects = new Map<int, _GridTemplateRect>(), | |
| 110 _numRows = rows.length { | |
| 111 _buildRects(rows); | |
| 112 } | |
| 113 | |
| 114 /** Scans the template strings and computes bounds for each one. */ | |
| 115 void _buildRects(List<String> templateRows) { | |
| 116 for (int r = 0; r < templateRows.length; r++) { | |
| 117 String row = templateRows[r]; | |
| 118 for (int c = 0; c < row.length; c++) { | |
| 119 int cell = row.charCodeAt(c); | |
| 120 final rect = _rects[cell]; | |
| 121 if (rect != null) { | |
| 122 rect.add(r + 1, c + 1); | |
| 123 } else { | |
| 124 _rects[cell] = new _GridTemplateRect(cell, r + 1, c + 1); | |
| 125 } | |
| 126 } | |
| 127 } | |
| 128 | |
| 129 // Finally, check that each rectangle is valid (i.e. all spaces filled) | |
| 130 for (final rect in _rects.getValues()) { | |
| 131 rect.checkValid(); | |
| 132 } | |
| 133 } | |
| 134 | |
| 135 /** | |
| 136 * Looks up the given cell in the template, and returns the rect. | |
| 137 */ | |
| 138 _GridTemplateRect lookupCell(String cell) { | |
| 139 if (cell.length != 1) { | |
| 140 throw new UnsupportedOperationException( | |
| 141 'grid-cell "$cell" must be a one character string'); | |
| 142 } | |
| 143 final rect = _rects[cell.charCodeAt(0)]; | |
| 144 if (rect == null) { | |
| 145 throw new UnsupportedOperationException( | |
| 146 'grid-cell "$cell" not found in parent\'s grid-template'); | |
| 147 } | |
| 148 return rect; | |
| 149 } | |
| 150 } | |
| 151 | |
| 152 /** Used by GridTemplate to track a single cell's bounds. */ | |
| 153 class _GridTemplateRect { | |
| 154 int row, column, rowSpan, columnSpan, _count, _char; | |
| 155 _GridTemplateRect(this._char, this.row, this.column) | |
| 156 : rowSpan = 1, columnSpan = 1, _count = 1 {} | |
| 157 | |
| 158 void add(int r, int c) { | |
| 159 assert (r >= row && c >= column); | |
| 160 _count++; | |
| 161 rowSpan = Math.max(rowSpan, r - row + 1); | |
| 162 columnSpan = Math.max(columnSpan, c - column + 1); | |
| 163 } | |
| 164 | |
| 165 void checkValid() { | |
| 166 int expected = rowSpan * columnSpan; | |
| 167 if (expected != _count) { | |
| 168 // TODO(jmesserly): not sure if we should throw here, due to CSS's | |
| 169 // permissiveness. At the moment we're noisy about errors. | |
| 170 String cell = new String.fromCharCodes([_char]); | |
| 171 throw new UnsupportedOperationException('grid-template "$cell"' + | |
| 172 ' is not square, expected $expected cells but got $_count'); | |
| 173 } | |
| 174 } | |
| 175 } | |
| 176 | |
| 177 | |
| 178 /** | |
| 179 * Used to return a row/column and span during parsing of grid-row and | |
| 180 * grid-column during parsing. | |
| 181 */ | |
| 182 class _GridLocation { | |
| 183 final int start, length; | |
| 184 _GridLocation(this.start, this.length) {} | |
| 185 | |
| 186 int get end() => start + length; | |
| 187 } | |
| OLD | NEW |