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

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: Address CL concerns 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;
8
9 /// Hosts the edge parameters and vends useful methods to construct expressions
10 /// for constraints. Also sets up and manages implicit constraints and edit
11 /// variables. Used as a mixin by layout containers and parent data instances
12 /// of render boxes taking part in auto layout
13 abstract class _AutoLayoutParamMixin {
14 // Ideally, the edges would all be final, but then they would have to be
15 // initialized before the constructor. Not sure how to do that using a Mixin
Hixie 2015/07/09 00:53:14 Why can't you just use a constructor?
Hixie 2015/07/09 22:05:09 i think you missed this one. :-)
16 al.Param _leftEdge;
17 al.Param _rightEdge;
18 al.Param _topEdge;
19 al.Param _bottomEdge;
20
21 List<al.Constraint> _implicitConstraints;
22
23 al.Param get leftEdge => _leftEdge;
24 al.Param get rightEdge => _rightEdge;
25 al.Param get topEdge => _topEdge;
26 al.Param get bottomEdge => _bottomEdge;
27
28 al.Expression get width => _rightEdge - _leftEdge;
29 al.Expression get height => _bottomEdge - _topEdge;
30
31 al.Expression get horizontalCenter => (_leftEdge + _rightEdge) / al.CM(2.0);
32 al.Expression get verticalCenter => (_topEdge + _bottomEdge) / al.CM(2.0);
33
34 void _setupLayoutParameters(dynamic context) {
35 _leftEdge = new al.Param.withContext(context);
36 _rightEdge = new al.Param.withContext(context);
37 _topEdge = new al.Param.withContext(context);
38 _bottomEdge = new al.Param.withContext(context);
39 }
40
41 void _setupEditVariablesInSolver(al.Solver solver, double priority) {
42 solver.addEditVariables([
43 _leftEdge.variable,
44 _rightEdge.variable,
45 _topEdge.variable,
46 _bottomEdge.variable], priority);
47 }
48
49 void _applyEditsAtSize(al.Solver solver, Size size) {
50 solver.suggestValueForVariable(_leftEdge.variable, 0.0);
51 solver.suggestValueForVariable(_topEdge.variable, 0.0);
52 solver.suggestValueForVariable(_bottomEdge.variable, size.height);
53 solver.suggestValueForVariable(_rightEdge.variable, size.width);
54 }
55
56 void _applyAutolayoutParameterUpdates();
57 List<al.Constraint> _constructImplicitConstraints();
58
59 void _setupImplicitConstraints(al.Solver solver) {
60 List<al.Constraint> implicit = _constructImplicitConstraints();
61
62 if (implicit == null || implicit.length == 0) {
63 return;
64 }
65
66 al.Result result = solver.addConstraints(implicit);
67 assert(result == al.Result.success);
68
69 _implicitConstraints = implicit;
70 }
71
72 void _collectImplicitConstraints(al.Solver solver) {
73 if (_implicitConstraints == null || _implicitConstraints.length == 0) {
74 return;
75 }
76
77 al.Result result = solver.removeConstraints(_implicitConstraints);
78 assert(result == al.Result.success);
79
80 _implicitConstraints = null;
81 }
82 }
83
84 class AutoLayoutParentData extends BoxParentData
85 with ContainerParentDataMixin<RenderBox>, _AutoLayoutParamMixin {
86
87 final RenderBox _renderBox;
88
89 AutoLayoutParentData(this._renderBox) {
90 _setupLayoutParameters(this);
Hixie 2015/07/09 00:53:15 put constructors before fields
Chinmay 2015/07/09 21:44:19 ack
91 }
92
93 @override
Hixie 2015/07/09 00:53:14 remove the @override annotations (or add them acro
Chinmay 2015/07/09 21:44:20 ack
94 void _applyAutolayoutParameterUpdates() {
Hixie 2015/07/09 00:53:15 Put a comment here explaining that this is called
Chinmay 2015/07/09 21:44:20 ack. Since this is part of the abstract class that
95 BoxConstraints box = new BoxConstraints.tightFor(
96 width: _rightEdge.value - _leftEdge.value,
97 height: _bottomEdge.value - _topEdge.value);
98
99 _renderBox.layout(box, parentUsesSize: false);
100 position = new Point(_leftEdge.value, _topEdge.value);
101 }
102
103 @override
104 List<al.Constraint> _constructImplicitConstraints() {
105 return [
106 // The left edge must be positive
107 _leftEdge >= al.CM(0.0),
108
109 // Width must be positive
110 _rightEdge >= _leftEdge,
111 ];
112 }
113 }
Hixie 2015/07/09 00:53:14 you have a blank line after the class open {, so y
Chinmay 2015/07/09 21:44:19 ack
114
115 class RenderAutoLayout extends RenderBox
116 with ContainerRenderObjectMixin<RenderBox, AutoLayoutParentData>,
117 RenderBoxContainerDefaultsMixin<RenderBox, AutoLayoutParentData>,
118 _AutoLayoutParamMixin {
119
120 final al.Solver _solver = new al.Solver();
121 List<al.Constraint> _explicitConstraints = new List<al.Constraint>();
122
123 RenderAutoLayout({List<RenderBox> children}) {
Hixie 2015/07/09 00:53:14 put spaces inside { }s around parameter arguments.
Chinmay 2015/07/09 21:44:20 ack
124 _setupLayoutParameters(this);
125 _setupEditVariablesInSolver(_solver, al.Priority.required - 1);
126
Hixie 2015/07/09 00:53:14 remove this blank line; it doesn't help readabilit
Chinmay 2015/07/09 21:44:20 ack
127 addAll(children);
128 }
129
130 /// Adds all the given constraints to the solver. Either all constraints are
131 /// added or none
132 al.Result addConstraints(List<al.Constraint> constraints) {
133 al.Result result = _solver.addConstraints(constraints);
134
135 if (result == al.Result.success) {
136 markNeedsLayout();
137 _explicitConstraints.addAll(constraints);
138 }
139
Hixie 2015/07/09 00:53:14 probably don't need the blank lines here either.
Chinmay 2015/07/09 21:44:20 ack
140 return result;
141 }
142
143 /// Add the given constraint to the solver.
144 al.Result addConstraint(al.Constraint constraint) {
145 al.Result result = _solver.addConstraint(constraint);
146
147 if (result == al.Result.success) {
148 markNeedsLayout();
149 _explicitConstraints.add(constraint);
150 }
151
152 return result;
153 }
154
155 /// Removes all explicitly added constraints.
156 al.Result clearAllConstraints() {
157 al.Result result = _solver.removeConstraints(_explicitConstraints);
158
159 if (result == al.Result.success) {
160 markNeedsLayout();
161 _explicitConstraints = new List<al.Constraint>();
162 }
163
164 return result;
165 }
166
167 @override
168 void setupParentData(RenderObject child) {
169 if (child.parentData is! AutoLayoutParentData) {
170 child.parentData = new AutoLayoutParentData(child);
Hixie 2015/07/09 00:53:14 no { }s around blocks that are only 1 line long
Chinmay 2015/07/09 21:44:20 ack
171 }
172 }
173
174 @override
175 void performLayout() {
176 // Step 1: Update dimensions of self
177 size = constraints.biggest;
Hixie 2015/07/09 00:53:14 If the size isn't configurable, then you should se
Chinmay 2015/07/09 21:44:20 This is something I am not completely sure of TBH.
Hixie 2015/07/09 22:05:09 As far as I can tell, you don't let the size be se
178 _applyEditsAtSize(_solver, size);
179
180 // Step 2: Resolve solver updates and flush parameters
181
182 // We don't iterate over the children, instead, we ask the solver to tell
183 // us the updated parameters. Attached to the parameters (via the context)
184 // are the _AutoLayoutParamMixin instances.
185 for (_AutoLayoutParamMixin update in _solver.flushUpdates()) {
186 update._applyAutolayoutParameterUpdates();
187 }
188 }
189
190 @override
191 void _applyAutolayoutParameterUpdates() {
192 // Nothing to do since the size update has already been presented to the
193 // solver as an edit variable modification. The invokation of this method
194 // only indicates that the value has been flushed to the variable.
195 }
196
197 @override
198 void hitTestChildren(HitTestResult result, {Point position}) =>
Hixie 2015/07/09 00:53:14 Don't use fat arrow if the body isn't on the same
Chinmay 2015/07/09 21:44:20 I have been referring to the expression count (ins
Hixie 2015/07/09 22:05:09 our style guide says => is for single-line declara
199 defaultHitTestChildren(result, position: position);
200
201 @override
202 void paint(PaintingCanvas canvas, Offset offset) =>
203 defaultPaint(canvas, offset);
204
205 @override
206 void adoptChild(RenderObject child) {
207 // Make sure to call super first to setup the parent data
208 super.adoptChild(child);
209 child.parentData._setupImplicitConstraints(_solver);
210 }
211
212 @override
213 void dropChild(RenderObject child) {
214 child.parentData._collectImplicitConstraints(_solver);
215
216 // Call super last as this collects parent data
Hixie 2015/07/09 00:53:14 it doesn't matter, dropChild doesn't touch parentD
Chinmay 2015/07/09 21:44:20 ack
217 super.dropChild(child);
218 }
219
220 @override
221 List<al.Constraint> _constructImplicitConstraints() {
222 // Only edits are present on layout containers
Hixie 2015/07/09 00:53:14 What does this mean?
Chinmay 2015/07/09 21:44:20 ack. Elaborated
223 return null;
224 }
225 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698