OLD | NEW |
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 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 | 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 layout; | 5 part of layout; |
6 | 6 |
7 /** | 7 /** |
8 * Implements a grid-based layout system based on: | 8 * Implements a grid-based layout system based on: |
9 * [http://dev.w3.org/csswg/css3-grid-align/] | 9 * [http://dev.w3.org/csswg/css3-grid-align/] |
10 * | 10 * |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
147 * and Grid rows. The goal of the function is to ensure: | 147 * and Grid rows. The goal of the function is to ensure: |
148 * 1. That each Grid Track satisfies its minSizing | 148 * 1. That each Grid Track satisfies its minSizing |
149 * 2. That each Grid Track grows from the breadth which satisfied its | 149 * 2. That each Grid Track grows from the breadth which satisfied its |
150 * minSizing to a breadth which satifies its | 150 * minSizing to a breadth which satifies its |
151 * maxSizing, subject to RemainingSpace. | 151 * maxSizing, subject to RemainingSpace. |
152 */ | 152 */ |
153 // Note: spec does not correctly doc all the parameters to this function. | 153 // Note: spec does not correctly doc all the parameters to this function. |
154 void _computeUsedBreadthOfTracks(List<GridTrack> tracks) { | 154 void _computeUsedBreadthOfTracks(List<GridTrack> tracks) { |
155 | 155 |
156 // TODO(jmesserly): as a performance optimization we could cache this | 156 // TODO(jmesserly): as a performance optimization we could cache this |
157 final items = CollectionUtils.map(view.childViews, (view_) => view_.layout); | 157 final items = view.childViews |
| 158 .mappedBy((view_) => view_.layout) |
| 159 .toList(); |
158 CollectionUtils.sortBy(items, (item) => _getSpanCount(item)); | 160 CollectionUtils.sortBy(items, (item) => _getSpanCount(item)); |
159 | 161 |
160 // 1. Initialize per Grid Track variables | 162 // 1. Initialize per Grid Track variables |
161 for (final t in tracks) { | 163 for (final t in tracks) { |
162 // percentage or length sizing functions will return a value | 164 // percentage or length sizing functions will return a value |
163 // min-content, max-content, or a fraction will be set to 0 | 165 // min-content, max-content, or a fraction will be set to 0 |
164 t.usedBreadth = t.minSizing.resolveLength(_getGridContentSize()); | 166 t.usedBreadth = t.minSizing.resolveLength(_getGridContentSize()); |
165 t.maxBreadth = t.maxSizing.resolveLength(_getGridContentSize()); | 167 t.maxBreadth = t.maxSizing.resolveLength(_getGridContentSize()); |
166 t.updatedBreadth = 0; | 168 t.updatedBreadth = 0; |
167 } | 169 } |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
247 /** | 249 /** |
248 * This method computes a '1fr' value, referred to as the | 250 * This method computes a '1fr' value, referred to as the |
249 * tempBreadth, for a set of Grid Tracks. The value computed | 251 * tempBreadth, for a set of Grid Tracks. The value computed |
250 * will ensure that when the tempBreadth is multiplied by the | 252 * will ensure that when the tempBreadth is multiplied by the |
251 * fractions associated with tracks, that the UsedBreadths of tracks | 253 * fractions associated with tracks, that the UsedBreadths of tracks |
252 * will increase by an amount equal to the maximum of zero and the specified | 254 * will increase by an amount equal to the maximum of zero and the specified |
253 * freeSpace less the sum of the current UsedBreadths. | 255 * freeSpace less the sum of the current UsedBreadths. |
254 */ | 256 */ |
255 num _calcNormalizedFractionBreadth(List<GridTrack> tracks) { | 257 num _calcNormalizedFractionBreadth(List<GridTrack> tracks) { |
256 | 258 |
257 final fractionTracks = tracks.filter((t) => t.maxSizing.isFraction); | 259 final fractionTracks = tracks.where((t) => t.maxSizing.isFraction).toList(); |
258 | 260 |
259 // Note: the spec has various bugs in this function, such as mismatched | 261 // Note: the spec has various bugs in this function, such as mismatched |
260 // identifiers and names that aren't defined. For the most part it's | 262 // identifiers and names that aren't defined. For the most part it's |
261 // possible to figure out the meaning. It's also a bit confused about | 263 // possible to figure out the meaning. It's also a bit confused about |
262 // how to compute spaceNeededFromFractionTracks, but that should just be the | 264 // how to compute spaceNeededFromFractionTracks, but that should just be the |
263 // set to the remaining free space after usedBreadth is accounted for. | 265 // set to the remaining free space after usedBreadth is accounted for. |
264 | 266 |
265 // We use the tempBreadth field to store the normalized fraction breadth | 267 // We use the tempBreadth field to store the normalized fraction breadth |
266 for (final t in fractionTracks) { | 268 for (final t in fractionTracks) { |
267 t.tempBreadth = t.usedBreadth / t.maxSizing.fractionValue; | 269 t.tempBreadth = t.usedBreadth / t.maxSizing.fractionValue; |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
333 * This function prioritizes the distribution of space driven by Grid Items | 335 * This function prioritizes the distribution of space driven by Grid Items |
334 * in content-sized Grid Tracks by the Grid Item's spanCount. That is, Grid | 336 * in content-sized Grid Tracks by the Grid Item's spanCount. That is, Grid |
335 * Items having a lower spanCount have an opportunity to increase the size of | 337 * Items having a lower spanCount have an opportunity to increase the size of |
336 * the Grid Tracks they cover before those with larger SpanCounts. | 338 * the Grid Tracks they cover before those with larger SpanCounts. |
337 * | 339 * |
338 * Note: items are assumed to be already sorted in increasing span count | 340 * Note: items are assumed to be already sorted in increasing span count |
339 */ | 341 */ |
340 void _distributeSpaceBySpanCount(List<ViewLayout> items, | 342 void _distributeSpaceBySpanCount(List<ViewLayout> items, |
341 ContentSizeMode sizeMode, _BreadthAccumulator breadth) { | 343 ContentSizeMode sizeMode, _BreadthAccumulator breadth) { |
342 | 344 |
343 items = items.filter((item) => | 345 items = items.where((item) => |
344 _hasContentSizedTracks(_getTracks(item), sizeMode, breadth)); | 346 _hasContentSizedTracks(_getTracks(item), sizeMode, breadth)).toList(); |
345 | 347 |
346 var tracks = []; | 348 var tracks = []; |
347 | 349 |
348 for (int i = 0; i < items.length; i++) { | 350 for (int i = 0; i < items.length; i++) { |
349 final item = items[i]; | 351 final item = items[i]; |
350 | 352 |
351 final itemTargetSize = item.measureContent(this, _dimension, sizeMode); | 353 final itemTargetSize = item.measureContent(this, _dimension, sizeMode); |
352 | 354 |
353 final spannedTracks = _getTracks(item); | 355 final spannedTracks = _getTracks(item); |
354 _distributeSpaceToTracks(spannedTracks, itemTargetSize, breadth, true); | 356 _distributeSpaceToTracks(spannedTracks, itemTargetSize, breadth, true); |
(...skipping 25 matching lines...) Expand all Loading... |
380 */ | 382 */ |
381 static bool _hasContentSizedTracks(Collection<GridTrack> tracks, | 383 static bool _hasContentSizedTracks(Collection<GridTrack> tracks, |
382 ContentSizeMode sizeMode, _BreadthAccumulator breadth) { | 384 ContentSizeMode sizeMode, _BreadthAccumulator breadth) { |
383 | 385 |
384 for (final t in tracks) { | 386 for (final t in tracks) { |
385 final fn = breadth.getSizingFunction(t); | 387 final fn = breadth.getSizingFunction(t); |
386 if (sizeMode == ContentSizeMode.MAX && fn.isMaxContentSized || | 388 if (sizeMode == ContentSizeMode.MAX && fn.isMaxContentSized || |
387 sizeMode == ContentSizeMode.MIN && fn.isContentSized) { | 389 sizeMode == ContentSizeMode.MIN && fn.isContentSized) { |
388 | 390 |
389 // Make sure we don't cross a fractional track | 391 // Make sure we don't cross a fractional track |
390 return tracks.length == 1 || !tracks.some((t_) => t_.isFractional); | 392 return tracks.length == 1 || !tracks.any((t_) => t_.isFractional); |
391 } | 393 } |
392 } | 394 } |
393 return false; | 395 return false; |
394 } | 396 } |
395 | 397 |
396 /** Ensures that the numbered track exists. */ | 398 /** Ensures that the numbered track exists. */ |
397 void _ensureTrack(List<GridTrack> tracks, TrackSizing sizing, | 399 void _ensureTrack(List<GridTrack> tracks, TrackSizing sizing, |
398 int start, int span) { | 400 int start, int span) { |
399 // Start is 1-based. Make it 0-based. | 401 // Start is 1-based. Make it 0-based. |
400 start -= 1; | 402 start -= 1; |
(...skipping 12 matching lines...) Expand all Loading... |
413 } | 415 } |
414 | 416 |
415 /** | 417 /** |
416 * Scans children creating GridLayoutParams as needed, and creates all of the | 418 * Scans children creating GridLayoutParams as needed, and creates all of the |
417 * rows and columns that we will need. | 419 * rows and columns that we will need. |
418 * | 420 * |
419 * Note: this can potentially create new rows/columns, so this needs to be | 421 * Note: this can potentially create new rows/columns, so this needs to be |
420 * run before the track sizing algorithm. | 422 * run before the track sizing algorithm. |
421 */ | 423 */ |
422 void _ensureAllTracks() { | 424 void _ensureAllTracks() { |
423 final items = CollectionUtils.map(view.childViews, (view_) => view_.layout); | 425 final items = view.childViews.mappedBy((view_) => view_.layout); |
424 | 426 |
425 for (final child in items) { | 427 for (final child in items) { |
426 if (child.layoutParams == null) { | 428 if (child.layoutParams == null) { |
427 final p = new GridLayoutParams(child.view, this); | 429 final p = new GridLayoutParams(child.view, this); |
428 _ensureTrack(_rowTracks, rowSizing, p.row, p.rowSpan); | 430 _ensureTrack(_rowTracks, rowSizing, p.row, p.rowSpan); |
429 _ensureTrack(_columnTracks, columnSizing, p.column, p.columnSpan); | 431 _ensureTrack(_columnTracks, columnSizing, p.column, p.columnSpan); |
430 child.layoutParams = p; | 432 child.layoutParams = p; |
431 } | 433 } |
432 child.cacheExistingBrowserLayout(); | 434 child.cacheExistingBrowserLayout(); |
433 } | 435 } |
434 } | 436 } |
435 | 437 |
436 /** | 438 /** |
437 * Given the track sizes that were computed, position children in the grid. | 439 * Given the track sizes that were computed, position children in the grid. |
438 */ | 440 */ |
439 void _setBoundsOfChildren() { | 441 void _setBoundsOfChildren() { |
440 final items = CollectionUtils.map(view.childViews, (view_) => view_.layout); | 442 final items = view.childViews.mappedBy((view_) => view_.layout); |
441 | 443 |
442 for (final item in items) { | 444 for (final item in items) { |
443 GridLayoutParams childLayout = item.layoutParams; | 445 GridLayoutParams childLayout = item.layoutParams; |
444 var xPos = _getTrackLocationX(childLayout); | 446 var xPos = _getTrackLocationX(childLayout); |
445 var yPos = _getTrackLocationY(childLayout); | 447 var yPos = _getTrackLocationY(childLayout); |
446 | 448 |
447 int left = xPos.start, width = xPos.length; | 449 int left = xPos.start, width = xPos.length; |
448 int top = yPos.start, height = yPos.length; | 450 int top = yPos.start, height = yPos.length; |
449 | 451 |
450 // Somewhat counterintuitively (at least to me): | 452 // Somewhat counterintuitively (at least to me): |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
497 span = childLayout.columnSpan; | 499 span = childLayout.columnSpan; |
498 tracks = _columnTracks; | 500 tracks = _columnTracks; |
499 } else if (_dimension == Dimension.HEIGHT) { | 501 } else if (_dimension == Dimension.HEIGHT) { |
500 start = childLayout.row - 1; | 502 start = childLayout.row - 1; |
501 span = childLayout.rowSpan; | 503 span = childLayout.rowSpan; |
502 tracks = _rowTracks; | 504 tracks = _rowTracks; |
503 } | 505 } |
504 | 506 |
505 assert(start >= 0 && span >= 1); | 507 assert(start >= 0 && span >= 1); |
506 | 508 |
507 final result = new List<GridTrack>(span); | 509 final result = new List<GridTrack>.fixedLength(span); |
508 for (int i = 0; i < span; i++) { | 510 for (int i = 0; i < span; i++) { |
509 result[i] = tracks[start + i]; | 511 result[i] = tracks[start + i]; |
510 } | 512 } |
511 return result; | 513 return result; |
512 } | 514 } |
513 | 515 |
514 int _getSpanCount(ViewLayout item) { | 516 int _getSpanCount(ViewLayout item) { |
515 GridLayoutParams childLayout = item.layoutParams; | 517 GridLayoutParams childLayout = item.layoutParams; |
516 return (_dimension == Dimension.WIDTH ? | 518 return (_dimension == Dimension.WIDTH ? |
517 childLayout.columnSpan : childLayout.rowSpan); | 519 childLayout.columnSpan : childLayout.rowSpan); |
518 } | 520 } |
519 } | 521 } |
OLD | NEW |