Chromium Code Reviews| 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 'box.dart'; | 5 import 'box.dart'; |
| 6 import 'object.dart'; | 6 import 'object.dart'; |
| 7 import 'package:cassowary/cassowary.dart' as al; | 7 import 'package:cassowary/cassowary.dart' as al; |
| 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 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 46 _bottomEdge.variable], priority); | 46 _bottomEdge.variable], priority); |
| 47 } | 47 } |
| 48 | 48 |
| 49 void _applyEditsAtSize(al.Solver solver, Size size) { | 49 void _applyEditsAtSize(al.Solver solver, Size size) { |
| 50 solver.suggestValueForVariable(_leftEdge.variable, 0.0); | 50 solver.suggestValueForVariable(_leftEdge.variable, 0.0); |
| 51 solver.suggestValueForVariable(_topEdge.variable, 0.0); | 51 solver.suggestValueForVariable(_topEdge.variable, 0.0); |
| 52 solver.suggestValueForVariable(_bottomEdge.variable, size.height); | 52 solver.suggestValueForVariable(_bottomEdge.variable, size.height); |
| 53 solver.suggestValueForVariable(_rightEdge.variable, size.width); | 53 solver.suggestValueForVariable(_rightEdge.variable, size.width); |
| 54 } | 54 } |
| 55 | 55 |
| 56 /// Called when the solver has updated at least one of the layout parameters | |
| 57 /// of this object. The object is now responsible for applying this update to | |
| 58 /// it other properties (if necessary) | |
|
Hixie
2015/07/09 21:52:07
s/it/the/, I assume?
| |
| 56 void _applyAutolayoutParameterUpdates(); | 59 void _applyAutolayoutParameterUpdates(); |
| 60 | |
| 61 /// Returns the set of implicit constraints that need to be applied to all | |
| 62 /// instances of this class when they are moved into a render object with an | |
| 63 /// active solver. If no implicit constraints needs to be applied, the object | |
| 64 /// may return null. | |
|
Hixie
2015/07/09 21:52:07
If it's for all instances, why isn't it static?
| |
| 57 List<al.Constraint> _constructImplicitConstraints(); | 65 List<al.Constraint> _constructImplicitConstraints(); |
| 58 | 66 |
| 59 void _setupImplicitConstraints(al.Solver solver) { | 67 void _setupImplicitConstraints(al.Solver solver) { |
| 60 List<al.Constraint> implicit = _constructImplicitConstraints(); | 68 List<al.Constraint> implicit = _constructImplicitConstraints(); |
| 61 | 69 |
| 62 if (implicit == null || implicit.length == 0) { | 70 if (implicit == null || implicit.length == 0) { |
| 63 return; | 71 return; |
| 64 } | 72 } |
| 65 | 73 |
| 66 al.Result result = solver.addConstraints(implicit); | 74 al.Result result = solver.addConstraints(implicit); |
| 67 assert(result == al.Result.success); | 75 assert(result == al.Result.success); |
| 68 | 76 |
| 69 _implicitConstraints = implicit; | 77 _implicitConstraints = implicit; |
| 70 } | 78 } |
| 71 | 79 |
| 72 void _collectImplicitConstraints(al.Solver solver) { | 80 void _collectImplicitConstraints(al.Solver solver) { |
| 73 if (_implicitConstraints == null || _implicitConstraints.length == 0) { | 81 if (_implicitConstraints == null || _implicitConstraints.length == 0) { |
| 74 return; | 82 return; |
| 75 } | 83 } |
| 76 | 84 |
| 77 al.Result result = solver.removeConstraints(_implicitConstraints); | 85 al.Result result = solver.removeConstraints(_implicitConstraints); |
| 78 assert(result == al.Result.success); | 86 assert(result == al.Result.success); |
| 79 | 87 |
| 80 _implicitConstraints = null; | 88 _implicitConstraints = null; |
| 81 } | 89 } |
| 90 | |
| 82 } | 91 } |
| 83 | 92 |
| 84 class AutoLayoutParentData extends BoxParentData | 93 class AutoLayoutParentData extends BoxParentData |
| 85 with ContainerParentDataMixin<RenderBox>, _AutoLayoutParamMixin { | 94 with ContainerParentDataMixin<RenderBox>, _AutoLayoutParamMixin { |
| 86 | 95 |
| 87 final RenderBox _renderBox; | |
| 88 | |
| 89 AutoLayoutParentData(this._renderBox) { | 96 AutoLayoutParentData(this._renderBox) { |
| 90 _setupLayoutParameters(this); | 97 _setupLayoutParameters(this); |
| 91 } | 98 } |
| 92 | 99 |
| 100 final RenderBox _renderBox; | |
| 101 | |
| 93 @override | 102 @override |
| 94 void _applyAutolayoutParameterUpdates() { | 103 void _applyAutolayoutParameterUpdates() { |
| 95 BoxConstraints box = new BoxConstraints.tightFor( | 104 BoxConstraints box = new BoxConstraints.tightFor( |
| 96 width: _rightEdge.value - _leftEdge.value, | 105 width: _rightEdge.value - _leftEdge.value, |
| 97 height: _bottomEdge.value - _topEdge.value); | 106 height: _bottomEdge.value - _topEdge.value); |
| 98 | 107 |
| 99 _renderBox.layout(box, parentUsesSize: false); | 108 _renderBox.layout(box, parentUsesSize: false); |
| 100 position = new Point(_leftEdge.value, _topEdge.value); | 109 position = new Point(_leftEdge.value, _topEdge.value); |
| 101 } | 110 } |
| 102 | 111 |
| 103 @override | 112 @override |
| 104 List<al.Constraint> _constructImplicitConstraints() { | 113 List<al.Constraint> _constructImplicitConstraints() { |
| 105 return [ | 114 return [ |
| 106 // The left edge must be positive | 115 // The left edge must be positive |
| 107 _leftEdge >= al.cm(0.0), | 116 _leftEdge >= al.cm(0.0), |
| 108 | 117 |
| 109 // Width must be positive | 118 // Width must be positive |
| 110 _rightEdge >= _leftEdge, | 119 _rightEdge >= _leftEdge, |
| 111 ]; | 120 ]; |
| 112 } | 121 } |
| 113 } | 122 } |
| 114 | 123 |
| 115 class RenderAutoLayout extends RenderBox | 124 class RenderAutoLayout extends RenderBox |
| 116 with ContainerRenderObjectMixin<RenderBox, AutoLayoutParentData>, | 125 with ContainerRenderObjectMixin<RenderBox, AutoLayoutParentData>, |
| 117 RenderBoxContainerDefaultsMixin<RenderBox, AutoLayoutParentData>, | 126 RenderBoxContainerDefaultsMixin<RenderBox, AutoLayoutParentData>, |
| 118 _AutoLayoutParamMixin { | 127 _AutoLayoutParamMixin { |
| 119 | 128 |
| 129 RenderAutoLayout({ List<RenderBox> children }) { | |
| 130 _setupLayoutParameters(this); | |
| 131 _setupEditVariablesInSolver(_solver, al.Priority.required - 1); | |
| 132 addAll(children); | |
| 133 } | |
| 134 | |
| 120 final al.Solver _solver = new al.Solver(); | 135 final al.Solver _solver = new al.Solver(); |
| 121 List<al.Constraint> _explicitConstraints = new List<al.Constraint>(); | 136 List<al.Constraint> _explicitConstraints = new List<al.Constraint>(); |
| 122 | 137 |
| 123 RenderAutoLayout({List<RenderBox> children}) { | |
| 124 _setupLayoutParameters(this); | |
| 125 _setupEditVariablesInSolver(_solver, al.Priority.required - 1); | |
| 126 | |
| 127 addAll(children); | |
| 128 } | |
| 129 | |
| 130 /// Adds all the given constraints to the solver. Either all constraints are | 138 /// Adds all the given constraints to the solver. Either all constraints are |
| 131 /// added or none | 139 /// added or none |
| 132 al.Result addConstraints(List<al.Constraint> constraints) { | 140 al.Result addConstraints(List<al.Constraint> constraints) { |
| 133 al.Result result = _solver.addConstraints(constraints); | 141 al.Result result = _solver.addConstraints(constraints); |
| 134 | |
| 135 if (result == al.Result.success) { | 142 if (result == al.Result.success) { |
| 136 markNeedsLayout(); | 143 markNeedsLayout(); |
| 137 _explicitConstraints.addAll(constraints); | 144 _explicitConstraints.addAll(constraints); |
| 138 } | 145 } |
| 139 | |
| 140 return result; | 146 return result; |
| 141 } | 147 } |
| 142 | 148 |
| 143 /// Add the given constraint to the solver. | 149 /// Add the given constraint to the solver. |
| 144 al.Result addConstraint(al.Constraint constraint) { | 150 al.Result addConstraint(al.Constraint constraint) { |
| 145 al.Result result = _solver.addConstraint(constraint); | 151 al.Result result = _solver.addConstraint(constraint); |
| 146 | 152 |
| 147 if (result == al.Result.success) { | 153 if (result == al.Result.success) { |
| 148 markNeedsLayout(); | 154 markNeedsLayout(); |
| 149 _explicitConstraints.add(constraint); | 155 _explicitConstraints.add(constraint); |
| 150 } | 156 } |
| 151 | 157 |
| 152 return result; | 158 return result; |
| 153 } | 159 } |
| 154 | 160 |
| 155 /// Removes all explicitly added constraints. | 161 /// Removes all explicitly added constraints. |
| 156 al.Result clearAllConstraints() { | 162 al.Result clearAllConstraints() { |
| 157 al.Result result = _solver.removeConstraints(_explicitConstraints); | 163 al.Result result = _solver.removeConstraints(_explicitConstraints); |
| 158 | 164 |
| 159 if (result == al.Result.success) { | 165 if (result == al.Result.success) { |
| 160 markNeedsLayout(); | 166 markNeedsLayout(); |
| 161 _explicitConstraints = new List<al.Constraint>(); | 167 _explicitConstraints = new List<al.Constraint>(); |
| 162 } | 168 } |
| 163 | 169 |
| 164 return result; | 170 return result; |
| 165 } | 171 } |
| 166 | 172 |
| 167 @override | 173 @override |
| 168 void setupParentData(RenderObject child) { | 174 void setupParentData(RenderObject child) { |
| 169 if (child.parentData is! AutoLayoutParentData) { | 175 if (child.parentData is! AutoLayoutParentData) |
| 170 child.parentData = new AutoLayoutParentData(child); | 176 child.parentData = new AutoLayoutParentData(child); |
| 171 } | |
| 172 } | 177 } |
| 173 | 178 |
| 174 @override | 179 @override |
| 175 void performLayout() { | 180 void performLayout() { |
| 176 // Step 1: Update dimensions of self | 181 // Step 1: Update dimensions of self |
| 177 size = constraints.biggest; | 182 size = constraints.biggest; |
| 178 _applyEditsAtSize(_solver, size); | 183 _applyEditsAtSize(_solver, size); |
| 179 | 184 |
| 180 // Step 2: Resolve solver updates and flush parameters | 185 // Step 2: Resolve solver updates and flush parameters |
| 181 | 186 |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 206 void adoptChild(RenderObject child) { | 211 void adoptChild(RenderObject child) { |
| 207 // Make sure to call super first to setup the parent data | 212 // Make sure to call super first to setup the parent data |
| 208 super.adoptChild(child); | 213 super.adoptChild(child); |
| 209 child.parentData._setupImplicitConstraints(_solver); | 214 child.parentData._setupImplicitConstraints(_solver); |
| 210 } | 215 } |
| 211 | 216 |
| 212 @override | 217 @override |
| 213 void dropChild(RenderObject child) { | 218 void dropChild(RenderObject child) { |
| 214 child.parentData._collectImplicitConstraints(_solver); | 219 child.parentData._collectImplicitConstraints(_solver); |
| 215 | 220 |
| 216 // Call super last as this collects parent data | |
| 217 super.dropChild(child); | 221 super.dropChild(child); |
| 218 } | 222 } |
| 219 | 223 |
| 220 @override | 224 @override |
| 221 List<al.Constraint> _constructImplicitConstraints() { | 225 List<al.Constraint> _constructImplicitConstraints() { |
| 222 // Only edits are present on layout containers | 226 // Only edits variables are present on layout containers. If, in the future, |
| 227 // implicit constraints (for say margins, padding, etc.) need to be added, | |
| 228 // they must be returned from here. | |
| 223 return null; | 229 return null; |
| 224 } | 230 } |
| 225 } | 231 } |
| OLD | NEW |