From 3fad3812e117c6bc16b5007076803f498538e4c4 Mon Sep 17 00:00:00 2001 From: Mica White Date: Mon, 8 Dec 2025 19:54:36 -0500 Subject: First commit --- lib/console.dart | 157 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100755 lib/console.dart (limited to 'lib/console.dart') diff --git a/lib/console.dart b/lib/console.dart new file mode 100755 index 0000000..e5bbc8b --- /dev/null +++ b/lib/console.dart @@ -0,0 +1,157 @@ +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 entries; + final void Function(String) messageFn; + + const ConsolePage(this.entries, this.messageFn, {super.key}); + + @override + State createState() => _ConsolePageState(); +} + +class _ConsolePageState extends State { + 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(); + }, + ), + ]), + ), + ); + } +} -- cgit v1.2.3