Reputation: 1650
I'd like to pause execution of my Dart script (in a webpage) until the user hits a key. The following code works, but I'm wondering if there's any better way of doing it:
import 'dart:html';
import 'dart:async';
StreamSubscription sub;
Future main() async {
KeyboardEvent k = await getkey();
print(k.keyCode.toString());
}
Future<KeyboardEvent> getkey() async {
Completer<KeyboardEvent> c = new Completer<KeyboardEvent>();
sub = document.onKeyDown.listen((KeyboardEvent e){
sub.cancel();
c.complete(e);
});
return c.future;
}
Update: Gunter's solution below is ideal. The code above shortens to:
import 'dart:html';
import 'dart:async';
StreamSubscription sub;
Future main() async {
KeyboardEvent k = await getkey();
print(k.keyCode.toString());
}
Future<KeyboardEvent> getkey() async {
return document.onKeyDown.first;
}
However, if I want to filter the keypresses I think I'm back to the former style:
import 'dart:html';
import 'dart:async';
StreamSubscription sub;
Future main() async {
KeyboardEvent k = await getkey([KeyCode.A,KeyCode.B,KeyCode.C,KeyCode.D]);
print(k.keyCode.toString());
}
Future<KeyboardEvent> getkey([List<int> lst]) async {
Completer<KeyboardEvent> c = new Completer<KeyboardEvent>();
sub = document.onKeyDown.listen((KeyboardEvent e){
if ((lst==null)||(lst.contains(e.keyCode))){
sub.cancel();
c.complete(e);
}
});
return c.future;
}
Is that right?
Update Thanks again to Gunter! Result is:
Future<KeyboardEvent> getkey([List<int> lst]) async {
return document.onKeyDown.firstWhere((KeyboardEvent e)=>((lst==null)||(lst.contains(e.keyCode))));
}
Used as follows:
import 'dart:html';
import 'dart:async';
Future main() async {
KeyboardEvent k = await getkey();
print(k.keyCode.toString());
KeyboardEvent k = await getkey([KeyCode.A,KeyCode.B,KeyCode.C,KeyCode.D]);
print(k.keyCode.toString());
}
Upvotes: 5
Views: 936
Reputation: 657148
Not tested, but as far as I remember changing
Completer<KeyboardEvent> c = new Completer<KeyboardEvent>();
sub = document.onKeyDown.listen((KeyboardEvent e){
sub.cancel();
c.complete(e);
});
return c.future;
to
return document.onKeyDown.first;
should do the same.
return document.onKeyDown.firstWhere((KeyboardEvent e) => 1st.contains(e.keyCode));
(again not tested)
Upvotes: 2