mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
This makes debugging the render tree a lot easier. Just print the node you care about, and you get an indented tree view of its subtree, including settings. New subclasses should implement the new virtual method debugDescribeSettings() to expose new settings. R=eseidel@chromium.org Review URL: https://codereview.chromium.org/1157993005
122 lines
4.4 KiB
Dart
122 lines
4.4 KiB
Dart
// Copyright 2015 The Chromium Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
import 'dart:sky' as sky;
|
|
import 'box.dart';
|
|
import 'object.dart';
|
|
|
|
class FlexBoxParentData extends BoxParentData with ContainerParentDataMixin<RenderBox> {
|
|
int flex;
|
|
void merge(FlexBoxParentData other) {
|
|
if (other.flex != null)
|
|
flex = other.flex;
|
|
super.merge(other);
|
|
}
|
|
String toString() => '${super.toString()}; flex=$flex';
|
|
}
|
|
|
|
enum FlexDirection { horizontal, vertical }
|
|
|
|
class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, FlexBoxParentData>,
|
|
RenderBoxContainerDefaultsMixin<RenderBox, FlexBoxParentData> {
|
|
// lays out RenderBox children using flexible layout
|
|
|
|
RenderFlex({
|
|
FlexDirection direction: FlexDirection.horizontal
|
|
}) : _direction = direction;
|
|
|
|
FlexDirection _direction;
|
|
FlexDirection get direction => _direction;
|
|
void set direction (FlexDirection value) {
|
|
if (_direction != value) {
|
|
_direction = value;
|
|
markNeedsLayout();
|
|
}
|
|
}
|
|
|
|
void setParentData(RenderBox child) {
|
|
if (child.parentData is! FlexBoxParentData)
|
|
child.parentData = new FlexBoxParentData();
|
|
}
|
|
|
|
bool get sizedByParent => true;
|
|
void performResize() {
|
|
size = constraints.constrain(new sky.Size(constraints.maxWidth, constraints.maxHeight));
|
|
assert(size.height < double.INFINITY);
|
|
assert(size.width < double.INFINITY);
|
|
}
|
|
|
|
int _getFlex(RenderBox child) {
|
|
assert(child.parentData is FlexBoxParentData);
|
|
return child.parentData.flex != null ? child.parentData.flex : 0;
|
|
}
|
|
|
|
void performLayout() {
|
|
// Based on http://www.w3.org/TR/css-flexbox-1/ Section 9.7 Resolving Flexible Lengths
|
|
// Steps 1-3. Determine used flex factor, size inflexible items, calculate free space
|
|
int totalFlex = 0;
|
|
assert(constraints != null);
|
|
double freeSpace = (_direction == FlexDirection.horizontal) ? constraints.maxWidth : constraints.maxHeight;
|
|
RenderBox child = firstChild;
|
|
while (child != null) {
|
|
int flex = _getFlex(child);
|
|
if (flex > 0) {
|
|
totalFlex += child.parentData.flex;
|
|
} else {
|
|
BoxConstraints innerConstraints = new BoxConstraints(maxHeight: constraints.maxHeight,
|
|
maxWidth: constraints.maxWidth);
|
|
child.layout(innerConstraints, parentUsesSize: true);
|
|
freeSpace -= (_direction == FlexDirection.horizontal) ? child.size.width : child.size.height;
|
|
}
|
|
child = child.parentData.nextSibling;
|
|
}
|
|
|
|
// Steps 4-5. Distribute remaining space to flexible children.
|
|
double spacePerFlex = totalFlex > 0 ? (freeSpace / totalFlex) : 0.0;
|
|
double usedSpace = 0.0;
|
|
child = firstChild;
|
|
while (child != null) {
|
|
int flex = _getFlex(child);
|
|
if (flex > 0) {
|
|
double spaceForChild = spacePerFlex * flex;
|
|
BoxConstraints innerConstraints;
|
|
switch (_direction) {
|
|
case FlexDirection.horizontal:
|
|
innerConstraints = new BoxConstraints(maxHeight: constraints.maxHeight,
|
|
minWidth: spaceForChild,
|
|
maxWidth: spaceForChild);
|
|
break;
|
|
case FlexDirection.vertical:
|
|
innerConstraints = new BoxConstraints(minHeight: spaceForChild,
|
|
maxHeight: spaceForChild,
|
|
maxWidth: constraints.maxWidth);
|
|
break;
|
|
}
|
|
child.layout(innerConstraints, parentUsesSize: true);
|
|
}
|
|
|
|
// For now, center the flex items in the cross direction
|
|
switch (_direction) {
|
|
case FlexDirection.horizontal:
|
|
child.parentData.position = new sky.Point(usedSpace, size.height / 2.0 - child.size.height / 2.0);
|
|
usedSpace += child.size.width;
|
|
break;
|
|
case FlexDirection.vertical:
|
|
child.parentData.position = new sky.Point(size.width / 2.0 - child.size.width / 2.0, usedSpace);
|
|
usedSpace += child.size.height;
|
|
break;
|
|
}
|
|
child = child.parentData.nextSibling;
|
|
}
|
|
}
|
|
|
|
void hitTestChildren(HitTestResult result, { sky.Point position }) {
|
|
defaultHitTestChildren(result, position: position);
|
|
}
|
|
|
|
void paint(RenderObjectDisplayList canvas) {
|
|
defaultPaint(canvas);
|
|
}
|
|
}
|