import 'package:flutter/material.dart';
class ConsoleEntry {
final String text;
final bool generatedByRuntime;
final DateTime timeGenerated;
ConsoleEntry({
required this.text,
required this.generatedByRuntime,
required this.timeGenerated,
});
}
class _ConsoleFilter extends StatelessWidget {
const _ConsoleFilter(this.filter, {required this.onChanged});
final String filter;
final Function(String filter) onChanged;
@override
Widget build(BuildContext context) {
return Row(
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.only(bottom: 3),
child: TextFormField(
autocorrect: false,
enableSuggestions: false,
onChanged: onChanged,
style: const TextStyle(fontSize: 12),
decoration: const InputDecoration(
contentPadding: EdgeInsets.all(6),
labelText: "Filter: ",
),
),
),
),
const SizedBox(width: 16),
const Text("Console entries are only kept for several seconds"),
],
);
}
}
class _ConsoleLine extends StatelessWidget {
const _ConsoleLine(
this.text, {
required this.runtime,
required this.time,
});
final String text;
final bool runtime;
final DateTime time;
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 3),
child: DecoratedBox(
decoration: BoxDecoration(
color: this.runtime
? Colors.blue.shade900.withAlpha(128)
: Colors.purple.shade900.withAlpha(128),
borderRadius: const BorderRadius.all(Radius.circular(4)),
border: Border.all(
color: this.runtime ? Colors.blue.shade700 : Colors.purple.shade700,
width: 3,
)),
child: Padding(
padding: const EdgeInsets.all(6),
child: Row(
children: [
Text(this.runtime ? "Runtime" : "Editor"),
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Text(
this.text,
style: const TextStyle(fontFamily: 'Consolas'),
),
),
),
Text(
"${this.time.hour.toString().padLeft(2, '0')}:${this.time.minute.toString().padLeft(2, '0')}")
],
),
),
),
);
}
}
class ConsolePage extends StatefulWidget {
final List<ConsoleEntry> entries;
final void Function(String) messageFn;
const ConsolePage(this.entries, this.messageFn, {super.key});
@override
State<ConsolePage> createState() => _ConsolePageState();
}
class _ConsolePageState extends State<ConsolePage> {
String filter = "";
@override
Widget build(BuildContext context) {
final controller = TextEditingController();
final filteredMessages =
this.widget.entries.where((e) => e.text.contains(this.filter)).toList();
return Center(
child: Padding(
padding: const EdgeInsets.all(20),
child: Column(children: [
_ConsoleFilter(
filter,
onChanged: (newFilter) => this.setState(() => this.filter = newFilter),
),
Expanded(
child: ListView.builder(
reverse: true,
itemCount: filteredMessages.length,
prototypeItem: _ConsoleLine(
"Loading...",
runtime: false,
time: DateTime(1970),
),
itemBuilder: (context, index) {
final entry = filteredMessages[filteredMessages.length - index - 1];
return _ConsoleLine(
entry.text,
runtime: entry.generatedByRuntime,
time: entry.timeGenerated,
);
},
),
),
TextField(
autocorrect: false,
enableSuggestions: false,
style: const TextStyle(fontFamily: 'Consolas'),
controller: controller,
decoration: const InputDecoration(hintText: "Send a console message to the runtime"),
onSubmitted: (message) {
this.widget.messageFn(message);
controller.clear();
},
),
]),
),
);
}
}
|