Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(196)

Side by Side Diff: sky/sdk/lib/rendering/auto_layout.dart

Issue 1230583003: Integrate the linear constraint solver into Sky as a RenderBox subclass. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 import 'box.dart';
6 import 'object.dart';
7 import 'package:cassowary/cassowary.dart' as AL;
abarth-chromium 2015/07/08 22:22:02 ditto
Chinmay 2015/07/08 23:01:01 ack
8
9 class AutoLayoutParentData extends BoxParentData
10 with ContainerParentDataMixin<RenderBox>, _AutoLayoutParamMixin {
11
12 final RenderBox _renderBox;
13
14 AutoLayoutParentData(this._renderBox) {
15 _setupLayoutParameters(this);
16 }
17
18 @override
19 void _applyAutolayoutParameterUpdates() {
20 BoxConstraints box = new BoxConstraints.tightFor(
21 width: _rightEdge.value - _leftEdge.value,
22 height: _bottomEdge.value - _topEdge.value);
23
24 _renderBox.layout(box, parentUsesSize: false);
25 this.position = new Point(_leftEdge.value, _topEdge.value);
abarth-chromium 2015/07/08 22:22:01 No need for |this.|
Chinmay 2015/07/08 23:01:01 ack
26 }
27
28 @override
29 List<AL.Constraint> _constructImplicitConstraints() {
30 return [
31 // The left edge must be positive
32 _leftEdge >= AL.CM(0.0),
33
34 // Width must be positive
35 _rightEdge >= _leftEdge,
36 ];
37 }
38 }
39
40 class RenderAutoLayout extends RenderBox
41 with ContainerRenderObjectMixin<RenderBox, AutoLayoutParentData>,
42 RenderBoxContainerDefaultsMixin<RenderBox, AutoLayoutParentData>,
43 _AutoLayoutParamMixin {
44
45 final AL.Solver _solver = new AL.Solver();
46 List<AL.Constraint> _explicitConstraints = new List<AL.Constraint>();
47
48 RenderAutoLayout({List<RenderBox> children}) {
49 _setupLayoutParameters(this);
50 _setupEditVariablesInSolver(_solver, AL.Priority.required - 1);
51
52 addAll(children);
53 }
54
55 /// Adds all the given constraints to the solver. Either all constraints are
56 /// added or none
57 AL.Result addConstraints(List<AL.Constraint> constraints) {
58 AL.Result res = _solver.addConstraints(constraints);
abarth-chromium 2015/07/08 22:22:01 s/res/result/ Please use complete words in variab
Chinmay 2015/07/08 23:01:01 ack
59
60 if (res == AL.Result.success) {
61 markNeedsLayout();
62 _explicitConstraints.addAll(constraints);
63 }
64
65 return res;
66 }
67
68 /// Add the given constraint to the solver.
69 AL.Result addConstraint(AL.Constraint constraint) {
70 AL.Result res = _solver.addConstraint(constraint);
71
72 if (res == AL.Result.success) {
73 markNeedsLayout();
74 _explicitConstraints.add(constraint);
75 }
76
77 return res;
78 }
79
80 /// Removes all explicitly added constraints.
81 AL.Result clearAllConstraints() {
82 AL.Result res = _solver.removeConstraints(_explicitConstraints);
83
84 if (res == AL.Result.success) {
85 markNeedsLayout();
86 _explicitConstraints = new List<AL.Constraint>();
87 }
88
89 return res;
90 }
91
92 @override
93 void setupParentData(RenderObject child) {
94 if (child.parentData is! AutoLayoutParentData) {
95 child.parentData = new AutoLayoutParentData(child);
96 }
97 }
98
99 @override
100 void set size(Size value) {
101 super.size = value;
102 _applyEditsAtSize(_solver, value);
103 }
abarth-chromium 2015/07/08 22:22:02 You shouldn't need to override the size setter. T
Chinmay 2015/07/08 23:01:01 ack. Good to know.
104
105 @override
106 void performLayout() {
107 // Step 1: Update dimensions of self
108 size = constraints.smallest;
abarth-chromium 2015/07/08 22:22:01 Typically we default to constraints.biggest becaus
Chinmay 2015/07/08 23:01:01 ack
109
110 // Step 2: Resolve solver updates and flush parameters
111
112 // We don't iterate over the children, instead, we ask the solver to tell
113 // us the updated parameters. Attached to the parameters (via the context)
114 // are the _AutoLayoutParamMixin instances.
115 for (_AutoLayoutParamMixin update in _solver.flushUpdates()) {
116 update._applyAutolayoutParameterUpdates();
117 }
118 }
119
120 @override
121 void _applyAutolayoutParameterUpdates() {
122 // Nothing to do since the size update has already been presented to the
123 // solver as an edit variable modification. The invokation of this method
124 // only indicates that the value has been flushed to the variable.
125 }
126
127 @override
128 void hitTestChildren(HitTestResult result, {Point position}) =>
129 defaultHitTestChildren(result, position: position);
130
131 @override
132 void paint(PaintingCanvas canvas, Offset offset) =>
133 defaultPaint(canvas, offset);
134
135 @override
136 void adoptChild(RenderObject child) {
137 // Make sure to call super first to setup the parent data
138 super.adoptChild(child);
139 child.parentData._setupImplicitConstraints(_solver);
140 }
141
142 @override
143 void dropChild(RenderObject child) {
144 child.parentData._collectImplicitConstraints(_solver);
145
146 // Call super last as this collects parent data
147 super.dropChild(child);
148 }
149
150 @override
151 List<AL.Constraint> _constructImplicitConstraints() {
152 // Only edits are present on layout containers
153 return null;
154 }
155 }
156
157 abstract class _AutoLayoutParamMixin {
abarth-chromium 2015/07/08 22:22:01 I would move this up in the file given that it's r
Chinmay 2015/07/08 23:01:01 ack. I was trying to keep the internal classes tow
158 // Ideally, the edges would all be final, but then they would have to be
159 // initialized before the constructor. Not sure how to do that using a Mixin
160 AL.Param _leftEdge;
161 AL.Param _rightEdge;
162 AL.Param _topEdge;
163 AL.Param _bottomEdge;
164
165 List<AL.Constraint> _implicitConstraints;
166
167 AL.Param get leftEdge => _leftEdge;
168 AL.Param get rightEdge => _rightEdge;
169 AL.Param get topEdge => _topEdge;
170 AL.Param get bottomEdge => _bottomEdge;
171
172 AL.Expression get width => _rightEdge - _leftEdge;
173 AL.Expression get height => _bottomEdge - _topEdge;
174
175 AL.Expression get horizontalCenter => (_leftEdge + _rightEdge) / AL.CM(2.0);
176 AL.Expression get verticalCenter => (_topEdge + _bottomEdge) / AL.CM(2.0);
177
178 void _setupLayoutParameters(dynamic context) {
179 _leftEdge = new AL.Param.withContext(context);
180 _rightEdge = new AL.Param.withContext(context);
181 _topEdge = new AL.Param.withContext(context);
182 _bottomEdge = new AL.Param.withContext(context);
183 }
184
185 void _setupEditVariablesInSolver(AL.Solver solver, double priority) {
186 solver.addEditVariables([
187 _leftEdge.variable,
188 _rightEdge.variable,
189 _topEdge.variable,
190 _bottomEdge.variable], priority);
191 }
192
193 void _applyEditsAtSize(AL.Solver solver, Size size) {
194 solver.suggestValueForVariable(_leftEdge.variable, 0.0);
195 solver.suggestValueForVariable(_topEdge.variable, 0.0);
196 solver.suggestValueForVariable(_bottomEdge.variable, size.height);
197 solver.suggestValueForVariable(_rightEdge.variable, size.width);
198 }
199
200 void _applyAutolayoutParameterUpdates();
201 List<AL.Constraint> _constructImplicitConstraints();
202
203 void _setupImplicitConstraints(AL.Solver solver) {
204 List<AL.Constraint> implicit = _constructImplicitConstraints();
205
206 if (implicit == null || implicit.length == 0) {
207 return;
208 }
209
210 AL.Result res = solver.addConstraints(implicit);
211 assert(res == AL.Result.success);
212
213 _implicitConstraints = implicit;
214 }
215
216 void _collectImplicitConstraints(AL.Solver solver) {
217 if (_implicitConstraints == null || _implicitConstraints.length == 0) {
218 return;
219 }
220
221 AL.Result res = solver.removeConstraints(_implicitConstraints);
222 assert(res == AL.Result.success);
223
224 _implicitConstraints = null;
225 }
226 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698