build method
Describes the part of the user interface represented by this widget.
Implementation
@override
Widget build(BuildContext context) {
return Focus(
onKeyEvent: (event) {
if (event.type == evt.KeyType.escape) {
PromptScope.of(context)?.done();
widget.onClose();
return true;
}
if (event.type == evt.KeyType.up) {
if (filteredSpans.isNotEmpty) {
setState(() {
selectedIndex = (selectedIndex - 1).clamp(
0,
filteredSpans.length - 1,
);
});
}
return true;
}
if (event.type == evt.KeyType.down) {
if (filteredSpans.isNotEmpty) {
setState(() {
selectedIndex = (selectedIndex + 1).clamp(
0,
filteredSpans.length - 1,
);
});
}
return true;
}
if (event.type == evt.KeyType.enter) {
if (filteredSpans.isNotEmpty &&
selectedIndex < filteredSpans.length) {
widget.onMatchSelected(filteredSpans[selectedIndex]);
return true;
}
}
return false;
},
child: DecoratedBox(
decoration: const BoxDecoration(
border: Border(
topChar: '─',
bottomChar: '─',
leftChar: '│',
rightChar: '│',
topLeftChar: '╔',
topRightChar: '╗',
bottomLeftChar: '╚',
bottomRightChar: '╝',
style: Style(foreground: Colors.white),
),
backgroundColor: Color(30, 30, 30),
),
child: Column([
Row([
Text(
' Search [Esc or X to close]',
style: const Style(foreground: Color(0, 255, 255)),
),
Expanded(child: const SizedBox()),
InkwellButton(onPressed: widget.onClose, text: '[X]'),
]),
SizedBox(
height: 1,
child: Text(
'─' * 50,
style: const Style(foreground: Color(128, 128, 128)),
),
),
Row([
Text(' > ', style: const Style(foreground: Colors.yellow)),
Expanded(
child: TextField(
controller: searchController,
style: const Style(foreground: Colors.white),
),
),
]),
SizedBox(
height: 1,
child: Text(
'─' * 50,
style: const Style(foreground: Color(128, 128, 128)),
),
),
SizedBox(
height: 1,
child: Row([
Text(
' Matches: ${filteredSpans.length} / ${searchController.text.isNotEmpty ? widget.spans.length : 0}',
style: const Style(foreground: Colors.green),
),
]),
),
Expanded(
child: ListView(
showScrollbar: true,
selectedIndex: selectedIndex,
onSelect: (index) {
setState(() {
selectedIndex = index;
});
widget.onMatchSelected(filteredSpans[index]);
},
children: filteredSpans
.map((span) {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 1),
child: Text(
' • ${span.name} (${(span.endUs - span.startUs) / 1000.0}ms)',
),
);
})
.toList()
.cast<Widget>(),
),
),
]),
),
);
}