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