Commit f5102d11 authored by Adam Barth's avatar Adam Barth

Events should bubble up the tree

Previously we reversed the event path by mistake before dispatching events.
parent bc169671
......@@ -52,17 +52,16 @@ class HitTestResult {
/// The list of [HitTestEntry] objects recorded during the hit test.
///
/// The first entry in the path is the least specific, typically the one at
/// the root of tree being hit tested. Event propagation starts with the most
/// specific (i.e., last) entry and proceeds in reverse order through the
/// path.
/// The first entry in the path is the most specific, typically the one at
/// the leaf of tree being hit tested. Event propagation starts with the most
/// specific (i.e., first) entry and proceeds in order through the path.
final List<HitTestEntry> path;
/// Add a [HitTestEntry] to the path.
///
/// The new entry is added at the end of the path, which means entries should
/// be added in order from last specific to most specific, typically during a
/// downward walk in the tree being hit tested.
/// be added in order from most specific to least specific, typically during a
/// upward walk in the tree being hit tested.
void add(HitTestEntry entry) {
path.add(entry);
}
......
......@@ -136,15 +136,15 @@ class SkyBinding extends HitTestTarget {
HitTestResult hitTest(Point position) {
HitTestResult result = new HitTestResult();
result.add(new BindingHitTestEntry(this, result));
_renderView.hitTest(result, position: position);
result.add(new BindingHitTestEntry(this, result));
return result;
}
EventDisposition dispatchEvent(sky.Event event, HitTestResult result) {
assert(result != null);
EventDisposition disposition = EventDisposition.ignored;
for (HitTestEntry entry in result.path.reversed) {
for (HitTestEntry entry in result.path) {
EventDisposition entryDisposition = entry.target.handleEvent(event, entry);
if (entryDisposition == EventDisposition.consumed)
return EventDisposition.consumed;
......
......@@ -81,11 +81,8 @@ class RenderView extends RenderObject with RenderObjectWithChildMixin<RenderBox>
}
bool hitTest(HitTestResult result, { Point position }) {
if (child != null) {
Rect childBounds = Point.origin & child.size;
if (childBounds.contains(position))
child.hitTest(result, position: position);
}
if (child != null)
child.hitTest(result, position: position);
result.add(new HitTestEntry(this));
return true;
}
......
......@@ -1366,7 +1366,7 @@ class WidgetSkyBinding extends SkyBinding {
EventDisposition handleEvent(sky.Event event, BindingHitTestEntry entry) {
EventDisposition disposition = EventDisposition.ignored;
for (HitTestEntry entry in entry.result.path.reversed) {
for (HitTestEntry entry in entry.result.path) {
if (entry.target is! RenderObject)
continue;
for (Widget target in RenderObjectWrapper.getWidgetsForRenderObject(entry.target)) {
......
import 'package:sky/widgets.dart';
import 'package:test/test.dart';
import 'widget_tester.dart';
void main() {
test('Events bubble up the tree', () {
WidgetTester tester = new WidgetTester();
List<String> log = new List<String>();
tester.pumpFrame(() {
return new Listener(
onPointerDown: (_) {
log.add('top');
},
child: new Listener(
onPointerDown: (_) {
log.add('middle');
},
child: new DecoratedBox(
decoration: const BoxDecoration(),
child: new Listener(
onPointerDown: (_) {
log.add('bottom');
},
child: new Text('X')
)
)
)
);
});
tester.tap(tester.findText('X'));
expect(log, equals([
'bottom',
'middle',
'top',
]));
});
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment