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 '../fn.dart'; | |
6 import '../layout.dart'; | |
7 import 'dart:collection'; | |
8 import 'dart:sky' as sky; | |
9 import 'ink_splash.dart'; | |
10 import 'scrollable.dart'; | |
11 | |
12 class InkWell extends Component implements ScrollClient { | |
13 static final Style _containmentStyleHack = new Style(''' | |
14 align-items: center; | |
15 transform: translateX(0);'''); | |
16 | |
17 LinkedHashSet<SplashController> _splashes; | |
18 | |
19 String inlineStyle; | |
20 List<UINode> children; | |
21 | |
22 InkWell({ Object key, this.inlineStyle, this.children }) | |
23 : super(key: key) { | |
24 onDidUnmount(() { | |
25 _cancelSplashes(null); | |
26 }); | |
27 } | |
28 | |
29 UINode build() { | |
30 List<UINode> childrenIncludingSplashes = []; | |
31 | |
32 if (_splashes != null) { | |
33 childrenIncludingSplashes.addAll( | |
34 _splashes.map((s) => new InkSplash(s.onStyleChanged))); | |
35 } | |
36 | |
37 if (children != null) | |
38 childrenIncludingSplashes.addAll(children); | |
39 | |
40 return new EventListenerNode( | |
41 new FlexContainer( | |
42 direction: FlexDirection.Row, | |
43 style: _containmentStyleHack, | |
44 inlineStyle: inlineStyle, | |
45 children: childrenIncludingSplashes), | |
46 onGestureTapDown: _startSplash, | |
47 onGestureTap: _confirmSplash | |
48 ); | |
49 } | |
50 | |
51 void _startSplash(sky.GestureEvent event) { | |
52 setState(() { | |
53 if (_splashes == null) | |
54 _splashes = new LinkedHashSet<SplashController>(); | |
55 var splash; | |
56 var root = getRoot(); | |
57 splash = new SplashController(root.rect, event.x, event.y, | |
58 pointer: event.primaryPointer, | |
59 onDone: () { _splashDone(splash); }); | |
60 _splashes.add(splash); | |
61 UINode node = parent; | |
62 while (node != null) { | |
63 if (node is Scrollable) | |
64 node.registerScrollClient(this); | |
65 node = node.parent; | |
66 } | |
67 }); | |
68 } | |
69 | |
70 bool ancestorScrolled(Scrollable ancestor) { | |
71 _abortSplashes(); | |
72 return false; | |
73 } | |
74 | |
75 void handleRemoved() { | |
76 UINode node = parent; | |
77 while (node != null) { | |
78 if (node is Scrollable) | |
79 node.unregisterScrollClient(this); | |
80 node = node.parent; | |
81 } | |
82 super.handleRemoved(); | |
83 } | |
84 | |
85 void _confirmSplash(sky.GestureEvent event) { | |
86 if (_splashes == null) | |
87 return; | |
88 _splashes.where((splash) => splash.pointer == event.primaryPointer) | |
89 .forEach((splash) { splash.confirm(); }); | |
90 } | |
91 | |
92 void _abortSplashes() { | |
93 if (_splashes == null) | |
94 return; | |
95 setState(() { | |
96 _splashes.forEach((s) { s.abort(); }); | |
97 }); | |
98 } | |
99 | |
100 void _cancelSplashes(sky.Event event) { | |
101 if (_splashes == null) | |
102 return; | |
103 setState(() { | |
104 var splashes = _splashes; | |
105 _splashes = null; | |
106 splashes.forEach((s) { s.cancel(); }); | |
107 }); | |
108 } | |
109 | |
110 void _splashDone(SplashController splash) { | |
111 if (_splashes == null) | |
112 return; | |
113 setState(() { | |
114 _splashes.remove(splash); | |
115 if (_splashes.length == 0) | |
116 _splashes = null; | |
117 }); | |
118 } | |
119 } | |
OLD | NEW |