| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 import 'package:cassowary/cassowary.dart' as al; | 5 import 'package:cassowary/cassowary.dart' as al; |
| 6 import 'package:sky/rendering/box.dart'; | 6 import 'package:sky/rendering/box.dart'; |
| 7 import 'package:sky/rendering/object.dart'; | 7 import 'package:sky/rendering/object.dart'; |
| 8 | 8 |
| 9 /// Hosts the edge parameters and vends useful methods to construct expressions | 9 /// Hosts the edge parameters and vends useful methods to construct expressions |
| 10 /// for constraints. Also sets up and manages implicit constraints and edit | 10 /// for constraints. Also sets up and manages implicit constraints and edit |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 70 if (implicit == null || implicit.length == 0) { | 70 if (implicit == null || implicit.length == 0) { |
| 71 return; | 71 return; |
| 72 } | 72 } |
| 73 | 73 |
| 74 al.Result result = solver.addConstraints(implicit); | 74 al.Result result = solver.addConstraints(implicit); |
| 75 assert(result == al.Result.success); | 75 assert(result == al.Result.success); |
| 76 | 76 |
| 77 _implicitConstraints = implicit; | 77 _implicitConstraints = implicit; |
| 78 } | 78 } |
| 79 | 79 |
| 80 void _collectImplicitConstraints(al.Solver solver) { | 80 void _removeImplicitConstraints(al.Solver solver) { |
| 81 if (_implicitConstraints == null || _implicitConstraints.length == 0) { | 81 if (_implicitConstraints == null || _implicitConstraints.length == 0) { |
| 82 return; | 82 return; |
| 83 } | 83 } |
| 84 | 84 |
| 85 al.Result result = solver.removeConstraints(_implicitConstraints); | 85 al.Result result = solver.removeConstraints(_implicitConstraints); |
| 86 assert(result == al.Result.success); | 86 assert(result == al.Result.success); |
| 87 | 87 |
| 88 _implicitConstraints = null; | 88 _implicitConstraints = null; |
| 89 } | 89 } |
| 90 | |
| 91 } | 90 } |
| 92 | 91 |
| 93 class AutoLayoutParentData extends BoxParentData | 92 class AutoLayoutParentData extends BoxParentData |
| 94 with ContainerParentDataMixin<RenderBox>, _AutoLayoutParamMixin { | 93 with ContainerParentDataMixin<RenderBox>, _AutoLayoutParamMixin { |
| 95 | 94 |
| 96 AutoLayoutParentData(this._renderBox) { | 95 AutoLayoutParentData(this._renderBox) { |
| 97 _setupLayoutParameters(this); | 96 _setupLayoutParameters(this); |
| 98 } | 97 } |
| 99 | 98 |
| 100 final RenderBox _renderBox; | 99 final RenderBox _renderBox; |
| 101 | 100 |
| 102 @override | |
| 103 void _applyAutolayoutParameterUpdates() { | 101 void _applyAutolayoutParameterUpdates() { |
| 104 BoxConstraints box = new BoxConstraints.tightFor( | 102 // This is called by the parent's layout function |
| 105 width: _rightEdge.value - _leftEdge.value, | 103 // to lay our box out. |
| 106 height: _bottomEdge.value - _topEdge.value); | 104 assert(_renderBox.parentData == this); |
| 107 | 105 assert(_renderBox.parent.debugDoingThisLayout); |
| 108 _renderBox.layout(box, parentUsesSize: false); | 106 BoxConstraints size = new BoxConstraints.tightFor( |
| 107 width: _rightEdge.value - _leftEdge.value, |
| 108 height: _bottomEdge.value - _topEdge.value |
| 109 ); |
| 110 _renderBox.layout(size); |
| 109 position = new Point(_leftEdge.value, _topEdge.value); | 111 position = new Point(_leftEdge.value, _topEdge.value); |
| 110 } | 112 } |
| 111 | 113 |
| 112 @override | |
| 113 List<al.Constraint> _constructImplicitConstraints() { | 114 List<al.Constraint> _constructImplicitConstraints() { |
| 114 return [ | 115 return [ |
| 115 // The left edge must be positive | 116 _leftEdge >= al.cm(0.0), // The left edge must be positive. |
| 116 _leftEdge >= al.cm(0.0), | 117 _rightEdge >= _leftEdge, // Width must be positive. |
| 117 | |
| 118 // Width must be positive | |
| 119 _rightEdge >= _leftEdge, | |
| 120 ]; | 118 ]; |
| 121 } | 119 } |
| 120 |
| 122 } | 121 } |
| 123 | 122 |
| 124 class RenderAutoLayout extends RenderBox | 123 class RenderAutoLayout extends RenderBox |
| 125 with ContainerRenderObjectMixin<RenderBox, AutoLayoutParentData>, | 124 with ContainerRenderObjectMixin<RenderBox, AutoLayoutParentData>, |
| 126 RenderBoxContainerDefaultsMixin<RenderBox, AutoLayoutParentData>, | 125 RenderBoxContainerDefaultsMixin<RenderBox, AutoLayoutParentData>, |
| 127 _AutoLayoutParamMixin { | 126 _AutoLayoutParamMixin { |
| 128 | 127 |
| 129 RenderAutoLayout({ List<RenderBox> children }) { | 128 RenderAutoLayout({ List<RenderBox> children }) { |
| 130 _setupLayoutParameters(this); | 129 _setupLayoutParameters(this); |
| 131 _setupEditVariablesInSolver(_solver, al.Priority.required - 1); | 130 _setupEditVariablesInSolver(_solver, al.Priority.required - 1); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 163 al.Result result = _solver.removeConstraints(_explicitConstraints); | 162 al.Result result = _solver.removeConstraints(_explicitConstraints); |
| 164 | 163 |
| 165 if (result == al.Result.success) { | 164 if (result == al.Result.success) { |
| 166 markNeedsLayout(); | 165 markNeedsLayout(); |
| 167 _explicitConstraints = new List<al.Constraint>(); | 166 _explicitConstraints = new List<al.Constraint>(); |
| 168 } | 167 } |
| 169 | 168 |
| 170 return result; | 169 return result; |
| 171 } | 170 } |
| 172 | 171 |
| 173 @override | 172 void adoptChild(RenderObject child) { |
| 173 // Make sure to call super first to setup the parent data |
| 174 super.adoptChild(child); |
| 175 child.parentData._setupImplicitConstraints(_solver); |
| 176 } |
| 177 |
| 178 void dropChild(RenderObject child) { |
| 179 child.parentData._removeImplicitConstraints(_solver); |
| 180 super.dropChild(child); |
| 181 } |
| 182 |
| 174 void setupParentData(RenderObject child) { | 183 void setupParentData(RenderObject child) { |
| 175 if (child.parentData is! AutoLayoutParentData) | 184 if (child.parentData is! AutoLayoutParentData) |
| 176 child.parentData = new AutoLayoutParentData(child); | 185 child.parentData = new AutoLayoutParentData(child); |
| 177 } | 186 } |
| 178 | 187 |
| 179 @override | 188 bool get sizedByParent => true; |
| 189 |
| 190 void performResize() { |
| 191 size = constraints.biggest; |
| 192 } |
| 193 |
| 180 void performLayout() { | 194 void performLayout() { |
| 181 // Step 1: Update dimensions of self | 195 // Step 1: Update dimensions of self |
| 182 size = constraints.biggest; | |
| 183 _applyEditsAtSize(_solver, size); | 196 _applyEditsAtSize(_solver, size); |
| 184 | 197 |
| 185 // Step 2: Resolve solver updates and flush parameters | 198 // Step 2: Resolve solver updates and flush parameters |
| 186 | 199 |
| 187 // We don't iterate over the children, instead, we ask the solver to tell | 200 // We don't iterate over the children, instead, we ask the solver to tell |
| 188 // us the updated parameters. Attached to the parameters (via the context) | 201 // us the updated parameters. Attached to the parameters (via the context) |
| 189 // are the _AutoLayoutParamMixin instances. | 202 // are the _AutoLayoutParamMixin instances. |
| 190 for (_AutoLayoutParamMixin update in _solver.flushUpdates()) { | 203 for (_AutoLayoutParamMixin update in _solver.flushUpdates()) { |
| 191 update._applyAutolayoutParameterUpdates(); | 204 update._applyAutolayoutParameterUpdates(); |
| 192 } | 205 } |
| 193 } | 206 } |
| 194 | 207 |
| 195 @override | |
| 196 void _applyAutolayoutParameterUpdates() { | 208 void _applyAutolayoutParameterUpdates() { |
| 197 // Nothing to do since the size update has already been presented to the | 209 // Nothing to do since the size update has already been presented to the |
| 198 // solver as an edit variable modification. The invokation of this method | 210 // solver as an edit variable modification. The invokation of this method |
| 199 // only indicates that the value has been flushed to the variable. | 211 // only indicates that the value has been flushed to the variable. |
| 200 } | 212 } |
| 201 | 213 |
| 202 @override | 214 void hitTestChildren(HitTestResult result, {Point position}) { |
| 203 void hitTestChildren(HitTestResult result, {Point position}) => | 215 defaultHitTestChildren(result, position: position); |
| 204 defaultHitTestChildren(result, position: position); | |
| 205 | |
| 206 @override | |
| 207 void paint(PaintingCanvas canvas, Offset offset) => | |
| 208 defaultPaint(canvas, offset); | |
| 209 | |
| 210 @override | |
| 211 void adoptChild(RenderObject child) { | |
| 212 // Make sure to call super first to setup the parent data | |
| 213 super.adoptChild(child); | |
| 214 child.parentData._setupImplicitConstraints(_solver); | |
| 215 } | 216 } |
| 216 | 217 |
| 217 @override | 218 void paint(PaintingCanvas canvas, Offset offset) { |
| 218 void dropChild(RenderObject child) { | 219 defaultPaint(canvas, offset); |
| 219 child.parentData._collectImplicitConstraints(_solver); | |
| 220 | |
| 221 super.dropChild(child); | |
| 222 } | 220 } |
| 223 | 221 |
| 224 @override | |
| 225 List<al.Constraint> _constructImplicitConstraints() { | 222 List<al.Constraint> _constructImplicitConstraints() { |
| 226 // Only edits variables are present on layout containers. If, in the future, | 223 // Only edits variables are present on layout containers. If, in the future, |
| 227 // implicit constraints (for say margins, padding, etc.) need to be added, | 224 // implicit constraints (for say margins, padding, etc.) need to be added, |
| 228 // they must be returned from here. | 225 // they must be returned from here. |
| 229 return null; | 226 return null; |
| 230 } | 227 } |
| 231 } | 228 } |
| OLD | NEW |