mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 08:24:39 +00:00
Migrate swarm's swarm_ui_lib/layout
Change-Id: I3c0809b8115d0b3244824e542c408ece78368bc5 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/248346 Reviewed-by: Bob Nystrom <rnystrom@google.com> Commit-Queue: Vijay Menon <vsm@google.com>
This commit is contained in:
parent
141c05d7d7
commit
65e8411498
|
@ -2,9 +2,6 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
|
||||
part of layout;
|
||||
|
||||
/**
|
||||
|
@ -47,9 +44,9 @@ part of layout;
|
|||
// - Optimize for the "incremental update" cases
|
||||
class GridLayout extends ViewLayout {
|
||||
/** Configuration parameters defined in CSS. */
|
||||
final GridTrackList rows;
|
||||
final GridTrackList columns;
|
||||
final GridTemplate template;
|
||||
final GridTrackList? rows;
|
||||
final GridTrackList? columns;
|
||||
final GridTemplate? template;
|
||||
|
||||
/** The default sizing for new rows. */
|
||||
final TrackSizing rowSizing;
|
||||
|
@ -61,33 +58,33 @@ class GridLayout extends ViewLayout {
|
|||
* This stores the grid's size during a layout.
|
||||
* Used for rows/columns with % or fr units.
|
||||
*/
|
||||
int _gridWidth, _gridHeight;
|
||||
int? _gridWidth, _gridHeight;
|
||||
|
||||
/**
|
||||
* During a layout, this stores all row/column size information.
|
||||
* Because grid-items can implicitly specify their own rows/columns, we can't
|
||||
* compute this until we know the set of items.
|
||||
*/
|
||||
List<GridTrack> _rowTracks, _columnTracks;
|
||||
late List<GridTrack> _rowTracks, _columnTracks;
|
||||
|
||||
/** During a layout, tracks which dimension we're processing. */
|
||||
Dimension _dimension;
|
||||
Dimension? _dimension;
|
||||
|
||||
GridLayout(Positionable view)
|
||||
: rows = _GridTrackParser.parse(view.customStyle['grid-rows']),
|
||||
columns = _GridTrackParser.parse(view.customStyle['grid-columns']),
|
||||
template = _GridTemplateParser.parse(view.customStyle['grid-template']),
|
||||
rowSizing = _GridTrackParser
|
||||
.parseTrackSizing(view.customStyle['grid-row-sizing']),
|
||||
columnSizing = _GridTrackParser
|
||||
.parseTrackSizing(view.customStyle['grid-column-sizing']),
|
||||
rowSizing = _GridTrackParser.parseTrackSizing(
|
||||
view.customStyle['grid-row-sizing']),
|
||||
columnSizing = _GridTrackParser.parseTrackSizing(
|
||||
view.customStyle['grid-column-sizing']),
|
||||
super(view) {
|
||||
_rowTracks = rows != null ? rows.tracks : new List<GridTrack>();
|
||||
_columnTracks = columns != null ? columns.tracks : new List<GridTrack>();
|
||||
_rowTracks = rows?.tracks ?? [];
|
||||
_columnTracks = columns?.tracks ?? [];
|
||||
}
|
||||
|
||||
int get currentWidth => _gridWidth;
|
||||
int get currentHeight => _gridHeight;
|
||||
int? get currentWidth => _gridWidth;
|
||||
int? get currentHeight => _gridHeight;
|
||||
|
||||
void cacheExistingBrowserLayout() {
|
||||
// We don't need to do anything as we don't rely on the _cachedViewRect
|
||||
|
@ -97,11 +94,11 @@ class GridLayout extends ViewLayout {
|
|||
// TODO(jacobr): cleanup this method so that it returns a Future
|
||||
// rather than taking a Completer as an argument.
|
||||
/** The main entry point for layout computation. */
|
||||
void measureLayout(Future<Size> size, Completer<bool> changed) {
|
||||
void measureLayout(Future<Size> size, Completer<bool>? changed) {
|
||||
_ensureAllTracks();
|
||||
size.then((value) {
|
||||
_gridWidth = value.width;
|
||||
_gridHeight = value.height;
|
||||
_gridWidth = value.width as int?;
|
||||
_gridHeight = value.height as int?;
|
||||
|
||||
if (_rowTracks.length > 0 && _columnTracks.length > 0) {
|
||||
_measureTracks();
|
||||
|
@ -135,7 +132,7 @@ class GridLayout extends ViewLayout {
|
|||
}
|
||||
|
||||
num _getRemainingSpace(List<GridTrack> tracks) {
|
||||
num remaining = _getGridContentSize();
|
||||
num remaining = _getGridContentSize()!;
|
||||
remaining -= CollectionUtils.sum(tracks, (t) => t.usedBreadth);
|
||||
return Math.max(0, remaining);
|
||||
}
|
||||
|
@ -152,7 +149,7 @@ class GridLayout extends ViewLayout {
|
|||
void _computeUsedBreadthOfTracks(List<GridTrack> tracks) {
|
||||
// TODO(jmesserly): as a performance optimization we could cache this
|
||||
final items = view.childViews.map((view_) => view_.layout).toList();
|
||||
CollectionUtils.sortBy(items, (item) => _getSpanCount(item));
|
||||
CollectionUtils.sortBy(items, (item) => _getSpanCount(item)!);
|
||||
|
||||
// 1. Initialize per Grid Track variables
|
||||
for (final t in tracks) {
|
||||
|
@ -224,7 +221,7 @@ class GridLayout extends ViewLayout {
|
|||
num finalPosition = position;
|
||||
|
||||
for (int i = 0; i < tracks.length; i++) {
|
||||
int startEdge = tracks[i].start;
|
||||
int startEdge = tracks[i].start as int;
|
||||
int endEdge;
|
||||
if (i < tracks.length - 1) {
|
||||
endEdge = tracks[i + 1].start.round();
|
||||
|
@ -266,7 +263,7 @@ class GridLayout extends ViewLayout {
|
|||
CollectionUtils.sortBy(fractionTracks, (t) => t.tempBreadth);
|
||||
|
||||
num spaceNeededFromFractionTracks = _getRemainingSpace(tracks);
|
||||
num currentBandFractionBreadth = 0;
|
||||
num? currentBandFractionBreadth = 0;
|
||||
num accumulatedFractions = 0;
|
||||
for (final t in fractionTracks) {
|
||||
if (t.tempBreadth != currentBandFractionBreadth) {
|
||||
|
@ -287,7 +284,7 @@ class GridLayout extends ViewLayout {
|
|||
* computed, updatedBreadth, that represents the Grid Track's share of
|
||||
* freeSpace.
|
||||
*/
|
||||
void _distributeSpaceToTracks(List<GridTrack> tracks, num freeSpace,
|
||||
void _distributeSpaceToTracks(List<GridTrack?> tracks, num? freeSpace,
|
||||
_BreadthAccumulator breadth, bool ignoreMaxBreadth) {
|
||||
// TODO(jmesserly): in some cases it would be safe to sort the passed in
|
||||
// list in place. Not always though.
|
||||
|
@ -298,9 +295,9 @@ class GridLayout extends ViewLayout {
|
|||
// their maxBreadth values. Because there are different MaxBreadths
|
||||
// assigned to the different Grid Tracks, this can result in uneven growth.
|
||||
for (int i = 0; i < tracks.length; i++) {
|
||||
num share = freeSpace / (tracks.length - i);
|
||||
share = Math.min(share, tracks[i].maxBreadth);
|
||||
tracks[i].tempBreadth = share;
|
||||
num share = freeSpace! / (tracks.length - i);
|
||||
share = Math.min(share, tracks[i]!.maxBreadth);
|
||||
tracks[i]!.tempBreadth = share;
|
||||
freeSpace -= share;
|
||||
}
|
||||
|
||||
|
@ -309,10 +306,10 @@ class GridLayout extends ViewLayout {
|
|||
// evenly and assign it to each Grid Track without regard for its
|
||||
// maxBreadth. This phase of growth will always be even, but only occurs
|
||||
// when the ignoreMaxBreadth flag is true.
|
||||
if (freeSpace > 0 && ignoreMaxBreadth) {
|
||||
if (freeSpace! > 0 && ignoreMaxBreadth) {
|
||||
for (int i = 0; i < tracks.length; i++) {
|
||||
final share = freeSpace / (tracks.length - i);
|
||||
tracks[i].tempBreadth += share;
|
||||
final share = freeSpace! / (tracks.length - i);
|
||||
tracks[i]!.tempBreadth = tracks[i]!.tempBreadth + share;
|
||||
freeSpace -= share;
|
||||
}
|
||||
}
|
||||
|
@ -320,7 +317,7 @@ class GridLayout extends ViewLayout {
|
|||
// Note: the spec has us updating all grid tracks, not just the passed in
|
||||
// tracks, but I think that's a spec bug.
|
||||
for (final t in tracks) {
|
||||
t.updatedBreadth = Math.max(t.updatedBreadth, t.tempBreadth);
|
||||
t!.updatedBreadth = Math.max(t.updatedBreadth, t.tempBreadth);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -352,7 +349,7 @@ class GridLayout extends ViewLayout {
|
|||
// Remember that we need to update the sizes on these tracks
|
||||
tracks.addAll(spannedTracks);
|
||||
|
||||
// Each time we transition to a new spanCount, update any modified tracks
|
||||
// Each time we transition to a spanCount, update any modified tracks
|
||||
bool spanCountFinished = false;
|
||||
if (i + 1 == items.length) {
|
||||
spanCountFinished = true;
|
||||
|
@ -362,7 +359,7 @@ class GridLayout extends ViewLayout {
|
|||
|
||||
if (spanCountFinished) {
|
||||
for (final t in tracks) {
|
||||
breadth.setSize(t, Math.max(breadth.getSize(t), t.updatedBreadth));
|
||||
breadth.setSize(t, Math.max(breadth.getSize(t)!, t.updatedBreadth));
|
||||
}
|
||||
tracks = [];
|
||||
}
|
||||
|
@ -373,14 +370,14 @@ class GridLayout extends ViewLayout {
|
|||
* Returns true if we have an appropriate content sized dimension, and don't
|
||||
* cross a fractional track.
|
||||
*/
|
||||
static bool _hasContentSizedTracks(Iterable<GridTrack> tracks,
|
||||
static bool _hasContentSizedTracks(Iterable<GridTrack?> tracks,
|
||||
ContentSizeMode sizeMode, _BreadthAccumulator breadth) {
|
||||
for (final t in tracks) {
|
||||
final fn = breadth.getSizingFunction(t);
|
||||
if (sizeMode == ContentSizeMode.MAX && fn.isMaxContentSized ||
|
||||
sizeMode == ContentSizeMode.MIN && fn.isContentSized) {
|
||||
// Make sure we don't cross a fractional track
|
||||
return tracks.length == 1 || !tracks.any((t_) => t_.isFractional);
|
||||
return tracks.length == 1 || !tracks.any((t_) => t_!.isFractional);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
@ -400,7 +397,7 @@ class GridLayout extends ViewLayout {
|
|||
// Fill in tracks
|
||||
for (int i = first; i < length; i++) {
|
||||
if (tracks[i] == null) {
|
||||
tracks[i] = new GridTrack(sizing);
|
||||
tracks[i] = GridTrack(sizing);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -409,7 +406,7 @@ class GridLayout extends ViewLayout {
|
|||
* Scans children creating GridLayoutParams as needed, and creates all of the
|
||||
* rows and columns that we will need.
|
||||
*
|
||||
* Note: this can potentially create new rows/columns, so this needs to be
|
||||
* Note: this can potentially create new qrows/columns, so this needs to be
|
||||
* run before the track sizing algorithm.
|
||||
*/
|
||||
void _ensureAllTracks() {
|
||||
|
@ -417,9 +414,9 @@ class GridLayout extends ViewLayout {
|
|||
|
||||
for (final child in items) {
|
||||
if (child.layoutParams == null) {
|
||||
final p = new GridLayoutParams(child.view, this);
|
||||
_ensureTrack(_rowTracks, rowSizing, p.row, p.rowSpan);
|
||||
_ensureTrack(_columnTracks, columnSizing, p.column, p.columnSpan);
|
||||
final p = GridLayoutParams(child.view, this);
|
||||
_ensureTrack(_rowTracks, rowSizing, p.row!, p.rowSpan!);
|
||||
_ensureTrack(_columnTracks, columnSizing, p.column!, p.columnSpan!);
|
||||
child.layoutParams = p;
|
||||
}
|
||||
child.cacheExistingBrowserLayout();
|
||||
|
@ -433,12 +430,12 @@ class GridLayout extends ViewLayout {
|
|||
final items = view.childViews.map((view_) => view_.layout);
|
||||
|
||||
for (final item in items) {
|
||||
GridLayoutParams childLayout = item.layoutParams;
|
||||
GridLayoutParams childLayout = item.layoutParams as GridLayoutParams;
|
||||
var xPos = _getTrackLocationX(childLayout);
|
||||
var yPos = _getTrackLocationY(childLayout);
|
||||
|
||||
int left = xPos.start, width = xPos.length;
|
||||
int top = yPos.start, height = yPos.length;
|
||||
int? left = xPos.start, width = xPos.length;
|
||||
int? top = yPos.start, height = yPos.length;
|
||||
|
||||
// Somewhat counterintuitively (at least to me):
|
||||
// grid-col-align is the horizontal alignment
|
||||
|
@ -446,11 +443,11 @@ class GridLayout extends ViewLayout {
|
|||
xPos = childLayout.columnAlign.align(xPos, item.currentWidth);
|
||||
yPos = childLayout.rowAlign.align(yPos, item.currentHeight);
|
||||
|
||||
item.setBounds(xPos.start, yPos.start, xPos.length, yPos.length);
|
||||
item.setBounds(xPos.start, yPos.start, xPos.length!, yPos.length!);
|
||||
}
|
||||
}
|
||||
|
||||
num _getGridContentSize() {
|
||||
num? _getGridContentSize() {
|
||||
if (_dimension == Dimension.WIDTH) {
|
||||
return _gridWidth;
|
||||
} else if (_dimension == Dimension.HEIGHT) {
|
||||
|
@ -459,55 +456,52 @@ class GridLayout extends ViewLayout {
|
|||
}
|
||||
|
||||
_GridLocation _getTrackLocationX(GridLayoutParams childLayout) {
|
||||
int start = childLayout.column - 1;
|
||||
int end = start + childLayout.columnSpan - 1;
|
||||
int start = childLayout.column! - 1;
|
||||
int end = start + childLayout.columnSpan! - 1;
|
||||
|
||||
start = _columnTracks[start].start;
|
||||
end = _columnTracks[end].end;
|
||||
start = _columnTracks[start].start as int;
|
||||
end = _columnTracks[end].end as int;
|
||||
|
||||
return new _GridLocation(start, end - start);
|
||||
return _GridLocation(start, end - start);
|
||||
}
|
||||
|
||||
_GridLocation _getTrackLocationY(GridLayoutParams childLayout) {
|
||||
int start = childLayout.row - 1;
|
||||
int end = start + childLayout.rowSpan - 1;
|
||||
int start = childLayout.row! - 1;
|
||||
int end = start + childLayout.rowSpan! - 1;
|
||||
|
||||
start = _rowTracks[start].start;
|
||||
end = _rowTracks[end].end;
|
||||
start = _rowTracks[start].start as int;
|
||||
end = _rowTracks[end].end as int;
|
||||
|
||||
return new _GridLocation(start, end - start);
|
||||
return _GridLocation(start, end - start);
|
||||
}
|
||||
|
||||
/** Gets the tracks that this item crosses. */
|
||||
// TODO(jmesserly): might be better to return an iterable
|
||||
List<GridTrack> _getTracks(ViewLayout item) {
|
||||
GridLayoutParams childLayout = item.layoutParams;
|
||||
List<GridTrack?> _getTracks(ViewLayout item) {
|
||||
GridLayoutParams? childLayout = item.layoutParams as GridLayoutParams?;
|
||||
|
||||
int start, span;
|
||||
List<GridTrack> tracks;
|
||||
int? start, span;
|
||||
List<GridTrack>? tracks;
|
||||
if (_dimension == Dimension.WIDTH) {
|
||||
start = childLayout.column - 1;
|
||||
start = childLayout!.column! - 1;
|
||||
span = childLayout.columnSpan;
|
||||
tracks = _columnTracks;
|
||||
} else if (_dimension == Dimension.HEIGHT) {
|
||||
start = childLayout.row - 1;
|
||||
start = childLayout!.row! - 1;
|
||||
span = childLayout.rowSpan;
|
||||
tracks = _rowTracks;
|
||||
}
|
||||
|
||||
assert(start >= 0 && span >= 1);
|
||||
assert(start! >= 0 && span! >= 1);
|
||||
|
||||
final result = new List<GridTrack>(span);
|
||||
for (int i = 0; i < span; i++) {
|
||||
result[i] = tracks[start + i];
|
||||
}
|
||||
final result = List<GridTrack>.generate(span!, (i) => tracks![start! + i]);
|
||||
return result;
|
||||
}
|
||||
|
||||
int _getSpanCount(ViewLayout item) {
|
||||
GridLayoutParams childLayout = item.layoutParams;
|
||||
int? _getSpanCount(ViewLayout item) {
|
||||
GridLayoutParams? childLayout = item.layoutParams as GridLayoutParams?;
|
||||
return (_dimension == Dimension.WIDTH
|
||||
? childLayout.columnSpan
|
||||
: childLayout.rowSpan);
|
||||
? childLayout!.columnSpan
|
||||
: childLayout!.rowSpan);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
part of layout;
|
||||
|
||||
/**
|
||||
|
@ -16,25 +14,24 @@ part of layout;
|
|||
// field ends up being mentioned 4 times instead of just twice.
|
||||
class GridLayoutParams extends LayoutParams {
|
||||
/** The coordinates of this item in the grid. */
|
||||
int row;
|
||||
int column;
|
||||
int rowSpan;
|
||||
int columnSpan;
|
||||
int layer;
|
||||
int? row;
|
||||
int? column;
|
||||
int? rowSpan;
|
||||
int? columnSpan;
|
||||
int? layer;
|
||||
|
||||
/** Alignment within its box */
|
||||
GridItemAlignment rowAlign;
|
||||
GridItemAlignment columnAlign;
|
||||
|
||||
GridLayoutParams(Positionable view, GridLayout layout) : super(view.node) {
|
||||
GridLayoutParams(Positionable view, GridLayout layout)
|
||||
: rowAlign =
|
||||
GridItemAlignment.fromString(view.customStyle['grid-row-align']),
|
||||
columnAlign =
|
||||
GridItemAlignment.fromString(view.customStyle['grid-column-align']),
|
||||
super(view.node) {
|
||||
// TODO(jmesserly): this can be cleaned up a lot by just passing "view"
|
||||
// into the parsers.
|
||||
|
||||
rowAlign =
|
||||
new GridItemAlignment.fromString(view.customStyle['grid-row-align']);
|
||||
columnAlign =
|
||||
new GridItemAlignment.fromString(view.customStyle['grid-column-align']);
|
||||
|
||||
layer = StringUtils.parseInt(view.customStyle['grid-layer'], 0);
|
||||
|
||||
rowSpan = StringUtils.parseInt(view.customStyle['grid-row-span']);
|
||||
|
@ -45,7 +42,7 @@ class GridLayoutParams extends LayoutParams {
|
|||
row = line.start;
|
||||
if (line.length != null) {
|
||||
if (rowSpan != null) {
|
||||
throw new UnsupportedError(
|
||||
throw UnsupportedError(
|
||||
'grid-row-span cannot be with grid-row that defines an end');
|
||||
}
|
||||
rowSpan = line.length;
|
||||
|
@ -59,14 +56,14 @@ class GridLayoutParams extends LayoutParams {
|
|||
column = line.start;
|
||||
if (line.length != null) {
|
||||
if (columnSpan != null) {
|
||||
throw new UnsupportedError(
|
||||
throw UnsupportedError(
|
||||
'grid-column-span cannot be with grid-column that defines an end');
|
||||
}
|
||||
columnSpan = line.length;
|
||||
}
|
||||
}
|
||||
|
||||
String cell = _GridTemplateParser.parseCell(view.customStyle['grid-cell']);
|
||||
String? cell = _GridTemplateParser.parseCell(view.customStyle['grid-cell']);
|
||||
if (cell != null && cell != 'none') {
|
||||
// TODO(jmesserly): I didn't see anything spec'd about conflicts and
|
||||
// error handling. For now, throw an error on a misconfigured view.
|
||||
|
@ -76,16 +73,16 @@ class GridLayoutParams extends LayoutParams {
|
|||
column != null ||
|
||||
rowSpan != null ||
|
||||
columnSpan != null) {
|
||||
throw new UnsupportedError(
|
||||
throw UnsupportedError(
|
||||
'grid-cell cannot be used with grid-row and grid-column');
|
||||
}
|
||||
|
||||
if (layout.template == null) {
|
||||
throw new UnsupportedError(
|
||||
throw UnsupportedError(
|
||||
'grid-cell requires that grid-template is set on the parent');
|
||||
}
|
||||
|
||||
final rect = layout.template.lookupCell(cell);
|
||||
final rect = layout.template!.lookupCell(cell);
|
||||
row = rect.row;
|
||||
column = rect.column;
|
||||
rowSpan = rect.rowSpan;
|
||||
|
@ -96,7 +93,7 @@ class GridLayoutParams extends LayoutParams {
|
|||
if (columnSpan == null) columnSpan = 1;
|
||||
|
||||
if (row == null && column == null) {
|
||||
throw new UnsupportedError('grid-flow is not implemented' +
|
||||
throw UnsupportedError('grid-flow is not implemented' +
|
||||
' so at least one row or one column must be defined');
|
||||
}
|
||||
|
||||
|
@ -104,6 +101,6 @@ class GridLayoutParams extends LayoutParams {
|
|||
if (column == null) column = 1;
|
||||
}
|
||||
|
||||
assert(row > 0 && rowSpan > 0 && column > 0 && columnSpan > 0);
|
||||
assert(row! > 0 && rowSpan! > 0 && column! > 0 && columnSpan! > 0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
part of layout;
|
||||
|
||||
/**
|
||||
|
@ -56,7 +54,7 @@ class _Parser {
|
|||
}
|
||||
|
||||
void _error(String msg) {
|
||||
throw new SyntaxErrorException(msg, _src, _offset);
|
||||
throw SyntaxErrorException(msg, _src, _offset);
|
||||
}
|
||||
|
||||
int get length => _src.length;
|
||||
|
@ -132,7 +130,7 @@ class _Parser {
|
|||
}
|
||||
}
|
||||
|
||||
String _maybeEatString() {
|
||||
String? _maybeEatString() {
|
||||
// TODO(jmesserly): make this match CSS string parsing
|
||||
String quote = "'";
|
||||
if (!_maybeEat(quote)) {
|
||||
|
@ -171,7 +169,7 @@ class _Parser {
|
|||
}
|
||||
|
||||
/** Eats an integer. */
|
||||
int _maybeEatInt() {
|
||||
int? _maybeEatInt() {
|
||||
int start = _offset;
|
||||
bool dot = false;
|
||||
while (_offset < length && _isDigit(_peekChar())) {
|
||||
|
@ -186,8 +184,8 @@ class _Parser {
|
|||
}
|
||||
|
||||
/** Eats an integer. */
|
||||
int _eatInt() {
|
||||
int result = _maybeEatInt();
|
||||
int? _eatInt() {
|
||||
int? result = _maybeEatInt();
|
||||
if (result == null) {
|
||||
_error('expected positive integer');
|
||||
}
|
||||
|
@ -224,37 +222,37 @@ class _GridTemplateParser extends _Parser {
|
|||
_GridTemplateParser._internal(String src) : super(src);
|
||||
|
||||
/** Parses the grid-rows and grid-columns CSS properties into object form. */
|
||||
static GridTemplate parse(String str) {
|
||||
static GridTemplate? parse(String? str) {
|
||||
if (str == null) return null;
|
||||
final p = new _GridTemplateParser._internal(str);
|
||||
final p = _GridTemplateParser._internal(str);
|
||||
final result = p._parseTemplate();
|
||||
p._eatEnd();
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Parses a grid-cell value. */
|
||||
static String parseCell(String str) {
|
||||
static String? parseCell(String? str) {
|
||||
if (str == null) return null;
|
||||
final p = new _GridTemplateParser._internal(str);
|
||||
final p = _GridTemplateParser._internal(str);
|
||||
final result = p._maybeEatString();
|
||||
p._eatEnd();
|
||||
return result;
|
||||
}
|
||||
|
||||
// => <string>+ | 'none'
|
||||
GridTemplate _parseTemplate() {
|
||||
GridTemplate? _parseTemplate() {
|
||||
if (_maybeEat('none')) {
|
||||
return null;
|
||||
}
|
||||
final rows = new List<String>();
|
||||
String row;
|
||||
final rows = <String?>[];
|
||||
String? row;
|
||||
while ((row = _maybeEatString()) != null) {
|
||||
rows.add(row);
|
||||
}
|
||||
if (rows.length == 0) {
|
||||
_error('expected at least one cell, or "none"');
|
||||
}
|
||||
return new GridTemplate(rows);
|
||||
return GridTemplate(rows);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -263,9 +261,9 @@ class _GridItemParser extends _Parser {
|
|||
_GridItemParser._internal(String src) : super(src);
|
||||
|
||||
/** Parses the grid-rows and grid-columns CSS properties into object form. */
|
||||
static _GridLocation parse(String cell, GridTrackList list) {
|
||||
static _GridLocation? parse(String? cell, GridTrackList? list) {
|
||||
if (cell == null) return null;
|
||||
final p = new _GridItemParser._internal(cell);
|
||||
final p = _GridItemParser._internal(cell);
|
||||
final result = p._parseTrack(list);
|
||||
p._eatEnd();
|
||||
return result;
|
||||
|
@ -274,27 +272,27 @@ class _GridItemParser extends _Parser {
|
|||
// [ [ <integer> | <string> | 'start' | 'end' ]
|
||||
// [ <integer> | <string> | 'start' | 'end' ]? ]
|
||||
// | 'auto'
|
||||
_GridLocation _parseTrack(GridTrackList list) {
|
||||
_GridLocation? _parseTrack(GridTrackList? list) {
|
||||
if (_maybeEat('auto')) {
|
||||
return null;
|
||||
}
|
||||
int start = _maybeParseLine(list);
|
||||
int? start = _maybeParseLine(list);
|
||||
if (start == null) {
|
||||
_error('expected row/column number or name');
|
||||
}
|
||||
int end = _maybeParseLine(list);
|
||||
int span = null;
|
||||
int? end = _maybeParseLine(list);
|
||||
int? span = null;
|
||||
if (end != null) {
|
||||
span = end - start;
|
||||
span = end - start!;
|
||||
if (span <= 0) {
|
||||
_error('expected row/column span to be a positive integer');
|
||||
}
|
||||
}
|
||||
return new _GridLocation(start, span);
|
||||
return _GridLocation(start, span);
|
||||
}
|
||||
|
||||
// [ <integer> | <string> | 'start' | 'end' ]
|
||||
int _maybeParseLine(GridTrackList list) {
|
||||
int? _maybeParseLine(GridTrackList? list) {
|
||||
if (_maybeEat('start')) {
|
||||
return 1;
|
||||
} else if (_maybeEat('end')) {
|
||||
|
@ -303,14 +301,14 @@ class _GridItemParser extends _Parser {
|
|||
// TODO(jmesserly): this won't interact properly with implicit
|
||||
// rows/columns. Instead it will snap to the number of tracks at the point
|
||||
// where it is evaluated.
|
||||
return list.tracks.length + 1;
|
||||
return list!.tracks.length + 1;
|
||||
}
|
||||
|
||||
String name = _maybeEatString();
|
||||
String? name = _maybeEatString();
|
||||
if (name == null) {
|
||||
return _maybeEatInt();
|
||||
} else {
|
||||
int edge = list.lineNames[name];
|
||||
int? edge = list!.lineNames[name];
|
||||
if (edge == null) {
|
||||
_error('row/column name "$name" not found in the parent\'s '
|
||||
' grid-row/grid-columns properties');
|
||||
|
@ -329,17 +327,17 @@ class _GridItemParser extends _Parser {
|
|||
// CSS units, support for all escape sequences, etc.
|
||||
class _GridTrackParser extends _Parser {
|
||||
final List<GridTrack> _tracks;
|
||||
final Map<String, int> _lineNames;
|
||||
final Map<String?, int> _lineNames;
|
||||
|
||||
_GridTrackParser._internal(String src)
|
||||
: _tracks = new List<GridTrack>(),
|
||||
_lineNames = new Map<String, int>(),
|
||||
: _tracks = <GridTrack>[],
|
||||
_lineNames = Map<String?, int>(),
|
||||
super(src);
|
||||
|
||||
/** Parses the grid-rows and grid-columns CSS properties into object form. */
|
||||
static GridTrackList parse(String str) {
|
||||
static GridTrackList? parse(String? str) {
|
||||
if (str == null) return null;
|
||||
final p = new _GridTrackParser._internal(str);
|
||||
final p = _GridTrackParser._internal(str);
|
||||
final result = p._parseTrackList();
|
||||
p._eatEnd();
|
||||
return result;
|
||||
|
@ -349,28 +347,28 @@ class _GridTrackParser extends _Parser {
|
|||
* Parses the grid-row-sizing and grid-column-sizing CSS properties into
|
||||
* object form.
|
||||
*/
|
||||
static TrackSizing parseTrackSizing(String str) {
|
||||
static TrackSizing parseTrackSizing(String? str) {
|
||||
if (str == null) str = 'auto';
|
||||
final p = new _GridTrackParser._internal(str);
|
||||
final p = _GridTrackParser._internal(str);
|
||||
final result = p._parseTrackMinmax();
|
||||
p._eatEnd();
|
||||
return result;
|
||||
}
|
||||
|
||||
// <track-list> => [ [ <string> ]* <track-group> [ <string> ]* ]+ | 'none'
|
||||
GridTrackList _parseTrackList() {
|
||||
GridTrackList? _parseTrackList() {
|
||||
if (_maybeEat('none')) {
|
||||
return null;
|
||||
}
|
||||
_parseTrackListHelper();
|
||||
return new GridTrackList(_tracks, _lineNames);
|
||||
return GridTrackList(_tracks, _lineNames);
|
||||
}
|
||||
|
||||
/** Code shared by _parseTrackList and _parseTrackGroup */
|
||||
void _parseTrackListHelper([List<GridTrack> resultTracks = null]) {
|
||||
void _parseTrackListHelper([List<GridTrack>? resultTracks = null]) {
|
||||
_maybeEatWhitespace();
|
||||
while (!endOfInput) {
|
||||
String name;
|
||||
String? name;
|
||||
while ((name = _maybeEatString()) != null) {
|
||||
_lineNames[name] = _tracks.length + 1; // should be 1-based
|
||||
}
|
||||
|
@ -384,7 +382,7 @@ class _GridTrackParser extends _Parser {
|
|||
if (_peekChar() == _Parser.R_PAREN) {
|
||||
return;
|
||||
}
|
||||
resultTracks.add(new GridTrack(_parseTrackMinmax()));
|
||||
resultTracks.add(GridTrack(_parseTrackMinmax()));
|
||||
} else {
|
||||
_parseTrackGroup();
|
||||
}
|
||||
|
@ -398,11 +396,11 @@ class _GridTrackParser extends _Parser {
|
|||
// | <track-minmax>
|
||||
void _parseTrackGroup() {
|
||||
if (_maybeEat('(')) {
|
||||
final tracks = new List<GridTrack>();
|
||||
final tracks = <GridTrack>[];
|
||||
_parseTrackListHelper(tracks);
|
||||
_eat(')');
|
||||
if (_maybeEat('[')) {
|
||||
num expand = _eatInt();
|
||||
num expand = _eatInt()!;
|
||||
_eat(']');
|
||||
|
||||
if (expand <= 0) {
|
||||
|
@ -419,7 +417,7 @@ class _GridTrackParser extends _Parser {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
_tracks.add(new GridTrack(_parseTrackMinmax()));
|
||||
_tracks.add(GridTrack(_parseTrackMinmax()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -434,10 +432,10 @@ class _GridTrackParser extends _Parser {
|
|||
_eat(',');
|
||||
final max = _parseTrackBreadth();
|
||||
_eat(')');
|
||||
return new TrackSizing(min, max);
|
||||
return TrackSizing(min, max);
|
||||
} else {
|
||||
final breadth = _parseTrackBreadth();
|
||||
return new TrackSizing(breadth, breadth);
|
||||
return TrackSizing(breadth, breadth);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -460,9 +458,9 @@ class _GridTrackParser extends _Parser {
|
|||
}
|
||||
|
||||
if (units == 'fr') {
|
||||
return new FractionSizing(value);
|
||||
return FractionSizing(value);
|
||||
} else {
|
||||
return new FixedSizing(value, units);
|
||||
return FixedSizing(value, units);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
part of layout;
|
||||
|
||||
// This file has classes representing the grid tracks and grid template
|
||||
|
@ -21,7 +19,7 @@ class GridTrackList {
|
|||
* is used as a start or end, it might be interpreted exclusively or
|
||||
* inclusively.
|
||||
*/
|
||||
final Map<String, int> lineNames;
|
||||
final Map<String?, int> lineNames;
|
||||
|
||||
GridTrackList(this.tracks, this.lineNames) {}
|
||||
}
|
||||
|
@ -32,15 +30,15 @@ class GridTrack {
|
|||
* The start position of this track. Equal to the sum of previous track's
|
||||
* usedBreadth.
|
||||
*/
|
||||
num start;
|
||||
late num start;
|
||||
|
||||
/** The final computed breadth of this track. */
|
||||
num usedBreadth;
|
||||
late num usedBreadth;
|
||||
|
||||
// Fields used internally by the sizing algorithm
|
||||
num maxBreadth;
|
||||
num updatedBreadth;
|
||||
num tempBreadth;
|
||||
late num maxBreadth;
|
||||
late num updatedBreadth;
|
||||
late num tempBreadth;
|
||||
|
||||
final TrackSizing sizing;
|
||||
|
||||
|
@ -50,7 +48,7 @@ class GridTrack {
|
|||
* Support for the feature that repeats rows and columns, e.g.
|
||||
* [:grid-columns: 10px ("content" 250px 10px)[4]:]
|
||||
*/
|
||||
GridTrack clone() => new GridTrack(sizing.clone());
|
||||
GridTrack clone() => GridTrack(sizing.clone());
|
||||
|
||||
/** The min sizing function for the track. */
|
||||
SizingFunction get minSizing => sizing.min;
|
||||
|
@ -69,7 +67,7 @@ class GridItemAlignment {
|
|||
final String value;
|
||||
|
||||
// 'start' | 'end' | 'center' | 'stretch'
|
||||
GridItemAlignment.fromString(String value)
|
||||
GridItemAlignment.fromString(String? value)
|
||||
: this.value = (value == null) ? 'stretch' : value {
|
||||
switch (this.value) {
|
||||
case 'start':
|
||||
|
@ -78,24 +76,25 @@ class GridItemAlignment {
|
|||
case 'stretch':
|
||||
break;
|
||||
default:
|
||||
throw new UnsupportedError('invalid row/column alignment "$value"');
|
||||
throw UnsupportedError('invalid row/column alignment "$value"');
|
||||
}
|
||||
}
|
||||
|
||||
_GridLocation align(_GridLocation span, int size) {
|
||||
_GridLocation align(_GridLocation span, int? size) {
|
||||
switch (value) {
|
||||
case 'start':
|
||||
return new _GridLocation(span.start, size);
|
||||
return _GridLocation(span.start, size);
|
||||
case 'end':
|
||||
return new _GridLocation(span.end - size, size);
|
||||
return _GridLocation(span.end - size!, size);
|
||||
case 'center':
|
||||
size = Math.min(size, span.length);
|
||||
num center = span.start + span.length / 2;
|
||||
size = Math.min(size!, span.length!);
|
||||
num center = span.start! + span.length! / 2;
|
||||
num left = center - size / 2;
|
||||
return new _GridLocation(left.round(), size);
|
||||
return _GridLocation(left.round(), size);
|
||||
case 'stretch':
|
||||
return span;
|
||||
}
|
||||
throw UnsupportedError('invalid row/column alignment "$value"');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -107,23 +106,23 @@ class GridTemplate {
|
|||
final Map<int, _GridTemplateRect> _rects;
|
||||
final int _numRows;
|
||||
|
||||
GridTemplate(List<String> rows)
|
||||
: _rects = new Map<int, _GridTemplateRect>(),
|
||||
GridTemplate(List<String?> rows)
|
||||
: _rects = <int, _GridTemplateRect>{},
|
||||
_numRows = rows.length {
|
||||
_buildRects(rows);
|
||||
}
|
||||
|
||||
/** Scans the template strings and computes bounds for each one. */
|
||||
void _buildRects(List<String> templateRows) {
|
||||
void _buildRects(List<String?> templateRows) {
|
||||
for (int r = 0; r < templateRows.length; r++) {
|
||||
String row = templateRows[r];
|
||||
String row = templateRows[r]!;
|
||||
for (int c = 0; c < row.length; c++) {
|
||||
int cell = row.codeUnitAt(c);
|
||||
final rect = _rects[cell];
|
||||
if (rect != null) {
|
||||
rect.add(r + 1, c + 1);
|
||||
} else {
|
||||
_rects[cell] = new _GridTemplateRect(cell, r + 1, c + 1);
|
||||
_rects[cell] = _GridTemplateRect(cell, r + 1, c + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -139,12 +138,12 @@ class GridTemplate {
|
|||
*/
|
||||
_GridTemplateRect lookupCell(String cell) {
|
||||
if (cell.length != 1) {
|
||||
throw new UnsupportedError(
|
||||
throw UnsupportedError(
|
||||
'grid-cell "$cell" must be a one character string');
|
||||
}
|
||||
final rect = _rects[cell.codeUnitAt(0)];
|
||||
if (rect == null) {
|
||||
throw new UnsupportedError(
|
||||
throw UnsupportedError(
|
||||
'grid-cell "$cell" not found in parent\'s grid-template');
|
||||
}
|
||||
return rect;
|
||||
|
@ -171,8 +170,8 @@ class _GridTemplateRect {
|
|||
if (expected != _count) {
|
||||
// TODO(jmesserly): not sure if we should throw here, due to CSS's
|
||||
// permissiveness. At the moment we're noisy about errors.
|
||||
String cell = new String.fromCharCodes([_char]);
|
||||
throw new UnsupportedError('grid-template "$cell"'
|
||||
String cell = String.fromCharCodes([_char]);
|
||||
throw UnsupportedError('grid-template "$cell"'
|
||||
' is not square, expected $expected cells but got $_count');
|
||||
}
|
||||
}
|
||||
|
@ -183,8 +182,8 @@ class _GridTemplateRect {
|
|||
* grid-column during parsing.
|
||||
*/
|
||||
class _GridLocation {
|
||||
final int start, length;
|
||||
final int? start, length;
|
||||
_GridLocation(this.start, this.length) {}
|
||||
|
||||
int get end => start + length;
|
||||
int get end => start! + length!;
|
||||
}
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
part of layout;
|
||||
|
||||
// This file has classes representing the grid sizing functions
|
||||
|
@ -20,7 +18,7 @@ class SizingFunction {
|
|||
bool get isMaxContentSized => false;
|
||||
bool get isFraction => false;
|
||||
|
||||
num resolveLength(num gridSize) => 0;
|
||||
num resolveLength(num? gridSize) => 0;
|
||||
|
||||
num get fractionValue => 0;
|
||||
|
||||
|
@ -46,16 +44,16 @@ class FixedSizing extends SizingFunction {
|
|||
FixedSizing(this.length, [this.units = 'px']) : _contentSized = false {
|
||||
if (units != 'px' && units != '%') {
|
||||
// TODO(jmesserly): support other unit types
|
||||
throw new UnsupportedError('Units other than px and %');
|
||||
throw UnsupportedError('Units other than px and %');
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(jmesserly): this is only needed because of our mutable property
|
||||
FixedSizing clone() => new FixedSizing(length, units);
|
||||
FixedSizing clone() => FixedSizing(length, units);
|
||||
|
||||
bool get isMinContentSized => _contentSized;
|
||||
|
||||
num resolveLength(num gridSize) {
|
||||
num resolveLength(num? gridSize) {
|
||||
if (units == '%') {
|
||||
if (gridSize == null) {
|
||||
// Use content size when the grid doesn't have an absolute size in this
|
||||
|
@ -120,38 +118,38 @@ class TrackSizing {
|
|||
TrackSizing(this.min, this.max) {}
|
||||
|
||||
// TODO(jmesserly): this is only needed because FixedSizing is mutable
|
||||
TrackSizing clone() => new TrackSizing(min.clone(), max.clone());
|
||||
TrackSizing clone() => TrackSizing(min.clone(), max.clone());
|
||||
}
|
||||
|
||||
/** Represents a GridTrack breadth property. */
|
||||
// TODO(jmesserly): these classes could be replaced with reflection/mirrors
|
||||
abstract class _BreadthAccumulator {
|
||||
void setSize(GridTrack t, num value);
|
||||
num getSize(GridTrack t);
|
||||
void setSize(GridTrack? t, num value);
|
||||
num? getSize(GridTrack? t);
|
||||
|
||||
SizingFunction getSizingFunction(GridTrack t);
|
||||
SizingFunction getSizingFunction(GridTrack? t);
|
||||
}
|
||||
|
||||
class _UsedBreadthAccumulator implements _BreadthAccumulator {
|
||||
const _UsedBreadthAccumulator();
|
||||
|
||||
void setSize(GridTrack t, num value) {
|
||||
t.usedBreadth = value;
|
||||
void setSize(GridTrack? t, num value) {
|
||||
t!.usedBreadth = value;
|
||||
}
|
||||
|
||||
num getSize(GridTrack t) => t.usedBreadth;
|
||||
num? getSize(GridTrack? t) => t!.usedBreadth;
|
||||
|
||||
SizingFunction getSizingFunction(GridTrack t) => t.minSizing;
|
||||
SizingFunction getSizingFunction(GridTrack? t) => t!.minSizing;
|
||||
}
|
||||
|
||||
class _MaxBreadthAccumulator implements _BreadthAccumulator {
|
||||
const _MaxBreadthAccumulator();
|
||||
|
||||
void setSize(GridTrack t, num value) {
|
||||
t.maxBreadth = value;
|
||||
void setSize(GridTrack? t, num value) {
|
||||
t!.maxBreadth = value;
|
||||
}
|
||||
|
||||
num getSize(GridTrack t) => t.maxBreadth;
|
||||
num? getSize(GridTrack? t) => t!.maxBreadth;
|
||||
|
||||
SizingFunction getSizingFunction(GridTrack t) => t.maxSizing;
|
||||
SizingFunction getSizingFunction(GridTrack? t) => t!.maxSizing;
|
||||
}
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
part of layout;
|
||||
|
||||
/** The interface that the layout algorithms use to talk to the view. */
|
||||
|
@ -30,9 +28,9 @@ abstract class Positionable {
|
|||
class LayoutParams {
|
||||
// TODO(jmesserly): should be const, but there's a bug in DartC preventing us
|
||||
// from calling "window." in an initializer. See b/5332777
|
||||
CssStyleDeclaration style;
|
||||
CssStyleDeclaration? style;
|
||||
|
||||
int get layer => 0;
|
||||
int? get layer => 0;
|
||||
|
||||
LayoutParams(Element node) {
|
||||
style = node.getComputedStyle();
|
||||
|
@ -73,9 +71,9 @@ class ViewLayout {
|
|||
* The layout parameters associated with this view and used by the parent
|
||||
* to determine how this view should be laid out.
|
||||
*/
|
||||
LayoutParams layoutParams;
|
||||
int _offsetWidth;
|
||||
int _offsetHeight;
|
||||
LayoutParams? layoutParams;
|
||||
int? _offsetWidth;
|
||||
int? _offsetHeight;
|
||||
|
||||
/** The view that this layout belongs to. */
|
||||
final Positionable view;
|
||||
|
@ -85,7 +83,7 @@ class ViewLayout {
|
|||
* properties in the first pass while computing positions. Then we have a
|
||||
* second pass that actually moves everything.
|
||||
*/
|
||||
int _measuredLeft, _measuredTop, _measuredWidth, _measuredHeight;
|
||||
int? _measuredLeft, _measuredTop, _measuredWidth, _measuredHeight;
|
||||
|
||||
ViewLayout(this.view);
|
||||
|
||||
|
@ -96,9 +94,9 @@ class ViewLayout {
|
|||
// registered with a LayoutProvider.
|
||||
factory ViewLayout.fromView(Positionable view) {
|
||||
if (hasCustomLayout(view)) {
|
||||
return new GridLayout(view);
|
||||
return GridLayout(view);
|
||||
} else {
|
||||
return new ViewLayout(view);
|
||||
return ViewLayout(view);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -106,36 +104,36 @@ class ViewLayout {
|
|||
return view.customStyle['display'] == "-dart-grid";
|
||||
}
|
||||
|
||||
CssStyleDeclaration get _style => layoutParams.style;
|
||||
CssStyleDeclaration? get _style => layoutParams!.style;
|
||||
|
||||
void cacheExistingBrowserLayout() {
|
||||
_offsetWidth = view.node.offset.width;
|
||||
_offsetHeight = view.node.offset.height;
|
||||
_offsetWidth = view.node.offset.width as int?;
|
||||
_offsetHeight = view.node.offset.height as int?;
|
||||
}
|
||||
|
||||
int get currentWidth {
|
||||
int? get currentWidth {
|
||||
return _offsetWidth;
|
||||
}
|
||||
|
||||
int get currentHeight {
|
||||
int? get currentHeight {
|
||||
return _offsetHeight;
|
||||
}
|
||||
|
||||
int get borderLeftWidth => _toPixels(_style.borderLeftWidth);
|
||||
int get borderTopWidth => _toPixels(_style.borderTopWidth);
|
||||
int get borderRightWidth => _toPixels(_style.borderRightWidth);
|
||||
int get borderBottomWidth => _toPixels(_style.borderBottomWidth);
|
||||
int get borderLeftWidth => _toPixels(_style!.borderLeftWidth);
|
||||
int get borderTopWidth => _toPixels(_style!.borderTopWidth);
|
||||
int get borderRightWidth => _toPixels(_style!.borderRightWidth);
|
||||
int get borderBottomWidth => _toPixels(_style!.borderBottomWidth);
|
||||
int get borderWidth => borderLeftWidth + borderRightWidth;
|
||||
int get borderHeight => borderTopWidth + borderBottomWidth;
|
||||
|
||||
/** Implements the custom layout computation. */
|
||||
void measureLayout(Future<Size> size, Completer<bool> changed) {}
|
||||
void measureLayout(Future<Size> size, Completer<bool>? changed) {}
|
||||
|
||||
/**
|
||||
* Positions the view within its parent container.
|
||||
* Also performs a layout of its children.
|
||||
*/
|
||||
void setBounds(int left, int top, int width, int height) {
|
||||
void setBounds(int? left, int? top, int width, int height) {
|
||||
assert(width >= 0 && height >= 0);
|
||||
|
||||
_measuredLeft = left;
|
||||
|
@ -144,8 +142,8 @@ class ViewLayout {
|
|||
// Note: we need to save the client height
|
||||
_measuredWidth = width - borderWidth;
|
||||
_measuredHeight = height - borderHeight;
|
||||
final completer = new Completer<Size>();
|
||||
completer.complete(new Size(_measuredWidth, _measuredHeight));
|
||||
final completer = Completer<Size>();
|
||||
completer.complete(Size(_measuredWidth!, _measuredHeight!));
|
||||
measureLayout(completer.future, null);
|
||||
}
|
||||
|
||||
|
@ -159,7 +157,7 @@ class ViewLayout {
|
|||
style.top = '${_measuredTop}px';
|
||||
style.width = '${_measuredWidth}px';
|
||||
style.height = '${_measuredHeight}px';
|
||||
style.zIndex = '${layoutParams.layer}';
|
||||
style.zIndex = '${layoutParams!.layer}';
|
||||
|
||||
_measuredLeft = null;
|
||||
_measuredTop = null;
|
||||
|
@ -181,8 +179,8 @@ class ViewLayout {
|
|||
}
|
||||
}
|
||||
|
||||
int measureContent(ViewLayout parent, Dimension dimension,
|
||||
[ContentSizeMode mode = null]) {
|
||||
int? measureContent(ViewLayout parent, Dimension? dimension,
|
||||
[ContentSizeMode? mode = null]) {
|
||||
if (dimension == Dimension.WIDTH) {
|
||||
return measureWidth(parent, mode);
|
||||
} else if (dimension == Dimension.HEIGHT) {
|
||||
|
@ -190,23 +188,23 @@ class ViewLayout {
|
|||
}
|
||||
}
|
||||
|
||||
int measureWidth(ViewLayout parent, ContentSizeMode mode) {
|
||||
final style = layoutParams.style;
|
||||
int? measureWidth(ViewLayout parent, ContentSizeMode? mode) {
|
||||
final style = layoutParams!.style;
|
||||
if (mode == ContentSizeMode.MIN) {
|
||||
return _styleToPixels(style.minWidth, currentWidth, parent.currentWidth);
|
||||
return _styleToPixels(style!.minWidth, currentWidth, parent.currentWidth);
|
||||
} else if (mode == ContentSizeMode.MAX) {
|
||||
return _styleToPixels(style.maxWidth, currentWidth, parent.currentWidth);
|
||||
return _styleToPixels(style!.maxWidth, currentWidth, parent.currentWidth);
|
||||
}
|
||||
}
|
||||
|
||||
int measureHeight(ViewLayout parent, ContentSizeMode mode) {
|
||||
final style = layoutParams.style;
|
||||
int? measureHeight(ViewLayout parent, ContentSizeMode? mode) {
|
||||
final style = layoutParams!.style;
|
||||
if (mode == ContentSizeMode.MIN) {
|
||||
return _styleToPixels(
|
||||
style.minHeight, currentHeight, parent.currentHeight);
|
||||
style!.minHeight, currentHeight, parent.currentHeight);
|
||||
} else if (mode == ContentSizeMode.MAX) {
|
||||
return _styleToPixels(
|
||||
style.maxHeight, currentHeight, parent.currentHeight);
|
||||
style!.maxHeight, currentHeight, parent.currentHeight);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -215,19 +213,18 @@ class ViewLayout {
|
|||
return int.parse(style.substring(0, style.length - 2));
|
||||
} else {
|
||||
// TODO(jmesserly): other size units
|
||||
throw new UnsupportedError(
|
||||
'Unknown min/max content size format: "$style"');
|
||||
throw UnsupportedError('Unknown min/max content size format: "$style"');
|
||||
}
|
||||
}
|
||||
|
||||
static int _styleToPixels(String style, num size, num parentSize) {
|
||||
static int? _styleToPixels(String style, num? size, num? parentSize) {
|
||||
if (style == 'none') {
|
||||
// For an unset max-content size, use the actual size
|
||||
return size;
|
||||
return size as int?;
|
||||
}
|
||||
if (style.endsWith('%')) {
|
||||
num percent = double.parse(style.substring(0, style.length - 1));
|
||||
return ((percent / 100) * parentSize).toInt();
|
||||
return ((percent / 100) * parentSize!).toInt();
|
||||
}
|
||||
return _toPixels(style);
|
||||
}
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
// @dart = 2.9
|
||||
|
||||
library layout;
|
||||
|
||||
import 'dart:async';
|
||||
|
|
|
@ -80,9 +80,9 @@ class CollectionUtils {
|
|||
}
|
||||
|
||||
/** Orders an iterable by its values, or by a key selector. */
|
||||
static List orderBy(Iterable source,
|
||||
static List<T> orderBy<T>(Iterable<T> source,
|
||||
[NumericValueSelector? selector = null]) {
|
||||
final result = List.from(source);
|
||||
final result = List<T>.from(source);
|
||||
sortBy(result, selector);
|
||||
return result;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue