浏览代码

add flex.

/main
kg 6 年前
当前提交
ac79a755
共有 18 个文件被更改,包括 983 次插入44 次删除
  1. 44
      Assets/UIWidgets/Tests/RenderBoxes.cs
  2. 3
      Assets/UIWidgets/editor/editor_window.cs
  3. 18
      Assets/UIWidgets/painting/basic_types.cs
  4. 20
      Assets/UIWidgets/painting/box_decoration.cs
  5. 2
      Assets/UIWidgets/painting/decoration.cs
  6. 64
      Assets/UIWidgets/rendering/box.cs
  7. 23
      Assets/UIWidgets/rendering/object.cs
  8. 60
      Assets/UIWidgets/rendering/object.mixin.gen.cs
  9. 35
      Assets/UIWidgets/rendering/object.mixin.njk
  10. 2
      Assets/UIWidgets/rendering/sliver.cs
  11. 2
      Assets/UIWidgets/rendering/viewpoint.cs
  12. 5
      Assets/UIWidgets/ui/text.cs
  13. 73
      Assets/UIWidgets/rendering/box.mixin.gen.cs
  14. 11
      Assets/UIWidgets/rendering/box.mixin.gen.cs.meta
  15. 74
      Assets/UIWidgets/rendering/box.mixin.njk
  16. 3
      Assets/UIWidgets/rendering/box.mixin.njk.meta
  17. 585
      Assets/UIWidgets/rendering/flex.cs
  18. 3
      Assets/UIWidgets/rendering/flex.cs.meta

44
Assets/UIWidgets/Tests/RenderBoxes.cs


using System;
using System.Collections.Generic;
using System.Linq;
using UIWidgets.editor;
using UIWidgets.painting;

this._options = new Func<RenderBox>[] {
this.none,
this.decoratedBox,
this.flex,
};
this._optionStrings = this._options.Select(x => x.Method.Name).ToArray();
this._selected = 0;

child: new RenderDecoratedBox(
decoration: new BoxDecoration(
color: new Color(0xFFFFFFFF),
borderRadius: BorderRadius.all(3)
borderRadius: BorderRadius.all(3),
boxShadow: new List<BoxShadow> {
new BoxShadow(
color: new Color(0xFFFF00FF),
offset: new Offset(0, 0),
blurRadius: 3.0,
spreadRadius: 10
)
}
}
RenderBox flex() {
var flexbox = new RenderFlex(
direction: Axis.horizontal,
crossAxisAlignment: CrossAxisAlignment.center);
flexbox.add(new RenderConstrainedBox(
additionalConstraints: new BoxConstraints(minWidth: 300, minHeight: 200),
child: new RenderDecoratedBox(
decoration: new BoxDecoration(
color: new Color(0xFF00FF00)
)
)));
flexbox.add(new RenderConstrainedBox(
additionalConstraints: new BoxConstraints(minWidth: 100, minHeight: 300),
child: new RenderDecoratedBox(
decoration: new BoxDecoration(
color: new Color(0xFF00FFFF)
)
)));
flexbox.add(new RenderConstrainedBox(
additionalConstraints: new BoxConstraints(minWidth: 50, minHeight: 100),
child: new RenderDecoratedBox(
decoration: new BoxDecoration(
color: new Color(0xFF0000FF)
)
)));
return flexbox;
}
}
}

3
Assets/UIWidgets/editor/editor_window.cs


using System;
using UIWidgets.flow;
using UIWidgets.rendering;
using UIWidgets.widgets;
using UnityEditor;
using UnityEngine;
using Rect = UnityEngine.Rect;

18
Assets/UIWidgets/painting/basic_types.cs


vertical,
}
public enum VerticalDirection {
up,
down,
}
public static Axis flipAxis(Axis direction) {
switch (direction) {
case Axis.horizontal:
return Axis.vertical;
case Axis.vertical:
return Axis.horizontal;
}
throw new Exception("unknown axis");
}
public static Axis axisDirectionToAxis(AxisDirection axisDirection) {
switch (axisDirection) {
case AxisDirection.up:

throw new Exception("unknown axisDirection");
}
}
}

20
Assets/UIWidgets/painting/box_decoration.cs


}
}
public void dispose() {
public override void dispose() {
base.dispose();
}

// this._paintShadows(canvas, rect);
this._paintShadows(canvas, rect);
// this._paintBackgroundImage(canvas, rect, configuration);
// if (this._decoration.border != null) {
// this._decoration.border.paint(
// canvas,
// rect,
// borderRadius: this._decoration.borderRadius
// );
// }
this._paintBackgroundImage(canvas, rect, configuration);
if (this._decoration.border != null) {
this._decoration.border.paint(
canvas,
rect,
borderRadius: this._decoration.borderRadius
);
}
}
}
}

2
Assets/UIWidgets/painting/decoration.cs


public abstract void paint(Canvas canvas, Offset offset, ImageConfiguration configuration);
public void dispose() {
public virtual void dispose() {
}
}
}

64
Assets/UIWidgets/rendering/box.cs


get { return Offset.zero & this.size; }
}
}
public abstract class
RenderBoxContainerDefaultsMixin<ChildType, ParentDataType>
: ContainerRenderObjectMixinRenderBox<ChildType, ParentDataType>
where ChildType : RenderBox
where ParentDataType : ContainerParentDataMixinBoxParentData<ChildType> {
public double? defaultComputeDistanceToFirstActualBaseline(TextBaseline baseline) {
var child = this.firstChild;
while (child != null) {
var childParentData = (ParentDataType) child.parentData;
double? result = child.getDistanceToActualBaseline(baseline);
if (result != null) {
return result.Value + childParentData.offset.dy;
}
child = childParentData.nextSibling;
}
return null;
}
public double? defaultComputeDistanceToHighestActualBaseline(TextBaseline baseline) {
double? result = null;
var child = this.firstChild;
while (child != null) {
var childParentData = (ParentDataType) child.parentData;
double? candidate = child.getDistanceToActualBaseline(baseline);
if (candidate != null) {
candidate += childParentData.offset.dy;
if (result != null) {
result = Math.Min(result.Value, candidate.Value);
} else {
result = candidate;
}
}
child = childParentData.nextSibling;
}
return result;
}
public void defaultPaint(PaintingContext context, Offset offset) {
var child = this.firstChild;
while (child != null) {
var childParentData = (ParentDataType) child.parentData;
context.paintChild(child, childParentData.offset + offset);
child = childParentData.nextSibling;
}
}
public List<ChildType> getChildrenAsList() {
var result = new List<ChildType>();
var child = this.firstChild;
while (child != null) {
var childParentData = (ParentDataType) child.parentData;
result.Add(child);
child = childParentData.nextSibling;
}
return result;
}
}
}

23
Assets/UIWidgets/rendering/object.cs


}
}
public abstract class ContainerParentDataMixin<ChildType> : ParentData where ChildType : RenderObject {
public ChildType previousSibling;
public ChildType nextSibling;
public override void detach() {
base.detach();
public interface ContainerParentDataMixin<ChildType> where ChildType : RenderObject {
ChildType previousSibling { get; set; }
if (this.previousSibling != null) {
var previousSiblingParentData = (ContainerParentDataMixin<ChildType>) this.previousSibling.parentData;
previousSiblingParentData.nextSibling = this.nextSibling;
}
if (this.nextSibling != null) {
var nextSiblingParentData = (ContainerParentDataMixin<ChildType>) this.nextSibling.parentData;
nextSiblingParentData.previousSibling = this.previousSibling;
}
this.previousSibling = null;
this.nextSibling = null;
}
ChildType nextSibling { get; set; }
}
public abstract class RenderObject : AbstractNode {

60
Assets/UIWidgets/rendering/object.mixin.gen.cs


namespace UIWidgets.rendering {
public abstract class RenderObjectWithChildMixinRenderBox<ChildType> : RenderBox where ChildType : RenderObject {
public abstract class RenderObjectWithChildMixinRenderObject<ChildType> : RenderObject where ChildType : RenderObject {
public ChildType _child;
public ChildType child {

}
public abstract class RenderObjectWithChildMixinRenderObject<ChildType> : RenderObject where ChildType : RenderObject {
public abstract class RenderObjectWithChildMixinRenderBox<ChildType> : RenderBox where ChildType : RenderObject {
public ChildType _child;
public ChildType child {

public abstract class ContainerParentDataMixinParentData<ChildType> : ParentData, ContainerParentDataMixin<ChildType> where ChildType : RenderObject {
public ChildType previousSibling { get; set; }
public ChildType nextSibling { get; set; }
public override void detach() {
base.detach();
if (this.previousSibling != null) {
var previousSiblingParentData = (ContainerParentDataMixin<ChildType>) this.previousSibling.parentData;
previousSiblingParentData.nextSibling = this.nextSibling;
}
if (this.nextSibling != null) {
var nextSiblingParentData = (ContainerParentDataMixin<ChildType>) this.nextSibling.parentData;
nextSiblingParentData.previousSibling = this.previousSibling;
}
this.previousSibling = null;
this.nextSibling = null;
}
}
public abstract class ContainerParentDataMixinBoxParentData<ChildType> : BoxParentData, ContainerParentDataMixin<ChildType> where ChildType : RenderObject {
public ChildType previousSibling { get; set; }
public ChildType nextSibling { get; set; }
public override void detach() {
base.detach();
if (this.previousSibling != null) {
var previousSiblingParentData = (ContainerParentDataMixin<ChildType>) this.previousSibling.parentData;
previousSiblingParentData.nextSibling = this.nextSibling;
}
if (this.nextSibling != null) {
var nextSiblingParentData = (ContainerParentDataMixin<ChildType>) this.nextSibling.parentData;
nextSiblingParentData.previousSibling = this.previousSibling;
}
this.previousSibling = null;
this.nextSibling = null;
}
}
where ParentDataType : ContainerParentDataMixin<ChildType> {
where ParentDataType : ParentData, ContainerParentDataMixin<ChildType> {
public int _childCount = 0;

public abstract class ContainerRenderObjectMixinRenderSliver<ChildType, ParentDataType> : RenderSliver
where ChildType : RenderObject
where ParentDataType : ContainerParentDataMixin<ChildType> {
where ParentDataType : ParentData, ContainerParentDataMixin<ChildType> {
public int _childCount = 0;

35
Assets/UIWidgets/rendering/object.mixin.njk


}
{% endmacro %}
{{ RenderObjectWithChildMixin('RenderObject') }}
{{ RenderObjectWithChildMixin('RenderObject') }}
{% macro ContainerParentDataMixin(with) %}
public abstract class ContainerParentDataMixin{{with}}<ChildType> : {{with}}, ContainerParentDataMixin<ChildType> where ChildType : RenderObject {
public ChildType previousSibling { get; set; }
public ChildType nextSibling { get; set; }
public override void detach() {
base.detach();
if (this.previousSibling != null) {
var previousSiblingParentData = (ContainerParentDataMixin<ChildType>) this.previousSibling.parentData;
previousSiblingParentData.nextSibling = this.nextSibling;
}
if (this.nextSibling != null) {
var nextSiblingParentData = (ContainerParentDataMixin<ChildType>) this.nextSibling.parentData;
nextSiblingParentData.previousSibling = this.previousSibling;
}
this.previousSibling = null;
this.nextSibling = null;
}
}
{% endmacro %}
{{ ContainerParentDataMixin('ParentData') }}
{{ ContainerParentDataMixin('BoxParentData') }}
where ParentDataType : ContainerParentDataMixin<ChildType> {
where ParentDataType : ParentData, ContainerParentDataMixin<ChildType> {
public int _childCount = 0;

2
Assets/UIWidgets/rendering/sliver.cs


namespace UIWidgets.rendering {
public class SliverPhysicalParentData : ContainerParentDataMixin<RenderSliver> {
public class SliverPhysicalParentData : ContainerParentDataMixinParentData<RenderSliver> {
}
public class SliverPhysicalContainerParentData : SliverPhysicalParentData {

2
Assets/UIWidgets/rendering/viewpoint.cs


public abstract class RenderViewportBase<ParentDataClass> :
ContainerRenderObjectMixinRenderBox<RenderSliver, ParentDataClass>,
RenderAbstractViewport
where ParentDataClass : ContainerParentDataMixin<RenderSliver> {
where ParentDataClass : ParentData, ContainerParentDataMixin<RenderSliver> {
protected RenderViewportBase(
AxisDirection crossAxisDirection,
ViewportOffset offset,

5
Assets/UIWidgets/ui/text.cs


alphabetic,
ideographic,
}
public enum TextDirection {
rtl,
ltr,
}
}

73
Assets/UIWidgets/rendering/box.mixin.gen.cs


using System;
using System.Collections.Generic;
using UIWidgets.ui;
namespace UIWidgets.rendering {
public abstract class
RenderBoxContainerDefaultsMixinContainerRenderObjectMixinRenderBox<ChildType, ParentDataType>
: ContainerRenderObjectMixinRenderBox<ChildType, ParentDataType>
where ChildType : RenderBox
where ParentDataType : ContainerParentDataMixinBoxParentData<ChildType> {
public double? defaultComputeDistanceToFirstActualBaseline(TextBaseline baseline) {
var child = this.firstChild;
while (child != null) {
var childParentData = (ParentDataType) child.parentData;
double? result = child.getDistanceToActualBaseline(baseline);
if (result != null) {
return result.Value + childParentData.offset.dy;
}
child = childParentData.nextSibling;
}
return null;
}
public double? defaultComputeDistanceToHighestActualBaseline(TextBaseline baseline) {
double? result = null;
var child = this.firstChild;
while (child != null) {
var childParentData = (ParentDataType) child.parentData;
double? candidate = child.getDistanceToActualBaseline(baseline);
if (candidate != null) {
candidate += childParentData.offset.dy;
if (result != null) {
result = Math.Min(result.Value, candidate.Value);
} else {
result = candidate;
}
}
child = childParentData.nextSibling;
}
return result;
}
public void defaultPaint(PaintingContext context, Offset offset) {
var child = this.firstChild;
while (child != null) {
var childParentData = (ParentDataType) child.parentData;
context.paintChild(child, childParentData.offset + offset);
child = childParentData.nextSibling;
}
}
public List<ChildType> getChildrenAsList() {
var result = new List<ChildType>();
var child = this.firstChild;
while (child != null) {
var childParentData = (ParentDataType) child.parentData;
result.Add(child);
child = childParentData.nextSibling;
}
return result;
}
}
}

11
Assets/UIWidgets/rendering/box.mixin.gen.cs.meta


fileFormatVersion: 2
guid: 4e3cc56d5c46c4172a60c42d39eab183
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

74
Assets/UIWidgets/rendering/box.mixin.njk


using System;
using System.Collections.Generic;
using UIWidgets.ui;
namespace UIWidgets.rendering {
{% macro RenderBoxContainerDefaultsMixin(with) %}
public abstract class
RenderBoxContainerDefaultsMixin{{with}}<ChildType, ParentDataType>
: {{with}}<ChildType, ParentDataType>
where ChildType : RenderBox
where ParentDataType : ContainerParentDataMixinBoxParentData<ChildType> {
public double? defaultComputeDistanceToFirstActualBaseline(TextBaseline baseline) {
var child = this.firstChild;
while (child != null) {
var childParentData = (ParentDataType) child.parentData;
double? result = child.getDistanceToActualBaseline(baseline);
if (result != null) {
return result.Value + childParentData.offset.dy;
}
child = childParentData.nextSibling;
}
return null;
}
public double? defaultComputeDistanceToHighestActualBaseline(TextBaseline baseline) {
double? result = null;
var child = this.firstChild;
while (child != null) {
var childParentData = (ParentDataType) child.parentData;
double? candidate = child.getDistanceToActualBaseline(baseline);
if (candidate != null) {
candidate += childParentData.offset.dy;
if (result != null) {
result = Math.Min(result.Value, candidate.Value);
} else {
result = candidate;
}
}
child = childParentData.nextSibling;
}
return result;
}
public void defaultPaint(PaintingContext context, Offset offset) {
var child = this.firstChild;
while (child != null) {
var childParentData = (ParentDataType) child.parentData;
context.paintChild(child, childParentData.offset + offset);
child = childParentData.nextSibling;
}
}
public List<ChildType> getChildrenAsList() {
var result = new List<ChildType>();
var child = this.firstChild;
while (child != null) {
var childParentData = (ParentDataType) child.parentData;
result.Add(child);
child = childParentData.nextSibling;
}
return result;
}
}
{% endmacro %}
{{ RenderBoxContainerDefaultsMixin('ContainerRenderObjectMixinRenderBox') }}
}

3
Assets/UIWidgets/rendering/box.mixin.njk.meta


fileFormatVersion: 2
guid: 936a3392b16d40d7b11ada65583df02d
timeCreated: 1535077168

585
Assets/UIWidgets/rendering/flex.cs


using System;
using System.Collections.Generic;
using UIWidgets.painting;
using UIWidgets.ui;
namespace UIWidgets.rendering {
public enum FlexFit {
tight,
loose,
}
public class FlexParentData : ContainerParentDataMixinBoxParentData<RenderBox> {
public int flex;
public FlexFit fit;
}
public enum MainAxisSize {
min,
max,
}
public enum MainAxisAlignment {
start,
end,
center,
spaceBetween,
spaceAround,
spaceEvenly,
}
public enum CrossAxisAlignment {
start,
end,
center,
stretch,
baseline,
}
public delegate double _ChildSizingFunction(RenderBox child, double extent);
public class RenderFlex : RenderBoxContainerDefaultsMixinContainerRenderObjectMixinRenderBox<RenderBox,
FlexParentData> {
public RenderFlex(
List<RenderBox> children = null,
Axis direction = Axis.horizontal,
MainAxisSize mainAxisSize = MainAxisSize.max,
MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start,
CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center,
TextDirection textDirection = TextDirection.ltr,
VerticalDirection verticalDirection = VerticalDirection.down,
TextBaseline textBaseline = TextBaseline.alphabetic
) {
this._direction = direction;
this._mainAxisAlignment = mainAxisAlignment;
this._mainAxisSize = mainAxisSize;
this._crossAxisAlignment = crossAxisAlignment;
this._textDirection = textDirection;
this._verticalDirection = verticalDirection;
this._textBaseline = textBaseline;
this.addAll(children);
}
public Axis direction {
get { return this._direction; }
set {
if (this._direction == value) {
return;
}
this._direction = value;
this.markNeedsLayout();
}
}
public Axis _direction;
public MainAxisSize mainAxisSize {
get { return this._mainAxisSize; }
set {
if (this._mainAxisSize == value) {
return;
}
this._mainAxisSize = value;
this.markNeedsLayout();
}
}
public MainAxisSize _mainAxisSize;
public MainAxisAlignment mainAxisAlignment {
get { return this._mainAxisAlignment; }
set {
if (this._mainAxisAlignment == value) {
return;
}
this._mainAxisAlignment = value;
this.markNeedsLayout();
}
}
public MainAxisAlignment _mainAxisAlignment;
public CrossAxisAlignment crossAxisAlignment {
get { return this._crossAxisAlignment; }
set {
if (this._crossAxisAlignment == value) {
return;
}
this._crossAxisAlignment = value;
this.markNeedsLayout();
}
}
public CrossAxisAlignment _crossAxisAlignment;
public TextDirection textDirection {
get { return this._textDirection; }
set {
if (this._textDirection == value) {
return;
}
this._textDirection = value;
this.markNeedsLayout();
}
}
public TextDirection _textDirection;
public VerticalDirection verticalDirection {
get { return this._verticalDirection; }
set {
if (this._verticalDirection == value) {
return;
}
this._verticalDirection = value;
this.markNeedsLayout();
}
}
public VerticalDirection _verticalDirection;
public TextBaseline textBaseline {
get { return this._textBaseline; }
set {
if (this._textBaseline == value) {
return;
}
this._textBaseline = value;
this.markNeedsLayout();
}
}
public TextBaseline _textBaseline;
public double _overflow;
public override void setupParentData(RenderObject child) {
if (!(child.parentData is FlexParentData)) {
child.parentData = new FlexParentData();
}
}
public double _getIntrinsicSize(
Axis sizingDirection,
double extent,
_ChildSizingFunction childSize
) {
if (this._direction == sizingDirection) {
double totalFlex = 0.0;
double inflexibleSpace = 0.0;
double maxFlexFractionSoFar = 0.0;
RenderBox child = this.firstChild;
while (child != null) {
int flex = this._getFlex(child);
totalFlex += flex;
if (flex > 0) {
double flexFraction = childSize(child, extent) / this._getFlex(child);
maxFlexFractionSoFar = Math.Max(maxFlexFractionSoFar, flexFraction);
} else {
inflexibleSpace += childSize(child, extent);
}
var childParentData = (FlexParentData) child.parentData;
child = childParentData.nextSibling;
}
return maxFlexFractionSoFar * totalFlex + inflexibleSpace;
} else {
double availableMainSpace = extent;
int totalFlex = 0;
double inflexibleSpace = 0.0;
double maxCrossSize = 0.0;
RenderBox child = this.firstChild;
while (child != null) {
int flex = this._getFlex(child);
totalFlex += flex;
if (flex == 0) {
double mainSize = 0.0;
double crossSize = 0.0;
switch (this._direction) {
case Axis.horizontal:
mainSize = child.getMaxIntrinsicWidth(double.PositiveInfinity);
crossSize = childSize(child, mainSize);
break;
case Axis.vertical:
mainSize = child.getMaxIntrinsicHeight(double.PositiveInfinity);
crossSize = childSize(child, mainSize);
break;
}
inflexibleSpace += mainSize;
maxCrossSize = Math.Max(maxCrossSize, crossSize);
}
var childParentData = (FlexParentData) child.parentData;
child = childParentData.nextSibling;
}
double spacePerFlex = Math.Max(0.0, (availableMainSpace - inflexibleSpace) / totalFlex);
child = this.firstChild;
while (child != null) {
int flex = this._getFlex(child);
if (flex > 0) {
maxCrossSize = Math.Max(maxCrossSize, childSize(child, spacePerFlex * flex));
}
var childParentData = (FlexParentData) child.parentData;
child = childParentData.nextSibling;
}
return maxCrossSize;
}
}
public override double computeMinIntrinsicWidth(double height) {
return this._getIntrinsicSize(
sizingDirection: Axis.horizontal,
extent: height,
childSize: (RenderBox child, double extent) => child.getMinIntrinsicWidth(extent)
);
}
public override double computeMaxIntrinsicWidth(double height) {
return this._getIntrinsicSize(
sizingDirection: Axis.horizontal,
extent: height,
childSize: (RenderBox child, double extent) => child.getMaxIntrinsicWidth(extent)
);
}
public override double computeMinIntrinsicHeight(double width) {
return this._getIntrinsicSize(
sizingDirection: Axis.vertical,
extent: width,
childSize: (RenderBox child, double extent) => child.getMinIntrinsicHeight(extent)
);
}
public override double computeMaxIntrinsicHeight(double width) {
return this._getIntrinsicSize(
sizingDirection: Axis.vertical,
extent: width,
childSize: (RenderBox child, double extent) => child.getMaxIntrinsicHeight(extent)
);
}
public override double? computeDistanceToActualBaseline(TextBaseline baseline) {
if (this._direction == Axis.horizontal) {
return this.defaultComputeDistanceToHighestActualBaseline(baseline);
}
return this.defaultComputeDistanceToFirstActualBaseline(baseline);
}
public int _getFlex(RenderBox child) {
var childParentData = (FlexParentData) child.parentData;
return childParentData.flex;
}
public FlexFit _getFit(RenderBox child) {
var childParentData = (FlexParentData) child.parentData;
return childParentData.fit;
}
public double _getCrossSize(RenderBox child) {
switch (this._direction) {
case Axis.horizontal:
return child.size.height;
case Axis.vertical:
return child.size.width;
}
return 0;
}
public double _getMainSize(RenderBox child) {
switch (this._direction) {
case Axis.horizontal:
return child.size.width;
case Axis.vertical:
return child.size.height;
}
return 0;
}
public override void performLayout() {
int totalFlex = 0;
int totalChildren = 0;
double maxMainSize = this._direction == Axis.horizontal ? this.constraints.maxWidth : this.constraints.maxHeight;
bool canFlex = maxMainSize < double.PositiveInfinity;
double crossSize = 0.0;
double allocatedSize = 0.0;
RenderBox child = this.firstChild;
RenderBox lastFlexChild = null;
while (child != null) {
var childParentData = (FlexParentData) child.parentData;
totalChildren++;
int flex = this._getFlex(child);
if (flex > 0) {
totalFlex += childParentData.flex;
lastFlexChild = child;
} else {
BoxConstraints innerConstraints = null;
if (this.crossAxisAlignment == CrossAxisAlignment.stretch) {
switch (this._direction) {
case Axis.horizontal:
innerConstraints = new BoxConstraints(minHeight: this.constraints.maxHeight,
maxHeight: this.constraints.maxHeight);
break;
case Axis.vertical:
innerConstraints = new BoxConstraints(minWidth: this.constraints.maxWidth,
maxWidth: this.constraints.maxWidth);
break;
}
} else {
switch (this._direction) {
case Axis.horizontal:
innerConstraints = new BoxConstraints(maxHeight: this.constraints.maxHeight);
break;
case Axis.vertical:
innerConstraints = new BoxConstraints(maxWidth: this.constraints.maxWidth);
break;
}
}
child.layout(innerConstraints, parentUsesSize: true);
allocatedSize += this._getMainSize(child);
crossSize = Math.Max(crossSize, this._getCrossSize(child));
}
child = childParentData.nextSibling;
}
double freeSpace = Math.Max(0.0, (canFlex ? maxMainSize : 0.0) - allocatedSize);
double allocatedFlexSpace = 0.0;
double maxBaselineDistance = 0.0;
if (totalFlex > 0 || this.crossAxisAlignment == CrossAxisAlignment.baseline) {
double spacePerFlex = canFlex && totalFlex > 0 ? (freeSpace / totalFlex) : double.NaN;
child = this.firstChild;
while (child != null) {
int flex = this._getFlex(child);
if (flex > 0) {
double maxChildExtent = canFlex
? (child == lastFlexChild ? (freeSpace - allocatedFlexSpace) : spacePerFlex * flex)
: double.PositiveInfinity;
double minChildExtent = 0.0;
switch (this._getFit(child)) {
case FlexFit.tight:
minChildExtent = maxChildExtent;
break;
case FlexFit.loose:
minChildExtent = 0.0;
break;
}
BoxConstraints innerConstraints = null;
if (this.crossAxisAlignment == CrossAxisAlignment.stretch) {
switch (this._direction) {
case Axis.horizontal:
innerConstraints = new BoxConstraints(minWidth: minChildExtent,
maxWidth: maxChildExtent,
minHeight: this.constraints.maxHeight,
maxHeight: this.constraints.maxHeight);
break;
case Axis.vertical:
innerConstraints = new BoxConstraints(minWidth: this.constraints.maxWidth,
maxWidth: this.constraints.maxWidth,
minHeight: minChildExtent,
maxHeight: maxChildExtent);
break;
}
} else {
switch (this._direction) {
case Axis.horizontal:
innerConstraints = new BoxConstraints(minWidth: minChildExtent,
maxWidth: maxChildExtent,
maxHeight: this.constraints.maxHeight);
break;
case Axis.vertical:
innerConstraints = new BoxConstraints(maxWidth: this.constraints.maxWidth,
minHeight: minChildExtent,
maxHeight: maxChildExtent);
break;
}
}
child.layout(innerConstraints, parentUsesSize: true);
double childSize = this._getMainSize(child);
allocatedSize += childSize;
allocatedFlexSpace += maxChildExtent;
crossSize = Math.Max(crossSize, this._getCrossSize(child));
}
if (this.crossAxisAlignment == CrossAxisAlignment.baseline) {
double? distance = child.getDistanceToBaseline(this.textBaseline, onlyReal: true);
if (distance != null) {
maxBaselineDistance = Math.Max(maxBaselineDistance, distance.Value);
}
}
var childParentData = (FlexParentData) child.parentData;
child = childParentData.nextSibling;
}
}
double idealSize = canFlex && this.mainAxisSize == MainAxisSize.max ? maxMainSize : allocatedSize;
double actualSize = 0.0;
double actualSizeDelta = 0.0;
switch (this._direction) {
case Axis.horizontal:
this.size = this.constraints.constrain(new Size(idealSize, crossSize));
actualSize = this.size.width;
crossSize = this.size.height;
break;
case Axis.vertical:
this.size = this.constraints.constrain(new Size(crossSize, idealSize));
actualSize = this.size.height;
crossSize = this.size.width;
break;
}
actualSizeDelta = actualSize - allocatedSize;
this._overflow = Math.Max(0.0, -actualSizeDelta);
double remainingSpace = Math.Max(0.0, actualSizeDelta);
double leadingSpace = 0.0;
double betweenSpace = 0.0;
bool flipMainAxis = !RenderFlex._startIsTopLeft(this.direction, this.textDirection, this.verticalDirection);
switch (this._mainAxisAlignment) {
case MainAxisAlignment.start:
leadingSpace = 0.0;
betweenSpace = 0.0;
break;
case MainAxisAlignment.end:
leadingSpace = remainingSpace;
betweenSpace = 0.0;
break;
case MainAxisAlignment.center:
leadingSpace = remainingSpace / 2.0;
betweenSpace = 0.0;
break;
case MainAxisAlignment.spaceBetween:
leadingSpace = 0.0;
betweenSpace = totalChildren > 1 ? remainingSpace / (totalChildren - 1) : 0.0;
break;
case MainAxisAlignment.spaceAround:
betweenSpace = totalChildren > 0 ? remainingSpace / totalChildren : 0.0;
leadingSpace = betweenSpace / 2.0;
break;
case MainAxisAlignment.spaceEvenly:
betweenSpace = totalChildren > 0 ? remainingSpace / (totalChildren + 1) : 0.0;
leadingSpace = betweenSpace;
break;
}
// Position elements
double childMainPosition = flipMainAxis ? actualSize - leadingSpace : leadingSpace;
child = this.firstChild;
while (child != null) {
var childParentData = (FlexParentData) child.parentData;
double childCrossPosition = 0.0;
switch (this._crossAxisAlignment) {
case CrossAxisAlignment.start:
case CrossAxisAlignment.end:
childCrossPosition =
RenderFlex._startIsTopLeft(
AxisUtils.flipAxis(this.direction), this.textDirection, this.verticalDirection)
== (this._crossAxisAlignment == CrossAxisAlignment.start)
? 0.0
: crossSize - this._getCrossSize(child);
break;
case CrossAxisAlignment.center:
childCrossPosition = crossSize / 2.0 - this._getCrossSize(child) / 2.0;
break;
case CrossAxisAlignment.stretch:
childCrossPosition = 0.0;
break;
case CrossAxisAlignment.baseline:
childCrossPosition = 0.0;
if (this._direction == Axis.horizontal) {
double? distance = child.getDistanceToBaseline(this.textBaseline, onlyReal: true);
if (distance != null) {
childCrossPosition = maxBaselineDistance - distance.Value;
}
}
break;
}
if (flipMainAxis) {
childMainPosition -= this._getMainSize(child);
}
switch (this._direction) {
case Axis.horizontal:
childParentData.offset = new Offset(childMainPosition, childCrossPosition);
break;
case Axis.vertical:
childParentData.offset = new Offset(childCrossPosition, childMainPosition);
break;
}
if (flipMainAxis) {
childMainPosition -= betweenSpace;
} else {
childMainPosition += this._getMainSize(child) + betweenSpace;
}
child = childParentData.nextSibling;
}
}
private static bool _startIsTopLeft(Axis direction, TextDirection textDirection,
VerticalDirection verticalDirection) {
switch (direction) {
case Axis.horizontal:
switch (textDirection) {
case TextDirection.ltr:
return true;
case TextDirection.rtl:
return false;
}
break;
case Axis.vertical:
switch (verticalDirection) {
case VerticalDirection.down:
return true;
case VerticalDirection.up:
return false;
}
break;
}
return true;
}
public override void paint(PaintingContext context, Offset offset) {
if (this._overflow <= 0.0) {
this.defaultPaint(context, offset);
return;
}
if (this.size.isEmpty)
return;
context.pushClipRect(this.needsCompositing, offset, Offset.zero & this.size, this.defaultPaint);
}
}
}

3
Assets/UIWidgets/rendering/flex.cs.meta


fileFormatVersion: 2
guid: a376f91ffd8d45e8a5af74f6f2f044b7
timeCreated: 1535074163
正在加载...
取消
保存