OLD | NEW |
| (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 'dart:sky' as sky; | |
6 import 'rendering/box.dart'; | |
7 import 'rendering/object.dart'; | |
8 import 'scheduler.dart' as scheduler; | |
9 | |
10 class PointerState { | |
11 HitTestResult result; | |
12 Point lastPosition; | |
13 | |
14 PointerState({ this.result, this.lastPosition }); | |
15 } | |
16 | |
17 class AppView { | |
18 | |
19 AppView({ RenderBox root: null, RenderView renderViewOverride }) { | |
20 assert(_app == null); | |
21 _app = this; | |
22 | |
23 sky.view.setEventCallback(_handleEvent); | |
24 sky.view.setMetricsChangedCallback(_handleMetricsChanged); | |
25 scheduler.init(); | |
26 scheduler.addPersistentFrameCallback(_beginFrame); | |
27 | |
28 if (renderViewOverride == null) { | |
29 _renderView = new RenderView(child: root); | |
30 _renderView.attach(); | |
31 _renderView.rootConstraints = _viewConstraints; | |
32 _renderView.scheduleInitialLayout(); | |
33 } else { | |
34 _renderView = renderViewOverride; | |
35 } | |
36 assert(_renderView != null); | |
37 | |
38 assert(_app == this); | |
39 } | |
40 | |
41 static AppView _app; // used to enforce that we're a singleton | |
42 | |
43 RenderView _renderView; | |
44 | |
45 ViewConstraints get _viewConstraints => | |
46 new ViewConstraints(width: sky.view.width, height: sky.view.height); | |
47 | |
48 Map<int, PointerState> _stateForPointer = new Map<int, PointerState>(); | |
49 | |
50 Function onFrame; | |
51 | |
52 RenderBox get root => _renderView.child; | |
53 void set root(RenderBox value) { | |
54 _renderView.child = value; | |
55 } | |
56 void _beginFrame(double timeStamp) { | |
57 if (onFrame != null) | |
58 onFrame(); | |
59 RenderObject.flushLayout(); | |
60 _renderView.paintFrame(); | |
61 } | |
62 | |
63 void _handleEvent(sky.Event event) { | |
64 if (event is sky.PointerEvent) { | |
65 _handlePointerEvent(event); | |
66 } else if (event is sky.GestureEvent) { | |
67 HitTestResult result = new HitTestResult(); | |
68 _renderView.hitTest(result, position: new Point(event.x, event.y)); | |
69 dispatchEvent(event, result); | |
70 } | |
71 } | |
72 | |
73 void _handleMetricsChanged() { | |
74 _renderView.rootConstraints = _viewConstraints; | |
75 } | |
76 | |
77 PointerState _createStateForPointer(sky.PointerEvent event, Point position) { | |
78 HitTestResult result = new HitTestResult(); | |
79 _renderView.hitTest(result, position: position); | |
80 PointerState state = new PointerState(result: result, lastPosition: position
); | |
81 _stateForPointer[event.pointer] = state; | |
82 return state; | |
83 } | |
84 | |
85 void _handlePointerEvent(sky.PointerEvent event) { | |
86 Point position = new Point(event.x, event.y); | |
87 | |
88 PointerState state; | |
89 switch(event.type) { | |
90 case 'pointerdown': | |
91 state = _createStateForPointer(event, position); | |
92 break; | |
93 case 'pointerup': | |
94 case 'pointercancel': | |
95 state = _stateForPointer[event.pointer]; | |
96 _stateForPointer.remove(event.pointer); | |
97 break; | |
98 case 'pointermove': | |
99 state = _stateForPointer[event.pointer]; | |
100 // In the case of mouse hover we won't already have a cached down. | |
101 if (state == null) | |
102 state = _createStateForPointer(event, position); | |
103 break; | |
104 } | |
105 event.dx = position.x - state.lastPosition.x; | |
106 event.dy = position.y - state.lastPosition.y; | |
107 state.lastPosition = position; | |
108 | |
109 dispatchEvent(event, state.result); | |
110 } | |
111 | |
112 void dispatchEvent(sky.Event event, HitTestResult result) { | |
113 assert(result != null); | |
114 for (HitTestEntry entry in result.path.reversed) | |
115 entry.target.handleEvent(event, entry); | |
116 } | |
117 | |
118 String toString() => 'Render Tree:\n${_renderView}'; | |
119 | |
120 void debugDumpRenderTree() { | |
121 toString().split('\n').forEach(print); | |
122 } | |
123 | |
124 } | |
OLD | NEW |