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

Side by Side Diff: samples-dev/swarm/swarm_ui_lib/layout/GridLayout.dart

Issue 2828603002: Format samples and samples-dev directories. (Closed)
Patch Set: Created 3 years, 8 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) 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 25 matching lines...) Expand all
36 // - The CSS parsing is not 100% complete, see the parser TODOs. 36 // - The CSS parsing is not 100% complete, see the parser TODOs.
37 // - We don't implement error recovery for invalid combinations of CSS 37 // - We don't implement error recovery for invalid combinations of CSS
38 // properties, or invalid CSS property values. Instead we throw an error. 38 // properties, or invalid CSS property values. Instead we throw an error.
39 // 39 //
40 // TODO(jmesserly): high level performance optimizations we could do: 40 // TODO(jmesserly): high level performance optimizations we could do:
41 // - Optimize for the common case of spanCount = 1 41 // - Optimize for the common case of spanCount = 1
42 // - Optimize for the vbox/hbox case (1 row or 1 column) 42 // - Optimize for the vbox/hbox case (1 row or 1 column)
43 // - Optimize for the case of no content sized tracks 43 // - Optimize for the case of no content sized tracks
44 // - Optimize for the "incremental update" cases 44 // - Optimize for the "incremental update" cases
45 class GridLayout extends ViewLayout { 45 class GridLayout extends ViewLayout {
46
47 /** Configuration parameters defined in CSS. */ 46 /** Configuration parameters defined in CSS. */
48 final GridTrackList rows; 47 final GridTrackList rows;
49 final GridTrackList columns; 48 final GridTrackList columns;
50 final GridTemplate template; 49 final GridTemplate template;
51 50
52 /** The default sizing for new rows. */ 51 /** The default sizing for new rows. */
53 final TrackSizing rowSizing; 52 final TrackSizing rowSizing;
54 53
55 /** The default sizing for new columns. */ 54 /** The default sizing for new columns. */
56 final TrackSizing columnSizing; 55 final TrackSizing columnSizing;
57 56
58 /** 57 /**
59 * This stores the grid's size during a layout. 58 * This stores the grid's size during a layout.
60 * Used for rows/columns with % or fr units. 59 * Used for rows/columns with % or fr units.
61 */ 60 */
62 int _gridWidth, _gridHeight; 61 int _gridWidth, _gridHeight;
63 62
64 /** 63 /**
65 * During a layout, this stores all row/column size information. 64 * During a layout, this stores all row/column size information.
66 * Because grid-items can implicitly specify their own rows/columns, we can't 65 * Because grid-items can implicitly specify their own rows/columns, we can't
67 * compute this until we know the set of items. 66 * compute this until we know the set of items.
68 */ 67 */
69 List<GridTrack> _rowTracks, _columnTracks; 68 List<GridTrack> _rowTracks, _columnTracks;
70 69
71 /** During a layout, tracks which dimension we're processing. */ 70 /** During a layout, tracks which dimension we're processing. */
72 Dimension _dimension; 71 Dimension _dimension;
73 72
74 GridLayout(Positionable view) 73 GridLayout(Positionable view)
75 : super(view), 74 : super(view),
76 rows = _GridTrackParser.parse(view.customStyle['grid-rows']), 75 rows = _GridTrackParser.parse(view.customStyle['grid-rows']),
77 columns = _GridTrackParser.parse(view.customStyle['grid-columns']), 76 columns = _GridTrackParser.parse(view.customStyle['grid-columns']),
78 template = _GridTemplateParser.parse(view.customStyle['grid-template']), 77 template = _GridTemplateParser.parse(view.customStyle['grid-template']),
79 78 rowSizing = _GridTrackParser
80 rowSizing = _GridTrackParser.parseTrackSizing( 79 .parseTrackSizing(view.customStyle['grid-row-sizing']),
81 view.customStyle['grid-row-sizing']), 80 columnSizing = _GridTrackParser
82 81 .parseTrackSizing(view.customStyle['grid-column-sizing']) {
83 columnSizing = _GridTrackParser.parseTrackSizing(
84 view.customStyle['grid-column-sizing']) {
85
86 _rowTracks = rows != null ? rows.tracks : new List<GridTrack>(); 82 _rowTracks = rows != null ? rows.tracks : new List<GridTrack>();
87 _columnTracks = columns != null ? columns.tracks : new List<GridTrack>(); 83 _columnTracks = columns != null ? columns.tracks : new List<GridTrack>();
88 } 84 }
89 85
90
91 int get currentWidth => _gridWidth; 86 int get currentWidth => _gridWidth;
92 int get currentHeight => _gridHeight; 87 int get currentHeight => _gridHeight;
93 88
94 void cacheExistingBrowserLayout() { 89 void cacheExistingBrowserLayout() {
95 // We don't need to do anything as we don't rely on the _cachedViewRect 90 // We don't need to do anything as we don't rely on the _cachedViewRect
96 // when the grid layout is used. 91 // when the grid layout is used.
97 } 92 }
98 93
99 // TODO(jacobr): cleanup this method so that it returns a Future 94 // TODO(jacobr): cleanup this method so that it returns a Future
100 // rather than taking a Completer as an argument. 95 // rather than taking a Completer as an argument.
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
145 /** 140 /**
146 * This is the core Grid Track sizing algorithm. It is run for Grid columns 141 * This is the core Grid Track sizing algorithm. It is run for Grid columns
147 * and Grid rows. The goal of the function is to ensure: 142 * and Grid rows. The goal of the function is to ensure:
148 * 1. That each Grid Track satisfies its minSizing 143 * 1. That each Grid Track satisfies its minSizing
149 * 2. That each Grid Track grows from the breadth which satisfied its 144 * 2. That each Grid Track grows from the breadth which satisfied its
150 * minSizing to a breadth which satifies its 145 * minSizing to a breadth which satifies its
151 * maxSizing, subject to RemainingSpace. 146 * maxSizing, subject to RemainingSpace.
152 */ 147 */
153 // Note: spec does not correctly doc all the parameters to this function. 148 // Note: spec does not correctly doc all the parameters to this function.
154 void _computeUsedBreadthOfTracks(List<GridTrack> tracks) { 149 void _computeUsedBreadthOfTracks(List<GridTrack> tracks) {
155
156 // TODO(jmesserly): as a performance optimization we could cache this 150 // TODO(jmesserly): as a performance optimization we could cache this
157 final items = view.childViews 151 final items = view.childViews.map((view_) => view_.layout).toList();
158 .map((view_) => view_.layout)
159 .toList();
160 CollectionUtils.sortBy(items, (item) => _getSpanCount(item)); 152 CollectionUtils.sortBy(items, (item) => _getSpanCount(item));
161 153
162 // 1. Initialize per Grid Track variables 154 // 1. Initialize per Grid Track variables
163 for (final t in tracks) { 155 for (final t in tracks) {
164 // percentage or length sizing functions will return a value 156 // percentage or length sizing functions will return a value
165 // min-content, max-content, or a fraction will be set to 0 157 // min-content, max-content, or a fraction will be set to 0
166 t.usedBreadth = t.minSizing.resolveLength(_getGridContentSize()); 158 t.usedBreadth = t.minSizing.resolveLength(_getGridContentSize());
167 t.maxBreadth = t.maxSizing.resolveLength(_getGridContentSize()); 159 t.maxBreadth = t.maxSizing.resolveLength(_getGridContentSize());
168 t.updatedBreadth = 0; 160 t.updatedBreadth = 0;
169 } 161 }
(...skipping 15 matching lines...) Expand all
185 177
186 // 4. Resolve content-based MaxTrackSizingFunctions 178 // 4. Resolve content-based MaxTrackSizingFunctions
187 _distributeSpaceBySpanCount(items, ContentSizeMode.MIN, MAX_BREADTH); 179 _distributeSpaceBySpanCount(items, ContentSizeMode.MIN, MAX_BREADTH);
188 180
189 _distributeSpaceBySpanCount(items, ContentSizeMode.MAX, MAX_BREADTH); 181 _distributeSpaceBySpanCount(items, ContentSizeMode.MAX, MAX_BREADTH);
190 182
191 // 5. Grow all Grid Tracks in GridTracks from their usedBreadth up to their 183 // 5. Grow all Grid Tracks in GridTracks from their usedBreadth up to their
192 // maxBreadth value until RemainingSpace is exhausted. 184 // maxBreadth value until RemainingSpace is exhausted.
193 // Note: it's not spec'd what to pass as the accumulator, but usedBreadth 185 // Note: it's not spec'd what to pass as the accumulator, but usedBreadth
194 // seems right. 186 // seems right.
195 _distributeSpaceToTracks(tracks, _getRemainingSpace(tracks), 187 _distributeSpaceToTracks(
196 USED_BREADTH, false); 188 tracks, _getRemainingSpace(tracks), USED_BREADTH, false);
197 189
198 // Spec wording is confusing about which direction this assignment happens, 190 // Spec wording is confusing about which direction this assignment happens,
199 // but this is the way that makes sense. 191 // but this is the way that makes sense.
200 for (final t in tracks) { 192 for (final t in tracks) {
201 t.usedBreadth = t.updatedBreadth; 193 t.usedBreadth = t.updatedBreadth;
202 } 194 }
203 195
204 // 6. Grow all Grid Tracks having a fraction as their maxSizing 196 // 6. Grow all Grid Tracks having a fraction as their maxSizing
205 final tempBreadth = _calcNormalizedFractionBreadth(tracks); 197 final tempBreadth = _calcNormalizedFractionBreadth(tracks);
206 for (final t in tracks) { 198 for (final t in tracks) {
207 t.usedBreadth = Math.max(t.usedBreadth, 199 t.usedBreadth =
208 tempBreadth * t.maxSizing.fractionValue); 200 Math.max(t.usedBreadth, tempBreadth * t.maxSizing.fractionValue);
209 } 201 }
210 202
211 _computeTrackPositions(tracks); 203 _computeTrackPositions(tracks);
212 } 204 }
213 205
214 /** 206 /**
215 * Final steps to finish positioning tracks. Takes the track size and uses 207 * Final steps to finish positioning tracks. Takes the track size and uses
216 * it to get start and end positions. Also rounds the positions to integers. 208 * it to get start and end positions. Also rounds the positions to integers.
217 */ 209 */
218 void _computeTrackPositions(List<GridTrack> tracks) { 210 void _computeTrackPositions(List<GridTrack> tracks) {
(...skipping 29 matching lines...) Expand all
248 240
249 /** 241 /**
250 * This method computes a '1fr' value, referred to as the 242 * This method computes a '1fr' value, referred to as the
251 * tempBreadth, for a set of Grid Tracks. The value computed 243 * tempBreadth, for a set of Grid Tracks. The value computed
252 * will ensure that when the tempBreadth is multiplied by the 244 * will ensure that when the tempBreadth is multiplied by the
253 * fractions associated with tracks, that the UsedBreadths of tracks 245 * fractions associated with tracks, that the UsedBreadths of tracks
254 * will increase by an amount equal to the maximum of zero and the specified 246 * will increase by an amount equal to the maximum of zero and the specified
255 * freeSpace less the sum of the current UsedBreadths. 247 * freeSpace less the sum of the current UsedBreadths.
256 */ 248 */
257 num _calcNormalizedFractionBreadth(List<GridTrack> tracks) { 249 num _calcNormalizedFractionBreadth(List<GridTrack> tracks) {
258
259 final fractionTracks = tracks.where((t) => t.maxSizing.isFraction).toList(); 250 final fractionTracks = tracks.where((t) => t.maxSizing.isFraction).toList();
260 251
261 // Note: the spec has various bugs in this function, such as mismatched 252 // Note: the spec has various bugs in this function, such as mismatched
262 // identifiers and names that aren't defined. For the most part it's 253 // identifiers and names that aren't defined. For the most part it's
263 // possible to figure out the meaning. It's also a bit confused about 254 // possible to figure out the meaning. It's also a bit confused about
264 // how to compute spaceNeededFromFractionTracks, but that should just be the 255 // how to compute spaceNeededFromFractionTracks, but that should just be the
265 // set to the remaining free space after usedBreadth is accounted for. 256 // set to the remaining free space after usedBreadth is accounted for.
266 257
267 // We use the tempBreadth field to store the normalized fraction breadth 258 // We use the tempBreadth field to store the normalized fraction breadth
268 for (final t in fractionTracks) { 259 for (final t in fractionTracks) {
(...skipping 19 matching lines...) Expand all
288 return spaceNeededFromFractionTracks / accumulatedFractions; 279 return spaceNeededFromFractionTracks / accumulatedFractions;
289 } 280 }
290 281
291 /** 282 /**
292 * Ensures that for each Grid Track in tracks, a value will be 283 * Ensures that for each Grid Track in tracks, a value will be
293 * computed, updatedBreadth, that represents the Grid Track's share of 284 * computed, updatedBreadth, that represents the Grid Track's share of
294 * freeSpace. 285 * freeSpace.
295 */ 286 */
296 void _distributeSpaceToTracks(List<GridTrack> tracks, num freeSpace, 287 void _distributeSpaceToTracks(List<GridTrack> tracks, num freeSpace,
297 _BreadthAccumulator breadth, bool ignoreMaxBreadth) { 288 _BreadthAccumulator breadth, bool ignoreMaxBreadth) {
298
299 // TODO(jmesserly): in some cases it would be safe to sort the passed in 289 // TODO(jmesserly): in some cases it would be safe to sort the passed in
300 // list in place. Not always though. 290 // list in place. Not always though.
301 tracks = CollectionUtils.orderBy(tracks, 291 tracks = CollectionUtils.orderBy(
302 (t) => t.maxBreadth - breadth.getSize(t)); 292 tracks, (t) => t.maxBreadth - breadth.getSize(t));
303 293
304 // Give each Grid Track an equal share of the space, but without exceeding 294 // Give each Grid Track an equal share of the space, but without exceeding
305 // their maxBreadth values. Because there are different MaxBreadths 295 // their maxBreadth values. Because there are different MaxBreadths
306 // assigned to the different Grid Tracks, this can result in uneven growth. 296 // assigned to the different Grid Tracks, this can result in uneven growth.
307 for (int i = 0; i < tracks.length; i++) { 297 for (int i = 0; i < tracks.length; i++) {
308 num share = freeSpace / (tracks.length - i); 298 num share = freeSpace / (tracks.length - i);
309 share = Math.min(share, tracks[i].maxBreadth); 299 share = Math.min(share, tracks[i].maxBreadth);
310 tracks[i].tempBreadth = share; 300 tracks[i].tempBreadth = share;
311 freeSpace -= share; 301 freeSpace -= share;
312 } 302 }
(...skipping 21 matching lines...) Expand all
334 /** 324 /**
335 * This function prioritizes the distribution of space driven by Grid Items 325 * This function prioritizes the distribution of space driven by Grid Items
336 * in content-sized Grid Tracks by the Grid Item's spanCount. That is, Grid 326 * in content-sized Grid Tracks by the Grid Item's spanCount. That is, Grid
337 * Items having a lower spanCount have an opportunity to increase the size of 327 * Items having a lower spanCount have an opportunity to increase the size of
338 * the Grid Tracks they cover before those with larger SpanCounts. 328 * the Grid Tracks they cover before those with larger SpanCounts.
339 * 329 *
340 * Note: items are assumed to be already sorted in increasing span count 330 * Note: items are assumed to be already sorted in increasing span count
341 */ 331 */
342 void _distributeSpaceBySpanCount(List<ViewLayout> items, 332 void _distributeSpaceBySpanCount(List<ViewLayout> items,
343 ContentSizeMode sizeMode, _BreadthAccumulator breadth) { 333 ContentSizeMode sizeMode, _BreadthAccumulator breadth) {
344 334 items = items
345 items = items.where((item) => 335 .where((item) =>
346 _hasContentSizedTracks(_getTracks(item), sizeMode, breadth)).toList(); 336 _hasContentSizedTracks(_getTracks(item), sizeMode, breadth))
337 .toList();
347 338
348 var tracks = []; 339 var tracks = [];
349 340
350 for (int i = 0; i < items.length; i++) { 341 for (int i = 0; i < items.length; i++) {
351 final item = items[i]; 342 final item = items[i];
352 343
353 final itemTargetSize = item.measureContent(this, _dimension, sizeMode); 344 final itemTargetSize = item.measureContent(this, _dimension, sizeMode);
354 345
355 final spannedTracks = _getTracks(item); 346 final spannedTracks = _getTracks(item);
356 _distributeSpaceToTracks(spannedTracks, itemTargetSize, breadth, true); 347 _distributeSpaceToTracks(spannedTracks, itemTargetSize, breadth, true);
357 348
358 // Remember that we need to update the sizes on these tracks 349 // Remember that we need to update the sizes on these tracks
359 tracks.addAll(spannedTracks); 350 tracks.addAll(spannedTracks);
360 351
361 // Each time we transition to a new spanCount, update any modified tracks 352 // Each time we transition to a new spanCount, update any modified tracks
362 bool spanCountFinished = false; 353 bool spanCountFinished = false;
363 if (i + 1 == items.length) { 354 if (i + 1 == items.length) {
364 spanCountFinished = true; 355 spanCountFinished = true;
365 } else if (_getSpanCount(item) != _getSpanCount(items[i + 1])) { 356 } else if (_getSpanCount(item) != _getSpanCount(items[i + 1])) {
366 spanCountFinished = true; 357 spanCountFinished = true;
367 } 358 }
368 359
369 if (spanCountFinished) { 360 if (spanCountFinished) {
370 for (final t in tracks) { 361 for (final t in tracks) {
371 breadth.setSize(t, 362 breadth.setSize(t, Math.max(breadth.getSize(t), t.updatedBreadth));
372 Math.max(breadth.getSize(t), t.updatedBreadth));
373 } 363 }
374 tracks = []; 364 tracks = [];
375 } 365 }
376 } 366 }
377 } 367 }
378 368
379 /** 369 /**
380 * Returns true if we have an appropriate content sized dimension, and don't 370 * Returns true if we have an appropriate content sized dimension, and don't
381 * cross a fractional track. 371 * cross a fractional track.
382 */ 372 */
383 static bool _hasContentSizedTracks(Iterable<GridTrack> tracks, 373 static bool _hasContentSizedTracks(Iterable<GridTrack> tracks,
384 ContentSizeMode sizeMode, _BreadthAccumulator breadth) { 374 ContentSizeMode sizeMode, _BreadthAccumulator breadth) {
385
386 for (final t in tracks) { 375 for (final t in tracks) {
387 final fn = breadth.getSizingFunction(t); 376 final fn = breadth.getSizingFunction(t);
388 if (sizeMode == ContentSizeMode.MAX && fn.isMaxContentSized || 377 if (sizeMode == ContentSizeMode.MAX && fn.isMaxContentSized ||
389 sizeMode == ContentSizeMode.MIN && fn.isContentSized) { 378 sizeMode == ContentSizeMode.MIN && fn.isContentSized) {
390
391 // Make sure we don't cross a fractional track 379 // Make sure we don't cross a fractional track
392 return tracks.length == 1 || !tracks.any((t_) => t_.isFractional); 380 return tracks.length == 1 || !tracks.any((t_) => t_.isFractional);
393 } 381 }
394 } 382 }
395 return false; 383 return false;
396 } 384 }
397 385
398 /** Ensures that the numbered track exists. */ 386 /** Ensures that the numbered track exists. */
399 void _ensureTrack(List<GridTrack> tracks, TrackSizing sizing, 387 void _ensureTrack(
400 int start, int span) { 388 List<GridTrack> tracks, TrackSizing sizing, int start, int span) {
401 // Start is 1-based. Make it 0-based. 389 // Start is 1-based. Make it 0-based.
402 start -= 1; 390 start -= 1;
403 391
404 // Grow the list if needed 392 // Grow the list if needed
405 int length = start + span; 393 int length = start + span;
406 int first = Math.min(start, tracks.length); 394 int first = Math.min(start, tracks.length);
407 tracks.length = Math.max(tracks.length, length); 395 tracks.length = Math.max(tracks.length, length);
408 396
409 // Fill in tracks 397 // Fill in tracks
410 for (int i = first; i < length; i++) { 398 for (int i = first; i < length; i++) {
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
508 496
509 final result = new List<GridTrack>(span); 497 final result = new List<GridTrack>(span);
510 for (int i = 0; i < span; i++) { 498 for (int i = 0; i < span; i++) {
511 result[i] = tracks[start + i]; 499 result[i] = tracks[start + i];
512 } 500 }
513 return result; 501 return result;
514 } 502 }
515 503
516 int _getSpanCount(ViewLayout item) { 504 int _getSpanCount(ViewLayout item) {
517 GridLayoutParams childLayout = item.layoutParams; 505 GridLayoutParams childLayout = item.layoutParams;
518 return (_dimension == Dimension.WIDTH ? 506 return (_dimension == Dimension.WIDTH
519 childLayout.columnSpan : childLayout.rowSpan); 507 ? childLayout.columnSpan
508 : childLayout.rowSpan);
520 } 509 }
521 } 510 }
OLDNEW
« no previous file with comments | « samples-dev/swarm/swarm_ui_lib/base/base.dart ('k') | samples-dev/swarm/swarm_ui_lib/layout/GridLayoutParams.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698