| 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 'dart:math' as math; | 5 import 'dart:math' as math; |
| 6 import 'dart:sky' as sky; | 6 import 'dart:sky' as sky; |
| 7 | 7 |
| 8 import 'package:sky/rendering/box.dart'; | 8 import 'package:sky/rendering/box.dart'; |
| 9 import 'package:sky/rendering/object.dart'; | 9 import 'package:sky/rendering/object.dart'; |
| 10 import 'package:sky/rendering/sky_binding.dart'; | 10 import 'package:sky/rendering/sky_binding.dart'; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 31 final double maxDeltaTheta; | 31 final double maxDeltaTheta; |
| 32 | 32 |
| 33 double constrainDeltaRadius(double deltaRadius) { | 33 double constrainDeltaRadius(double deltaRadius) { |
| 34 return clamp(min: minDeltaRadius, max: maxDeltaRadius, value: deltaRadius); | 34 return clamp(min: minDeltaRadius, max: maxDeltaRadius, value: deltaRadius); |
| 35 } | 35 } |
| 36 | 36 |
| 37 double constrainDeltaTheta(double deltaTheta) { | 37 double constrainDeltaTheta(double deltaTheta) { |
| 38 return clamp(min: minDeltaTheta, max: maxDeltaTheta, value: deltaTheta); | 38 return clamp(min: minDeltaTheta, max: maxDeltaTheta, value: deltaTheta); |
| 39 } | 39 } |
| 40 | 40 |
| 41 @override |
| 41 bool get isTight => minDeltaTheta >= maxDeltaTheta && minDeltaTheta >= maxDelt
aTheta; | 42 bool get isTight => minDeltaTheta >= maxDeltaTheta && minDeltaTheta >= maxDelt
aTheta; |
| 42 } | 43 } |
| 43 | 44 |
| 44 class SectorDimensions { | 45 class SectorDimensions { |
| 45 const SectorDimensions({ this.deltaRadius: 0.0, this.deltaTheta: 0.0 }); | 46 const SectorDimensions({ this.deltaRadius: 0.0, this.deltaTheta: 0.0 }); |
| 46 | 47 |
| 47 factory SectorDimensions.withConstraints( | 48 factory SectorDimensions.withConstraints( |
| 48 SectorConstraints constraints, | 49 SectorConstraints constraints, |
| 49 { double deltaRadius: 0.0, double deltaTheta: 0.0 } | 50 { double deltaRadius: 0.0, double deltaTheta: 0.0 } |
| 50 ) { | 51 ) { |
| 51 return new SectorDimensions( | 52 return new SectorDimensions( |
| 52 deltaRadius: constraints.constrainDeltaRadius(deltaRadius), | 53 deltaRadius: constraints.constrainDeltaRadius(deltaRadius), |
| 53 deltaTheta: constraints.constrainDeltaTheta(deltaTheta) | 54 deltaTheta: constraints.constrainDeltaTheta(deltaTheta) |
| 54 ); | 55 ); |
| 55 } | 56 } |
| 56 | 57 |
| 57 final double deltaRadius; | 58 final double deltaRadius; |
| 58 final double deltaTheta; | 59 final double deltaTheta; |
| 59 } | 60 } |
| 60 | 61 |
| 61 class SectorParentData extends ParentData { | 62 class SectorParentData extends ParentData { |
| 62 double radius = 0.0; | 63 double radius = 0.0; |
| 63 double theta = 0.0; | 64 double theta = 0.0; |
| 64 } | 65 } |
| 65 | 66 |
| 66 abstract class RenderSector extends RenderObject { | 67 abstract class RenderSector extends RenderObject { |
| 67 | 68 |
| 69 @override |
| 68 void setupParentData(RenderObject child) { | 70 void setupParentData(RenderObject child) { |
| 69 if (child.parentData is! SectorParentData) | 71 if (child.parentData is! SectorParentData) |
| 70 child.parentData = new SectorParentData(); | 72 child.parentData = new SectorParentData(); |
| 71 } | 73 } |
| 72 | 74 |
| 73 SectorDimensions getIntrinsicDimensions(SectorConstraints constraints, double
radius) { | 75 SectorDimensions getIntrinsicDimensions(SectorConstraints constraints, double
radius) { |
| 74 return new SectorDimensions.withConstraints(constraints); | 76 return new SectorDimensions.withConstraints(constraints); |
| 75 } | 77 } |
| 76 | 78 |
| 79 @override |
| 77 SectorConstraints get constraints => super.constraints; | 80 SectorConstraints get constraints => super.constraints; |
| 81 |
| 82 @override |
| 78 bool debugDoesMeetConstraints() { | 83 bool debugDoesMeetConstraints() { |
| 79 assert(constraints != null); | 84 assert(constraints != null); |
| 80 assert(deltaRadius != null); | 85 assert(deltaRadius != null); |
| 81 assert(deltaRadius < double.INFINITY); | 86 assert(deltaRadius < double.INFINITY); |
| 82 assert(deltaTheta != null); | 87 assert(deltaTheta != null); |
| 83 assert(deltaTheta < double.INFINITY); | 88 assert(deltaTheta < double.INFINITY); |
| 84 return constraints.minDeltaRadius <= deltaRadius && | 89 return constraints.minDeltaRadius <= deltaRadius && |
| 85 deltaRadius <= math.max(constraints.minDeltaRadius, constraints.maxDe
ltaRadius) && | 90 deltaRadius <= math.max(constraints.minDeltaRadius, constraints.maxDe
ltaRadius) && |
| 86 constraints.minDeltaTheta <= deltaTheta && | 91 constraints.minDeltaTheta <= deltaTheta && |
| 87 deltaTheta <= math.max(constraints.minDeltaTheta, constraints.maxDelt
aTheta); | 92 deltaTheta <= math.max(constraints.minDeltaTheta, constraints.maxDelt
aTheta); |
| 88 } | 93 } |
| 94 |
| 95 @override |
| 89 void performResize() { | 96 void performResize() { |
| 90 // default behaviour for subclasses that have sizedByParent = true | 97 // default behaviour for subclasses that have sizedByParent = true |
| 91 deltaRadius = constraints.constrainDeltaRadius(0.0); | 98 deltaRadius = constraints.constrainDeltaRadius(0.0); |
| 92 deltaTheta = constraints.constrainDeltaTheta(0.0); | 99 deltaTheta = constraints.constrainDeltaTheta(0.0); |
| 93 } | 100 } |
| 101 |
| 102 @override |
| 94 void performLayout() { | 103 void performLayout() { |
| 95 // descendants have to either override performLayout() to set both | 104 // descendants have to either override performLayout() to set both |
| 96 // the dimensions and lay out children, or, set sizedByParent to | 105 // the dimensions and lay out children, or, set sizedByParent to |
| 97 // true so that performResize()'s logic above does its thing. | 106 // true so that performResize()'s logic above does its thing. |
| 98 assert(sizedByParent); | 107 assert(sizedByParent); |
| 99 } | 108 } |
| 100 | 109 |
| 101 bool hitTest(HitTestResult result, { double radius, double theta }) { | 110 bool hitTest(HitTestResult result, { double radius, double theta }) { |
| 102 assert(parentData is SectorParentData); | 111 assert(parentData is SectorParentData); |
| 103 if (radius < parentData.radius || radius >= parentData.radius + deltaRadius
|| | 112 if (radius < parentData.radius || radius >= parentData.radius + deltaRadius
|| |
| (...skipping 16 matching lines...) Expand all Loading... |
| 120 BoxDecoration _decoration; | 129 BoxDecoration _decoration; |
| 121 BoxDecoration get decoration => _decoration; | 130 BoxDecoration get decoration => _decoration; |
| 122 void set decoration (BoxDecoration value) { | 131 void set decoration (BoxDecoration value) { |
| 123 if (value == _decoration) | 132 if (value == _decoration) |
| 124 return; | 133 return; |
| 125 _decoration = value; | 134 _decoration = value; |
| 126 markNeedsPaint(); | 135 markNeedsPaint(); |
| 127 } | 136 } |
| 128 | 137 |
| 129 // offset must point to the center of the circle | 138 // offset must point to the center of the circle |
| 139 @override |
| 130 void paint(PaintingCanvas canvas, Offset offset) { | 140 void paint(PaintingCanvas canvas, Offset offset) { |
| 131 assert(deltaRadius != null); | 141 assert(deltaRadius != null); |
| 132 assert(deltaTheta != null); | 142 assert(deltaTheta != null); |
| 133 assert(parentData is SectorParentData); | 143 assert(parentData is SectorParentData); |
| 134 | 144 |
| 135 if (_decoration == null) | 145 if (_decoration == null) |
| 136 return; | 146 return; |
| 137 | 147 |
| 138 if (_decoration.backgroundColor != null) { | 148 if (_decoration.backgroundColor != null) { |
| 139 Paint paint = new Paint()..color = _decoration.backgroundColor; | 149 Paint paint = new Paint()..color = _decoration.backgroundColor; |
| 140 Path path = new Path(); | 150 Path path = new Path(); |
| 141 double outerRadius = (parentData.radius + deltaRadius); | 151 double outerRadius = (parentData.radius + deltaRadius); |
| 142 Rect outerBounds = new Rect.fromLTRB(offset.dx-outerRadius, offset.dy-oute
rRadius, offset.dx+outerRadius, offset.dy+outerRadius); | 152 Rect outerBounds = new Rect.fromLTRB(offset.dx-outerRadius, offset.dy-oute
rRadius, offset.dx+outerRadius, offset.dy+outerRadius); |
| 143 path.arcTo(outerBounds, parentData.theta, deltaTheta, true); | 153 path.arcTo(outerBounds, parentData.theta, deltaTheta, true); |
| 144 double innerRadius = parentData.radius; | 154 double innerRadius = parentData.radius; |
| 145 Rect innerBounds = new Rect.fromLTRB(offset.dx-innerRadius, offset.dy-inne
rRadius, offset.dx+innerRadius, offset.dy+innerRadius); | 155 Rect innerBounds = new Rect.fromLTRB(offset.dx-innerRadius, offset.dy-inne
rRadius, offset.dx+innerRadius, offset.dy+innerRadius); |
| 146 path.arcTo(innerBounds, parentData.theta + deltaTheta, -deltaTheta, false)
; | 156 path.arcTo(innerBounds, parentData.theta + deltaTheta, -deltaTheta, false)
; |
| 147 path.close(); | 157 path.close(); |
| 148 canvas.drawPath(path, paint); | 158 canvas.drawPath(path, paint); |
| 149 } | 159 } |
| 150 } | 160 } |
| 151 | 161 |
| 152 } | 162 } |
| 153 | 163 |
| 154 class SectorChildListParentData extends SectorParentData with ContainerParentDat
aMixin<RenderSector> { } | 164 class SectorChildListParentData extends SectorParentData with ContainerParentDat
aMixin<RenderSector> { } |
| 155 | 165 |
| 156 class RenderSectorWithChildren extends RenderDecoratedSector with ContainerRende
rObjectMixin<RenderSector, SectorChildListParentData> { | 166 class RenderSectorWithChildren extends RenderDecoratedSector with ContainerRende
rObjectMixin<RenderSector, SectorChildListParentData> { |
| 157 RenderSectorWithChildren(BoxDecoration decoration) : super(decoration); | 167 RenderSectorWithChildren(BoxDecoration decoration) : super(decoration); |
| 158 | 168 |
| 169 @override |
| 159 void hitTestChildren(HitTestResult result, { double radius, double theta }) { | 170 void hitTestChildren(HitTestResult result, { double radius, double theta }) { |
| 160 RenderSector child = lastChild; | 171 RenderSector child = lastChild; |
| 161 while (child != null) { | 172 while (child != null) { |
| 162 assert(child.parentData is SectorChildListParentData); | 173 assert(child.parentData is SectorChildListParentData); |
| 163 if (child.hitTest(result, radius: radius, theta: theta)) | 174 if (child.hitTest(result, radius: radius, theta: theta)) |
| 164 return; | 175 return; |
| 165 child = child.parentData.previousSibling; | 176 child = child.parentData.previousSibling; |
| 166 } | 177 } |
| 167 } | 178 } |
| 168 } | 179 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 190 double get padding => _padding; | 201 double get padding => _padding; |
| 191 void set padding(double value) { | 202 void set padding(double value) { |
| 192 // TODO(ianh): avoid code duplication | 203 // TODO(ianh): avoid code duplication |
| 193 assert(value != null); | 204 assert(value != null); |
| 194 if (_padding != value) { | 205 if (_padding != value) { |
| 195 _padding = value; | 206 _padding = value; |
| 196 markNeedsLayout(); | 207 markNeedsLayout(); |
| 197 } | 208 } |
| 198 } | 209 } |
| 199 | 210 |
| 211 @override |
| 200 void setupParentData(RenderObject child) { | 212 void setupParentData(RenderObject child) { |
| 201 // TODO(ianh): avoid code duplication | 213 // TODO(ianh): avoid code duplication |
| 202 if (child.parentData is! SectorChildListParentData) | 214 if (child.parentData is! SectorChildListParentData) |
| 203 child.parentData = new SectorChildListParentData(); | 215 child.parentData = new SectorChildListParentData(); |
| 204 } | 216 } |
| 205 | 217 |
| 218 @override |
| 206 SectorDimensions getIntrinsicDimensions(SectorConstraints constraints, double
radius) { | 219 SectorDimensions getIntrinsicDimensions(SectorConstraints constraints, double
radius) { |
| 207 double outerDeltaRadius = constraints.constrainDeltaRadius(desiredDeltaRadiu
s); | 220 double outerDeltaRadius = constraints.constrainDeltaRadius(desiredDeltaRadiu
s); |
| 208 double innerDeltaRadius = outerDeltaRadius - padding * 2.0; | 221 double innerDeltaRadius = outerDeltaRadius - padding * 2.0; |
| 209 double childRadius = radius + padding; | 222 double childRadius = radius + padding; |
| 210 double paddingTheta = math.atan(padding / (radius + outerDeltaRadius)); | 223 double paddingTheta = math.atan(padding / (radius + outerDeltaRadius)); |
| 211 double innerTheta = paddingTheta; // increments with each child | 224 double innerTheta = paddingTheta; // increments with each child |
| 212 double remainingDeltaTheta = constraints.maxDeltaTheta - (innerTheta + paddi
ngTheta); | 225 double remainingDeltaTheta = constraints.maxDeltaTheta - (innerTheta + paddi
ngTheta); |
| 213 RenderSector child = firstChild; | 226 RenderSector child = firstChild; |
| 214 while (child != null) { | 227 while (child != null) { |
| 215 SectorConstraints innerConstraints = new SectorConstraints( | 228 SectorConstraints innerConstraints = new SectorConstraints( |
| 216 maxDeltaRadius: innerDeltaRadius, | 229 maxDeltaRadius: innerDeltaRadius, |
| 217 maxDeltaTheta: remainingDeltaTheta | 230 maxDeltaTheta: remainingDeltaTheta |
| 218 ); | 231 ); |
| 219 SectorDimensions childDimensions = child.getIntrinsicDimensions(innerConst
raints, childRadius); | 232 SectorDimensions childDimensions = child.getIntrinsicDimensions(innerConst
raints, childRadius); |
| 220 innerTheta += childDimensions.deltaTheta; | 233 innerTheta += childDimensions.deltaTheta; |
| 221 remainingDeltaTheta -= childDimensions.deltaTheta; | 234 remainingDeltaTheta -= childDimensions.deltaTheta; |
| 222 assert(child.parentData is SectorChildListParentData); | 235 assert(child.parentData is SectorChildListParentData); |
| 223 child = child.parentData.nextSibling; | 236 child = child.parentData.nextSibling; |
| 224 if (child != null) { | 237 if (child != null) { |
| 225 innerTheta += paddingTheta; | 238 innerTheta += paddingTheta; |
| 226 remainingDeltaTheta -= paddingTheta; | 239 remainingDeltaTheta -= paddingTheta; |
| 227 } | 240 } |
| 228 } | 241 } |
| 229 return new SectorDimensions.withConstraints(constraints, | 242 return new SectorDimensions.withConstraints(constraints, |
| 230 deltaRadius: outerDeltaRadius, | 243 deltaRadius: outerDeltaRadius, |
| 231 deltaTheta: innerTheta); | 244 deltaTheta: innerTheta); |
| 232 } | 245 } |
| 233 | 246 |
| 247 @override |
| 234 void performLayout() { | 248 void performLayout() { |
| 235 assert(this.parentData is SectorParentData); | 249 assert(this.parentData is SectorParentData); |
| 236 deltaRadius = constraints.constrainDeltaRadius(desiredDeltaRadius); | 250 deltaRadius = constraints.constrainDeltaRadius(desiredDeltaRadius); |
| 237 assert(deltaRadius < double.INFINITY); | 251 assert(deltaRadius < double.INFINITY); |
| 238 double innerDeltaRadius = deltaRadius - padding * 2.0; | 252 double innerDeltaRadius = deltaRadius - padding * 2.0; |
| 239 double childRadius = this.parentData.radius + padding; | 253 double childRadius = this.parentData.radius + padding; |
| 240 double paddingTheta = math.atan(padding / (this.parentData.radius + deltaRad
ius)); | 254 double paddingTheta = math.atan(padding / (this.parentData.radius + deltaRad
ius)); |
| 241 double innerTheta = paddingTheta; // increments with each child | 255 double innerTheta = paddingTheta; // increments with each child |
| 242 double remainingDeltaTheta = constraints.maxDeltaTheta - (innerTheta + paddi
ngTheta); | 256 double remainingDeltaTheta = constraints.maxDeltaTheta - (innerTheta + paddi
ngTheta); |
| 243 RenderSector child = firstChild; | 257 RenderSector child = firstChild; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 257 if (child != null) { | 271 if (child != null) { |
| 258 innerTheta += paddingTheta; | 272 innerTheta += paddingTheta; |
| 259 remainingDeltaTheta -= paddingTheta; | 273 remainingDeltaTheta -= paddingTheta; |
| 260 } | 274 } |
| 261 } | 275 } |
| 262 deltaTheta = innerTheta; | 276 deltaTheta = innerTheta; |
| 263 } | 277 } |
| 264 | 278 |
| 265 // offset must point to the center of our circle | 279 // offset must point to the center of our circle |
| 266 // each sector then knows how to paint itself at its location | 280 // each sector then knows how to paint itself at its location |
| 281 @override |
| 267 void paint(PaintingCanvas canvas, Offset offset) { | 282 void paint(PaintingCanvas canvas, Offset offset) { |
| 268 // TODO(ianh): avoid code duplication | 283 // TODO(ianh): avoid code duplication |
| 269 super.paint(canvas, offset); | 284 super.paint(canvas, offset); |
| 270 RenderSector child = firstChild; | 285 RenderSector child = firstChild; |
| 271 while (child != null) { | 286 while (child != null) { |
| 272 assert(child.parentData is SectorChildListParentData); | 287 assert(child.parentData is SectorChildListParentData); |
| 273 canvas.paintChild(child, offset.toPoint()); | 288 canvas.paintChild(child, offset.toPoint()); |
| 274 child = child.parentData.nextSibling; | 289 child = child.parentData.nextSibling; |
| 275 } | 290 } |
| 276 } | 291 } |
| (...skipping 23 matching lines...) Expand all Loading... |
| 300 double get padding => _padding; | 315 double get padding => _padding; |
| 301 void set padding(double value) { | 316 void set padding(double value) { |
| 302 // TODO(ianh): avoid code duplication | 317 // TODO(ianh): avoid code duplication |
| 303 assert(value != null); | 318 assert(value != null); |
| 304 if (_padding != value) { | 319 if (_padding != value) { |
| 305 _padding = value; | 320 _padding = value; |
| 306 markNeedsLayout(); | 321 markNeedsLayout(); |
| 307 } | 322 } |
| 308 } | 323 } |
| 309 | 324 |
| 325 @override |
| 310 void setupParentData(RenderObject child) { | 326 void setupParentData(RenderObject child) { |
| 311 // TODO(ianh): avoid code duplication | 327 // TODO(ianh): avoid code duplication |
| 312 if (child.parentData is! SectorChildListParentData) | 328 if (child.parentData is! SectorChildListParentData) |
| 313 child.parentData = new SectorChildListParentData(); | 329 child.parentData = new SectorChildListParentData(); |
| 314 } | 330 } |
| 315 | 331 |
| 332 @override |
| 316 SectorDimensions getIntrinsicDimensions(SectorConstraints constraints, double
radius) { | 333 SectorDimensions getIntrinsicDimensions(SectorConstraints constraints, double
radius) { |
| 317 assert(this.parentData is SectorParentData); | 334 assert(this.parentData is SectorParentData); |
| 318 double paddingTheta = math.atan(padding / this.parentData.radius); | 335 double paddingTheta = math.atan(padding / this.parentData.radius); |
| 319 double outerDeltaTheta = constraints.constrainDeltaTheta(desiredDeltaTheta); | 336 double outerDeltaTheta = constraints.constrainDeltaTheta(desiredDeltaTheta); |
| 320 double innerDeltaTheta = outerDeltaTheta - paddingTheta * 2.0; | 337 double innerDeltaTheta = outerDeltaTheta - paddingTheta * 2.0; |
| 321 double childRadius = this.parentData.radius + padding; | 338 double childRadius = this.parentData.radius + padding; |
| 322 double remainingDeltaRadius = constraints.maxDeltaRadius - (padding * 2.0); | 339 double remainingDeltaRadius = constraints.maxDeltaRadius - (padding * 2.0); |
| 323 RenderSector child = firstChild; | 340 RenderSector child = firstChild; |
| 324 while (child != null) { | 341 while (child != null) { |
| 325 SectorConstraints innerConstraints = new SectorConstraints( | 342 SectorConstraints innerConstraints = new SectorConstraints( |
| 326 maxDeltaRadius: remainingDeltaRadius, | 343 maxDeltaRadius: remainingDeltaRadius, |
| 327 maxDeltaTheta: innerDeltaTheta | 344 maxDeltaTheta: innerDeltaTheta |
| 328 ); | 345 ); |
| 329 SectorDimensions childDimensions = child.getIntrinsicDimensions(innerConst
raints, childRadius); | 346 SectorDimensions childDimensions = child.getIntrinsicDimensions(innerConst
raints, childRadius); |
| 330 childRadius += childDimensions.deltaRadius; | 347 childRadius += childDimensions.deltaRadius; |
| 331 remainingDeltaRadius -= childDimensions.deltaRadius; | 348 remainingDeltaRadius -= childDimensions.deltaRadius; |
| 332 assert(child.parentData is SectorChildListParentData); | 349 assert(child.parentData is SectorChildListParentData); |
| 333 child = child.parentData.nextSibling; | 350 child = child.parentData.nextSibling; |
| 334 childRadius += padding; | 351 childRadius += padding; |
| 335 remainingDeltaRadius -= padding; | 352 remainingDeltaRadius -= padding; |
| 336 } | 353 } |
| 337 return new SectorDimensions.withConstraints(constraints, | 354 return new SectorDimensions.withConstraints(constraints, |
| 338 deltaRadius: childRadius - this.
parentData.radius, | 355 deltaRadius: childRadius - this.
parentData.radius, |
| 339 deltaTheta: outerDeltaTheta); | 356 deltaTheta: outerDeltaTheta); |
| 340 } | 357 } |
| 341 | 358 |
| 359 @override |
| 342 void performLayout() { | 360 void performLayout() { |
| 343 assert(this.parentData is SectorParentData); | 361 assert(this.parentData is SectorParentData); |
| 344 deltaTheta = constraints.constrainDeltaTheta(desiredDeltaTheta); | 362 deltaTheta = constraints.constrainDeltaTheta(desiredDeltaTheta); |
| 345 assert(deltaTheta <= kTwoPi); | 363 assert(deltaTheta <= kTwoPi); |
| 346 double paddingTheta = math.atan(padding / this.parentData.radius); | 364 double paddingTheta = math.atan(padding / this.parentData.radius); |
| 347 double innerTheta = this.parentData.theta + paddingTheta; | 365 double innerTheta = this.parentData.theta + paddingTheta; |
| 348 double innerDeltaTheta = deltaTheta - paddingTheta * 2.0; | 366 double innerDeltaTheta = deltaTheta - paddingTheta * 2.0; |
| 349 double childRadius = this.parentData.radius + padding; | 367 double childRadius = this.parentData.radius + padding; |
| 350 double remainingDeltaRadius = constraints.maxDeltaRadius - (padding * 2.0); | 368 double remainingDeltaRadius = constraints.maxDeltaRadius - (padding * 2.0); |
| 351 RenderSector child = firstChild; | 369 RenderSector child = firstChild; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 362 assert(child.parentData is SectorChildListParentData); | 380 assert(child.parentData is SectorChildListParentData); |
| 363 child = child.parentData.nextSibling; | 381 child = child.parentData.nextSibling; |
| 364 childRadius += padding; | 382 childRadius += padding; |
| 365 remainingDeltaRadius -= padding; | 383 remainingDeltaRadius -= padding; |
| 366 } | 384 } |
| 367 deltaRadius = childRadius - this.parentData.radius; | 385 deltaRadius = childRadius - this.parentData.radius; |
| 368 } | 386 } |
| 369 | 387 |
| 370 // offset must point to the center of our circle | 388 // offset must point to the center of our circle |
| 371 // each sector then knows how to paint itself at its location | 389 // each sector then knows how to paint itself at its location |
| 390 @override |
| 372 void paint(PaintingCanvas canvas, Offset offset) { | 391 void paint(PaintingCanvas canvas, Offset offset) { |
| 373 // TODO(ianh): avoid code duplication | 392 // TODO(ianh): avoid code duplication |
| 374 super.paint(canvas, offset); | 393 super.paint(canvas, offset); |
| 375 RenderSector child = firstChild; | 394 RenderSector child = firstChild; |
| 376 while (child != null) { | 395 while (child != null) { |
| 377 assert(child.parentData is SectorChildListParentData); | 396 assert(child.parentData is SectorChildListParentData); |
| 378 canvas.paintChild(child, offset.toPoint()); | 397 canvas.paintChild(child, offset.toPoint()); |
| 379 child = child.parentData.nextSibling; | 398 child = child.parentData.nextSibling; |
| 380 } | 399 } |
| 381 } | 400 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 400 RenderSector _child; | 419 RenderSector _child; |
| 401 RenderSector get child => _child; | 420 RenderSector get child => _child; |
| 402 void set child(RenderSector value) { | 421 void set child(RenderSector value) { |
| 403 if (_child != null) | 422 if (_child != null) |
| 404 dropChild(_child); | 423 dropChild(_child); |
| 405 _child = value; | 424 _child = value; |
| 406 adoptChild(_child); | 425 adoptChild(_child); |
| 407 markNeedsLayout(); | 426 markNeedsLayout(); |
| 408 } | 427 } |
| 409 | 428 |
| 429 @override |
| 410 void setupParentData(RenderObject child) { | 430 void setupParentData(RenderObject child) { |
| 411 if (child.parentData is! SectorParentData) | 431 if (child.parentData is! SectorParentData) |
| 412 child.parentData = new SectorParentData(); | 432 child.parentData = new SectorParentData(); |
| 413 } | 433 } |
| 414 | 434 |
| 435 @override |
| 415 double getMinIntrinsicWidth(BoxConstraints constraints) { | 436 double getMinIntrinsicWidth(BoxConstraints constraints) { |
| 416 if (child == null) | 437 if (child == null) |
| 417 return super.getMinIntrinsicWidth(constraints); | 438 return super.getMinIntrinsicWidth(constraints); |
| 418 return getIntrinsicDimensions(constraints).width; | 439 return getIntrinsicDimensions(constraints).width; |
| 419 } | 440 } |
| 420 | 441 |
| 442 @override |
| 421 double getMaxIntrinsicWidth(BoxConstraints constraints) { | 443 double getMaxIntrinsicWidth(BoxConstraints constraints) { |
| 422 if (child == null) | 444 if (child == null) |
| 423 return super.getMaxIntrinsicWidth(constraints); | 445 return super.getMaxIntrinsicWidth(constraints); |
| 424 return getIntrinsicDimensions(constraints).width; | 446 return getIntrinsicDimensions(constraints).width; |
| 425 } | 447 } |
| 426 | 448 |
| 449 @override |
| 427 double getMinIntrinsicHeight(BoxConstraints constraints) { | 450 double getMinIntrinsicHeight(BoxConstraints constraints) { |
| 428 if (child == null) | 451 if (child == null) |
| 429 return super.getMinIntrinsicHeight(constraints); | 452 return super.getMinIntrinsicHeight(constraints); |
| 430 return getIntrinsicDimensions(constraints).height; | 453 return getIntrinsicDimensions(constraints).height; |
| 431 } | 454 } |
| 432 | 455 |
| 456 @override |
| 433 double getMaxIntrinsicHeight(BoxConstraints constraints) { | 457 double getMaxIntrinsicHeight(BoxConstraints constraints) { |
| 434 if (child == null) | 458 if (child == null) |
| 435 return super.getMaxIntrinsicHeight(constraints); | 459 return super.getMaxIntrinsicHeight(constraints); |
| 436 return getIntrinsicDimensions(constraints).height; | 460 return getIntrinsicDimensions(constraints).height; |
| 437 } | 461 } |
| 438 | 462 |
| 439 Size getIntrinsicDimensions(BoxConstraints constraints) { | 463 Size getIntrinsicDimensions(BoxConstraints constraints) { |
| 440 assert(child is RenderSector); | 464 assert(child is RenderSector); |
| 441 assert(child.parentData is SectorParentData); | 465 assert(child.parentData is SectorParentData); |
| 442 assert(!constraints.isInfinite); | 466 assert(!constraints.isInfinite); |
| 443 double maxChildDeltaRadius = math.min(constraints.maxWidth, constraints.maxH
eight) / 2.0 - innerRadius; | 467 double maxChildDeltaRadius = math.min(constraints.maxWidth, constraints.maxH
eight) / 2.0 - innerRadius; |
| 444 SectorDimensions childDimensions = child.getIntrinsicDimensions(new SectorCo
nstraints(maxDeltaRadius: maxChildDeltaRadius), innerRadius); | 468 SectorDimensions childDimensions = child.getIntrinsicDimensions(new SectorCo
nstraints(maxDeltaRadius: maxChildDeltaRadius), innerRadius); |
| 445 double dimension = (innerRadius + childDimensions.deltaRadius) * 2.0; | 469 double dimension = (innerRadius + childDimensions.deltaRadius) * 2.0; |
| 446 return constraints.constrain(new Size(dimension, dimension)); | 470 return constraints.constrain(new Size(dimension, dimension)); |
| 447 } | 471 } |
| 448 | 472 |
| 473 @override |
| 449 void performLayout() { | 474 void performLayout() { |
| 450 if (child == null) { | 475 if (child == null) { |
| 451 size = constraints.constrain(Size.zero); | 476 size = constraints.constrain(Size.zero); |
| 452 } else { | 477 } else { |
| 453 assert(child is RenderSector); | 478 assert(child is RenderSector); |
| 454 assert(!constraints.isInfinite); | 479 assert(!constraints.isInfinite); |
| 455 double maxChildDeltaRadius = math.min(constraints.maxWidth, constraints.ma
xHeight) / 2.0 - innerRadius; | 480 double maxChildDeltaRadius = math.min(constraints.maxWidth, constraints.ma
xHeight) / 2.0 - innerRadius; |
| 456 assert(child.parentData is SectorParentData); | 481 assert(child.parentData is SectorParentData); |
| 457 child.parentData.radius = innerRadius; | 482 child.parentData.radius = innerRadius; |
| 458 child.parentData.theta = 0.0; | 483 child.parentData.theta = 0.0; |
| 459 child.layout(new SectorConstraints(maxDeltaRadius: maxChildDeltaRadius), p
arentUsesSize: true); | 484 child.layout(new SectorConstraints(maxDeltaRadius: maxChildDeltaRadius), p
arentUsesSize: true); |
| 460 double dimension = (innerRadius + child.deltaRadius) * 2.0; | 485 double dimension = (innerRadius + child.deltaRadius) * 2.0; |
| 461 size = constraints.constrain(new Size(dimension, dimension)); | 486 size = constraints.constrain(new Size(dimension, dimension)); |
| 462 } | 487 } |
| 463 } | 488 } |
| 464 | 489 |
| 490 @override |
| 465 void paint(PaintingCanvas canvas, Offset offset) { | 491 void paint(PaintingCanvas canvas, Offset offset) { |
| 466 super.paint(canvas, offset); | 492 super.paint(canvas, offset); |
| 467 if (child != null) { | 493 if (child != null) { |
| 468 Rect bounds = offset & size; | 494 Rect bounds = offset & size; |
| 469 // we move the offset to the center of the circle for the RenderSectors | 495 // we move the offset to the center of the circle for the RenderSectors |
| 470 canvas.paintChild(child, bounds.center); | 496 canvas.paintChild(child, bounds.center); |
| 471 } | 497 } |
| 472 } | 498 } |
| 473 | 499 |
| 500 @override |
| 474 bool hitTest(HitTestResult result, { Point position }) { | 501 bool hitTest(HitTestResult result, { Point position }) { |
| 475 double x = position.x; | 502 double x = position.x; |
| 476 double y = position.y; | 503 double y = position.y; |
| 477 if (child == null) | 504 if (child == null) |
| 478 return false; | 505 return false; |
| 479 // translate to our origin | 506 // translate to our origin |
| 480 x -= size.width/2.0; | 507 x -= size.width/2.0; |
| 481 y -= size.height/2.0; | 508 y -= size.height/2.0; |
| 482 // convert to radius/theta | 509 // convert to radius/theta |
| 483 double radius = math.sqrt(x*x+y*y); | 510 double radius = math.sqrt(x*x+y*y); |
| 484 double theta = (math.atan2(x, -y) - math.PI/2.0) % kTwoPi; | 511 double theta = (math.atan2(x, -y) - math.PI/2.0) % kTwoPi; |
| 485 if (radius < innerRadius) | 512 if (radius < innerRadius) |
| 486 return false; | 513 return false; |
| 487 if (radius >= innerRadius + child.deltaRadius) | 514 if (radius >= innerRadius + child.deltaRadius) |
| 488 return false; | 515 return false; |
| 489 if (theta > child.deltaTheta) | 516 if (theta > child.deltaTheta) |
| 490 return false; | 517 return false; |
| 491 child.hitTest(result, radius: radius, theta: theta); | 518 child.hitTest(result, radius: radius, theta: theta); |
| 492 result.add(new BoxHitTestEntry(this, position)); | 519 result.add(new BoxHitTestEntry(this, position)); |
| 493 return true; | 520 return true; |
| 494 } | 521 } |
| 495 | 522 |
| 496 } | 523 } |
| 497 | 524 |
| 498 class RenderSolidColor extends RenderDecoratedSector { | 525 class RenderSolidColor extends RenderDecoratedSector { |
| 499 RenderSolidColor(Color backgroundColor, { | 526 RenderSolidColor(Color backgroundColor, { |
| 500 this.desiredDeltaRadius: double.INFINITY, | 527 this.desiredDeltaRadius: double.INFINITY, |
| 501 this.desiredDeltaTheta: kTwoPi | 528 this.desiredDeltaTheta: kTwoPi |
| 502 }) : this.backgroundColor = backgroundColor, | 529 }) : this.backgroundColor = backgroundColor, |
| 503 super(new BoxDecoration(backgroundColor: backgroundColor)); | 530 super(new BoxDecoration(backgroundColor: backgroundColor)); |
| 504 | 531 |
| 505 double desiredDeltaRadius; | 532 double desiredDeltaRadius; |
| 506 double desiredDeltaTheta; | 533 double desiredDeltaTheta; |
| 507 final Color backgroundColor; | 534 final Color backgroundColor; |
| 508 | 535 |
| 536 @override |
| 509 SectorDimensions getIntrinsicDimensions(SectorConstraints constraints, double
radius) { | 537 SectorDimensions getIntrinsicDimensions(SectorConstraints constraints, double
radius) { |
| 510 return new SectorDimensions.withConstraints(constraints, deltaTheta: desired
DeltaTheta); | 538 return new SectorDimensions.withConstraints(constraints, deltaTheta: desired
DeltaTheta); |
| 511 } | 539 } |
| 512 | 540 |
| 541 @override |
| 513 void performLayout() { | 542 void performLayout() { |
| 514 deltaRadius = constraints.constrainDeltaRadius(desiredDeltaRadius); | 543 deltaRadius = constraints.constrainDeltaRadius(desiredDeltaRadius); |
| 515 deltaTheta = constraints.constrainDeltaTheta(desiredDeltaTheta); | 544 deltaTheta = constraints.constrainDeltaTheta(desiredDeltaTheta); |
| 516 } | 545 } |
| 517 | 546 |
| 547 @override |
| 518 void handleEvent(sky.Event event, HitTestEntry entry) { | 548 void handleEvent(sky.Event event, HitTestEntry entry) { |
| 519 if (event.type == 'pointerdown') | 549 if (event.type == 'pointerdown') |
| 520 decoration = new BoxDecoration(backgroundColor: const Color(0xFFFF0000)); | 550 decoration = new BoxDecoration(backgroundColor: const Color(0xFFFF0000)); |
| 521 else if (event.type == 'pointerup') | 551 else if (event.type == 'pointerup') |
| 522 decoration = new BoxDecoration(backgroundColor: backgroundColor); | 552 decoration = new BoxDecoration(backgroundColor: backgroundColor); |
| 523 } | 553 } |
| 524 } | 554 } |
| 525 | 555 |
| 526 RenderBox buildSectorExample() { | 556 RenderBox buildSectorExample() { |
| 527 RenderSectorRing rootCircle = new RenderSectorRing(padding: 20.0); | 557 RenderSectorRing rootCircle = new RenderSectorRing(padding: 20.0); |
| 528 rootCircle.add(new RenderSolidColor(const Color(0xFF00FFFF), desiredDeltaTheta
: kTwoPi * 0.15)); | 558 rootCircle.add(new RenderSolidColor(const Color(0xFF00FFFF), desiredDeltaTheta
: kTwoPi * 0.15)); |
| 529 rootCircle.add(new RenderSolidColor(const Color(0xFF0000FF), desiredDeltaTheta
: kTwoPi * 0.4)); | 559 rootCircle.add(new RenderSolidColor(const Color(0xFF0000FF), desiredDeltaTheta
: kTwoPi * 0.4)); |
| 530 RenderSectorSlice stack = new RenderSectorSlice(padding: 2.0); | 560 RenderSectorSlice stack = new RenderSectorSlice(padding: 2.0); |
| 531 stack.add(new RenderSolidColor(const Color(0xFFFFFF00), desiredDeltaRadius: 20
.0)); | 561 stack.add(new RenderSolidColor(const Color(0xFFFFFF00), desiredDeltaRadius: 20
.0)); |
| 532 stack.add(new RenderSolidColor(const Color(0xFFFF9000), desiredDeltaRadius: 20
.0)); | 562 stack.add(new RenderSolidColor(const Color(0xFFFF9000), desiredDeltaRadius: 20
.0)); |
| 533 stack.add(new RenderSolidColor(const Color(0xFF00FF00))); | 563 stack.add(new RenderSolidColor(const Color(0xFF00FF00))); |
| 534 rootCircle.add(stack); | 564 rootCircle.add(stack); |
| 535 return new RenderBoxToRenderSectorAdapter(innerRadius: 50.0, child: rootCircle
); | 565 return new RenderBoxToRenderSectorAdapter(innerRadius: 50.0, child: rootCircle
); |
| 536 } | 566 } |
| 537 | 567 |
| 538 void main() { | 568 void main() { |
| 539 new SkyBinding(root: buildSectorExample()); | 569 new SkyBinding(root: buildSectorExample()); |
| 540 } | 570 } |
| OLD | NEW |