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 import 'package:sky/framework/app.dart'; |
7 import 'package:sky/framework/layout2.dart'; | 8 import 'package:sky/framework/layout2.dart'; |
8 | 9 |
9 const double kTwoPi = 2 * math.PI; | 10 const double kTwoPi = 2 * math.PI; |
10 | 11 |
11 double deg(double radians) => radians * 180.0 / math.PI; | 12 double deg(double radians) => radians * 180.0 / math.PI; |
12 | 13 |
13 class SectorConstraints { | 14 class SectorConstraints { |
14 const SectorConstraints({ | 15 const SectorConstraints({ |
15 this.minDeltaRadius: 0.0, | 16 this.minDeltaRadius: 0.0, |
16 this.maxDeltaRadius: double.INFINITY, | 17 this.maxDeltaRadius: double.INFINITY, |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 SectorDimensions getIntrinsicDimensions(SectorConstraints constraints, double
radius) { | 71 SectorDimensions getIntrinsicDimensions(SectorConstraints constraints, double
radius) { |
71 return new SectorDimensions.withConstraints(constraints); | 72 return new SectorDimensions.withConstraints(constraints); |
72 } | 73 } |
73 | 74 |
74 void layout(SectorConstraints constraints, { RenderNode relayoutSubtreeRoot })
{ | 75 void layout(SectorConstraints constraints, { RenderNode relayoutSubtreeRoot })
{ |
75 deltaRadius = constraints.constrainDeltaRadius(0.0); | 76 deltaRadius = constraints.constrainDeltaRadius(0.0); |
76 deltaTheta = constraints.constrainDeltaTheta(0.0); | 77 deltaTheta = constraints.constrainDeltaTheta(0.0); |
77 layoutDone(); | 78 layoutDone(); |
78 } | 79 } |
79 | 80 |
| 81 bool hitTest(HitTestResult result, { double radius, double theta }) { |
| 82 assert(parentData is SectorParentData); |
| 83 if (radius < parentData.radius || radius >= parentData.radius + deltaRadius
|| |
| 84 theta < parentData.theta || theta >= parentData.theta + deltaTheta) |
| 85 return false; |
| 86 hitTestChildren(result, radius: radius, theta: theta); |
| 87 result.add(this); |
| 88 return true; |
| 89 } |
| 90 void hitTestChildren(HitTestResult result, { double radius, double theta }) {
} |
| 91 |
80 double deltaRadius; | 92 double deltaRadius; |
81 double deltaTheta; | 93 double deltaTheta; |
82 } | 94 } |
83 | 95 |
84 class RenderDecoratedSector extends RenderSector { | 96 class RenderDecoratedSector extends RenderSector { |
85 BoxDecoration _decoration; | 97 BoxDecoration _decoration; |
86 | 98 |
87 RenderDecoratedSector(BoxDecoration decoration) : _decoration = decoration; | 99 RenderDecoratedSector(BoxDecoration decoration) : _decoration = decoration; |
88 | 100 |
89 void setBoxDecoration(BoxDecoration decoration) { | 101 void setBoxDecoration(BoxDecoration decoration) { |
(...skipping 22 matching lines...) Expand all Loading... |
112 sky.Rect innerBounds = new sky.Rect()..setLTRB(-innerRadius, -innerRadius,
innerRadius, innerRadius); | 124 sky.Rect innerBounds = new sky.Rect()..setLTRB(-innerRadius, -innerRadius,
innerRadius, innerRadius); |
113 path.arcTo(innerBounds, deg(parentData.theta + deltaTheta), deg(-deltaThet
a), false); | 125 path.arcTo(innerBounds, deg(parentData.theta + deltaTheta), deg(-deltaThet
a), false); |
114 path.close(); | 126 path.close(); |
115 canvas.drawPath(path, paint); | 127 canvas.drawPath(path, paint); |
116 } | 128 } |
117 } | 129 } |
118 } | 130 } |
119 | 131 |
120 class SectorChildListParentData extends SectorParentData with ContainerParentDat
aMixin<RenderSector> { } | 132 class SectorChildListParentData extends SectorParentData with ContainerParentDat
aMixin<RenderSector> { } |
121 | 133 |
122 class RenderSectorRing extends RenderDecoratedSector with ContainerRenderNodeMix
in<RenderSector, SectorChildListParentData> { | 134 class RenderSectorWithChildren extends RenderDecoratedSector with ContainerRende
rNodeMixin<RenderSector, SectorChildListParentData> { |
| 135 RenderSectorWithChildren(BoxDecoration decoration) : super(decoration); |
| 136 |
| 137 void hitTestChildren(HitTestResult result, { double radius, double theta }) { |
| 138 RenderSector child = lastChild; |
| 139 while (child != null) { |
| 140 assert(child.parentData is SectorChildListParentData); |
| 141 if (child.hitTest(result, radius: radius, theta: theta)) |
| 142 return; |
| 143 child = child.parentData.previousSibling; |
| 144 } |
| 145 } |
| 146 } |
| 147 |
| 148 class RenderSectorRing extends RenderSectorWithChildren { |
123 // lays out RenderSector children in a ring | 149 // lays out RenderSector children in a ring |
124 | 150 |
125 RenderSectorRing({ | 151 RenderSectorRing({ |
126 BoxDecoration decoration, | 152 BoxDecoration decoration, |
127 double deltaRadius: double.INFINITY, | 153 double deltaRadius: double.INFINITY, |
128 double padding: 0.0 | 154 double padding: 0.0 |
129 }) : super(decoration), _padding = padding, _desiredDeltaRadius = deltaRadius; | 155 }) : super(decoration), _padding = padding, _desiredDeltaRadius = deltaRadius; |
130 | 156 |
131 double _desiredDeltaRadius; | 157 double _desiredDeltaRadius; |
132 double get desiredDeltaRadius => _desiredDeltaRadius; | 158 double get desiredDeltaRadius => _desiredDeltaRadius; |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
222 assert(child.parentData is SectorChildListParentData); | 248 assert(child.parentData is SectorChildListParentData); |
223 child = child.parentData.nextSibling; | 249 child = child.parentData.nextSibling; |
224 if (child != null) { | 250 if (child != null) { |
225 innerTheta += paddingTheta; | 251 innerTheta += paddingTheta; |
226 remainingDeltaTheta -= paddingTheta; | 252 remainingDeltaTheta -= paddingTheta; |
227 } | 253 } |
228 } | 254 } |
229 deltaTheta = innerTheta; | 255 deltaTheta = innerTheta; |
230 } | 256 } |
231 | 257 |
232 // TODO(ianh): hit testing et al is pending on adam's patch | |
233 | |
234 // paint origin is 0,0 of our circle | 258 // paint origin is 0,0 of our circle |
235 // each sector then knows how to paint itself at its location | 259 // each sector then knows how to paint itself at its location |
236 void paint(RenderNodeDisplayList canvas) { | 260 void paint(RenderNodeDisplayList canvas) { |
237 // TODO(ianh): avoid code duplication | 261 // TODO(ianh): avoid code duplication |
238 super.paint(canvas); | 262 super.paint(canvas); |
239 RenderSector child = firstChild; | 263 RenderSector child = firstChild; |
240 while (child != null) { | 264 while (child != null) { |
241 assert(child.parentData is SectorChildListParentData); | 265 assert(child.parentData is SectorChildListParentData); |
242 canvas.paintChild(child, 0.0, 0.0); | 266 canvas.paintChild(child, 0.0, 0.0); |
243 child = child.parentData.nextSibling; | 267 child = child.parentData.nextSibling; |
244 } | 268 } |
245 } | 269 } |
246 | 270 |
247 } | 271 } |
248 | 272 |
249 class RenderSectorSlice extends RenderDecoratedSector with ContainerRenderNodeMi
xin<RenderSector, SectorChildListParentData> { | 273 class RenderSectorSlice extends RenderSectorWithChildren { |
250 // lays out RenderSector children in a stack | 274 // lays out RenderSector children in a stack |
251 | 275 |
252 RenderSectorSlice({ | 276 RenderSectorSlice({ |
253 BoxDecoration decoration, | 277 BoxDecoration decoration, |
254 double deltaTheta: kTwoPi, | 278 double deltaTheta: kTwoPi, |
255 double padding: 0.0 | 279 double padding: 0.0 |
256 }) : super(decoration), _padding = padding, _desiredDeltaTheta = deltaTheta; | 280 }) : super(decoration), _padding = padding, _desiredDeltaTheta = deltaTheta; |
257 | 281 |
258 double _desiredDeltaTheta; | 282 double _desiredDeltaTheta; |
259 double get desiredDeltaTheta => _desiredDeltaTheta; | 283 double get desiredDeltaTheta => _desiredDeltaTheta; |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
344 childRadius += child.deltaRadius; | 368 childRadius += child.deltaRadius; |
345 remainingDeltaRadius -= child.deltaRadius; | 369 remainingDeltaRadius -= child.deltaRadius; |
346 assert(child.parentData is SectorChildListParentData); | 370 assert(child.parentData is SectorChildListParentData); |
347 child = child.parentData.nextSibling; | 371 child = child.parentData.nextSibling; |
348 childRadius += padding; | 372 childRadius += padding; |
349 remainingDeltaRadius -= padding; | 373 remainingDeltaRadius -= padding; |
350 } | 374 } |
351 deltaRadius = childRadius - this.parentData.radius; | 375 deltaRadius = childRadius - this.parentData.radius; |
352 } | 376 } |
353 | 377 |
354 // TODO(ianh): hit testing et al is pending on adam's patch | |
355 | |
356 // paint origin is 0,0 of our circle | 378 // paint origin is 0,0 of our circle |
357 // each sector then knows how to paint itself at its location | 379 // each sector then knows how to paint itself at its location |
358 void paint(RenderNodeDisplayList canvas) { | 380 void paint(RenderNodeDisplayList canvas) { |
359 // TODO(ianh): avoid code duplication | 381 // TODO(ianh): avoid code duplication |
360 super.paint(canvas); | 382 super.paint(canvas); |
361 RenderSector child = firstChild; | 383 RenderSector child = firstChild; |
362 while (child != null) { | 384 while (child != null) { |
363 assert(child.parentData is SectorChildListParentData); | 385 assert(child.parentData is SectorChildListParentData); |
364 canvas.paintChild(child, 0.0, 0.0); | 386 canvas.paintChild(child, 0.0, 0.0); |
365 child = child.parentData.nextSibling; | 387 child = child.parentData.nextSibling; |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
429 ourDimensions = new BoxDimensions.withConstraints(constraints, width: dime
nsion, height: dimension); | 451 ourDimensions = new BoxDimensions.withConstraints(constraints, width: dime
nsion, height: dimension); |
430 } | 452 } |
431 width = ourDimensions.width; | 453 width = ourDimensions.width; |
432 height = ourDimensions.height; | 454 height = ourDimensions.height; |
433 layoutDone(); | 455 layoutDone(); |
434 } | 456 } |
435 | 457 |
436 double width; | 458 double width; |
437 double height; | 459 double height; |
438 | 460 |
439 // TODO(ianh): hit testing et al is pending on adam's patch | |
440 | |
441 // paint origin is 0,0 of our circle | 461 // paint origin is 0,0 of our circle |
442 void paint(RenderNodeDisplayList canvas) { | 462 void paint(RenderNodeDisplayList canvas) { |
443 super.paint(canvas); | 463 super.paint(canvas); |
444 if (child != null) | 464 if (child != null) |
445 canvas.paintChild(child, width/2.0, height/2.0); | 465 canvas.paintChild(child, width/2.0, height/2.0); |
446 } | 466 } |
| 467 |
| 468 bool hitTest(HitTestResult result, { double x, double y }) { |
| 469 if (child == null) |
| 470 return false; |
| 471 // translate to our origin |
| 472 x -= width/2.0; |
| 473 y -= height/2.0; |
| 474 // convert to radius/theta |
| 475 double radius = math.sqrt(x*x+y*y); |
| 476 double theta = (math.atan2(x, -y) - math.PI/2.0) % kTwoPi; |
| 477 if (radius < innerRadius) |
| 478 return false; |
| 479 if (radius >= innerRadius + child.deltaRadius) |
| 480 return false; |
| 481 if (theta > child.deltaTheta) |
| 482 return false; |
| 483 child.hitTest(result, radius: radius, theta: theta); |
| 484 result.add(this); |
| 485 return true; |
| 486 } |
447 | 487 |
448 } | 488 } |
449 | 489 |
450 class RenderSolidColor extends RenderDecoratedSector { | 490 class RenderSolidColor extends RenderDecoratedSector { |
451 RenderSolidColor(int backgroundColor, { | 491 RenderSolidColor(int backgroundColor, { |
452 this.desiredDeltaRadius: double.INFINITY, | 492 this.desiredDeltaRadius: double.INFINITY, |
453 this.desiredDeltaTheta: kTwoPi | 493 this.desiredDeltaTheta: kTwoPi |
454 }) : super(new BoxDecoration(backgroundColor: backgroundColor)); | 494 }) : this.backgroundColor = backgroundColor, |
| 495 super(new BoxDecoration(backgroundColor: backgroundColor)); |
455 | 496 |
456 double desiredDeltaRadius; | 497 double desiredDeltaRadius; |
457 double desiredDeltaTheta; | 498 double desiredDeltaTheta; |
| 499 final int backgroundColor; |
458 | 500 |
459 SectorDimensions getIntrinsicDimensions(SectorConstraints constraints, double
radius) { | 501 SectorDimensions getIntrinsicDimensions(SectorConstraints constraints, double
radius) { |
460 return new SectorDimensions.withConstraints(constraints, deltaTheta: 1.0); /
/ 1.0 radians | 502 return new SectorDimensions.withConstraints(constraints, deltaTheta: 1.0); /
/ 1.0 radians |
461 } | 503 } |
462 | 504 |
463 void layout(SectorConstraints constraints, { RenderNode relayoutSubtreeRoot })
{ | 505 void layout(SectorConstraints constraints, { RenderNode relayoutSubtreeRoot })
{ |
464 deltaRadius = constraints.constrainDeltaRadius(desiredDeltaRadius); | 506 deltaRadius = constraints.constrainDeltaRadius(desiredDeltaRadius); |
465 deltaTheta = constraints.constrainDeltaTheta(desiredDeltaTheta); | 507 deltaTheta = constraints.constrainDeltaTheta(desiredDeltaTheta); |
466 layoutDone(); | 508 layoutDone(); |
467 } | 509 } |
| 510 |
| 511 void handlePointer(sky.PointerEvent event) { |
| 512 if (event.type == 'pointerdown') |
| 513 setBoxDecoration(new BoxDecoration(backgroundColor: 0xFFFF0000)); |
| 514 else if (event.type == 'pointerup') |
| 515 setBoxDecoration(new BoxDecoration(backgroundColor: backgroundColor)); |
| 516 } |
468 } | 517 } |
469 | 518 |
470 RenderView renderView; | 519 AppView app; |
471 | |
472 void beginFrame(double timeStamp) { | |
473 RenderNode.flushLayout(); | |
474 | |
475 renderView.paintFrame(); | |
476 } | |
477 | |
478 bool handleEvent(sky.Event event) { | |
479 if (event is! sky.PointerEvent) | |
480 return false; | |
481 return renderView.handlePointer(event, x: event.x, y: event.y); | |
482 } | |
483 | 520 |
484 void main() { | 521 void main() { |
485 print("test..."); | |
486 sky.view.setEventCallback(handleEvent); | |
487 sky.view.setBeginFrameCallback(beginFrame); | |
488 | 522 |
489 var rootCircle = new RenderSectorRing(padding: 10.0); | 523 var rootCircle = new RenderSectorRing(padding: 20.0); |
490 rootCircle.add(new RenderSolidColor(0xFF00FFFF, desiredDeltaTheta: kTwoPi * 0.
25)); | 524 rootCircle.add(new RenderSolidColor(0xFF00FFFF, desiredDeltaTheta: kTwoPi * 0.
15)); |
491 rootCircle.add(new RenderSolidColor(0xFF0000FF, desiredDeltaTheta: kTwoPi * 0.
3)); | 525 rootCircle.add(new RenderSolidColor(0xFF0000FF, desiredDeltaTheta: kTwoPi * 0.
4)); |
492 var stack = new RenderSectorSlice(padding: 10.0); | 526 var stack = new RenderSectorSlice(padding: 2.0); |
493 stack.add(new RenderSolidColor(0xFFFFFF00, desiredDeltaRadius: 20.0)); | 527 stack.add(new RenderSolidColor(0xFFFFFF00, desiredDeltaRadius: 20.0)); |
494 stack.add(new RenderSolidColor(0xFFFF9000, desiredDeltaRadius: 20.0)); | 528 stack.add(new RenderSolidColor(0xFFFF9000, desiredDeltaRadius: 20.0)); |
495 stack.add(new RenderSolidColor(0xFF00FF00, desiredDeltaRadius: 20.0)); | 529 stack.add(new RenderSolidColor(0xFF00FF00)); |
496 rootCircle.add(stack); | 530 rootCircle.add(stack); |
497 | 531 |
498 var root = new RenderBoxToRenderSectorAdapter(innerRadius: 50.0, child: rootCi
rcle); | 532 var root = new RenderBoxToRenderSectorAdapter(innerRadius: 50.0, child: rootCi
rcle); |
499 renderView = new RenderView(root: root); | 533 app = new AppView(root); |
500 renderView.layout(newWidth: sky.view.width, newHeight: sky.view.height); | |
501 | |
502 sky.view.scheduleFrame(); | |
503 } | 534 } |
OLD | NEW |