blob: fac4d5fbd1b751f323a6edb9d47b3e6511a3b462 [file] [log] [blame]
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import '../fn2.dart';
import 'dart:collection';
import 'dart:sky' as sky;
import 'ink_splash.dart';
import 'scrollable.dart';
class InkWell extends Component implements ScrollClient {
static final Style _containmentStyleHack = new Style('''
align-items: center;
transform: translateX(0);''');
LinkedHashSet<SplashController> _splashes;
String inlineStyle;
List<UINode> children;
InkWell({ Object key, this.inlineStyle, this.children })
: super(key: key) {
onDidUnmount(() {
_cancelSplashes(null);
});
}
UINode build() {
List<UINode> childrenIncludingSplashes = [];
if (_splashes != null) {
childrenIncludingSplashes.addAll(
_splashes.map((s) => new InkSplash(s.onStyleChanged)));
}
if (children != null)
childrenIncludingSplashes.addAll(children);
return new EventListenerNode(
new FlexContainer(
direction: FlexDirection.Row,
style: _containmentStyleHack,
inlineStyle: inlineStyle,
children: childrenIncludingSplashes),
onGestureTapDown: _startSplash,
onGestureTap: _confirmSplash
);
}
void _startSplash(sky.GestureEvent event) {
setState(() {
if (_splashes == null)
_splashes = new LinkedHashSet<SplashController>();
var splash;
var root = getRoot();
splash = new SplashController(root.rect, event.x, event.y,
pointer: event.primaryPointer,
onDone: () { _splashDone(splash); });
_splashes.add(splash);
UINode node = parent;
while (node != null) {
if (node is Scrollable)
node.registerScrollClient(this);
node = node.parent;
}
});
}
bool ancestorScrolled(Scrollable ancestor) {
_abortSplashes();
return false;
}
void handleRemoved() {
UINode node = parent;
while (node != null) {
if (node is Scrollable)
node.unregisterScrollClient(this);
node = node.parent;
}
super.handleRemoved();
}
void _confirmSplash(sky.GestureEvent event) {
if (_splashes == null)
return;
_splashes.where((splash) => splash.pointer == event.primaryPointer)
.forEach((splash) { splash.confirm(); });
}
void _abortSplashes() {
if (_splashes == null)
return;
setState(() {
_splashes.forEach((s) { s.abort(); });
});
}
void _cancelSplashes(sky.Event event) {
if (_splashes == null)
return;
setState(() {
var splashes = _splashes;
_splashes = null;
splashes.forEach((s) { s.cancel(); });
});
}
void _splashDone(SplashController splash) {
if (_splashes == null)
return;
setState(() {
_splashes.remove(splash);
if (_splashes.length == 0)
_splashes = null;
});
}
}