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

Side by Side Diff: sky/examples/raw/sector-layout.dart

Issue 1143343004: Rationalise hit testing in the new RenderNode world (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 5 years, 7 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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698