square.dart 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. import 'dart:async';
  2. import 'dart:math';
  3. import 'dart:typed_data';
  4. import 'package:flutter/material.dart';
  5. import 'package:flutter/services.dart';
  6. import 'package:the_paint/src/generated/client.pbgrpc.dart';
  7. import 'dart:ui' as ui;
  8. import '../color_ref.dart';
  9. import '../square/in_memory.dart';
  10. import '../square/square.dart';
  11. class SquareComponent extends StatefulWidget {
  12. final Point<int> tile;
  13. final ColorRef color;
  14. const SquareComponent({super.key, required this.tile, required this.color});
  15. @override
  16. SquareComponentState createState() => SquareComponentState();
  17. }
  18. class SquareComponentState extends State<SquareComponent> {
  19. late final SquereData __serverSquareData = InMemorySquereData(widget.tile);
  20. final Uint8List data = Uint8List(256 * 256 * 4);
  21. Future<ui.Image> _loadImage() async {
  22. final Completer<ui.Image> completer = Completer<ui.Image>();
  23. ui.decodeImageFromPixels(
  24. data,
  25. 256,
  26. 256,
  27. ui.PixelFormat.rgba8888,
  28. (ui.Image image) => completer.complete(image.clone()),
  29. allowUpscaling: false,
  30. );
  31. return completer.future;
  32. }
  33. @override
  34. void initState() {
  35. super.initState();
  36. streamSub();
  37. }
  38. @override
  39. Widget build(BuildContext context) {
  40. return GestureDetector(
  41. onTapDown: (details) {
  42. var point = Point<int>(
  43. details.localPosition.dx.floor(),
  44. details.localPosition.dy.floor(),
  45. );
  46. __serverSquareData.paint(point, widget.color.getColor());
  47. },
  48. child: Stack(children: [
  49. // Text(this.hashCode.toString()),
  50. FutureBuilder<ui.Image>(
  51. future: _loadImage(),
  52. builder: getImage,
  53. )
  54. ]));
  55. }
  56. Future<void> streamSub() async {
  57. await for (var event in __serverSquareData.getSteam()) {
  58. setState(() {
  59. storePoint(event);
  60. });
  61. }
  62. }
  63. void storePoint(MonitorReply dd) {
  64. BPoint? lastPosition;
  65. for (var point in dd.points) {
  66. lastPosition = point.point;
  67. var p = lastPosition;
  68. final startByte = (p.x + p.y * 256) * 4;
  69. for (int index in [0, 1, 2, 3]) {
  70. data[startByte + index] = point.color.rgba >> 8 * index & 0xff;
  71. }
  72. }
  73. }
  74. Widget getImage(BuildContext context, AsyncSnapshot<ui.Image> snapshot) {
  75. if (snapshot.hasData) {
  76. var image = snapshot.data?.clone();
  77. // snapshot.data?.dispose();
  78. return RawImage(
  79. image: image,
  80. filterQuality: FilterQuality.none,
  81. );
  82. } else if (snapshot.hasError) {
  83. print('${snapshot.error}');
  84. return Text('${snapshot.error}');
  85. }
  86. // By default, show a loading spinner.
  87. return const CircularProgressIndicator();
  88. }
  89. @override
  90. void dispose() {
  91. super.dispose();
  92. }
  93. }