flutter_desktop: show cursor

Signed-off-by: fufesou <shuanglongchen@yeah.net>
This commit is contained in:
fufesou 2022-09-07 02:14:52 -07:00
parent 70c4726766
commit 1bf9700da6
2 changed files with 41 additions and 27 deletions

View File

@ -1,5 +1,6 @@
import 'dart:async'; import 'dart:async';
import 'dart:io'; import 'dart:io';
import 'dart:typed_data';
import 'dart:ui' as ui; import 'dart:ui' as ui;
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
@ -407,7 +408,7 @@ class _RemotePageState extends State<RemotePage>
]; ];
paints.add(Obx(() => Visibility( paints.add(Obx(() => Visibility(
visible: _keyboardEnabled.isTrue || _showRemoteCursor.isTrue, visible: _showRemoteCursor.isTrue && _remoteCursorMoved.isTrue,
child: CursorPaint( child: CursorPaint(
id: widget.id, id: widget.id,
)))); ))));
@ -493,7 +494,7 @@ class ImagePaint extends StatelessWidget {
painter: ImagePainter(image: m.image, x: 0, y: 0, scale: s), painter: ImagePainter(image: m.image, x: 0, y: 0, scale: s),
)); ));
Rx<Offset> pos = Rx<Offset>(Offset(0.0, 0.0)); Rx<Offset> pos = Rx<Offset>(const Offset(0.0, 0.0));
return Center( return Center(
child: NotificationListener<ScrollNotification>( child: NotificationListener<ScrollNotification>(
onNotification: (notification) { onNotification: (notification) {
@ -512,12 +513,15 @@ class ImagePaint extends StatelessWidget {
cursor: (cursorOverImage.isTrue && keyboardEnabled.isTrue) cursor: (cursorOverImage.isTrue && keyboardEnabled.isTrue)
? (remoteCursorMoved.isTrue ? (remoteCursorMoved.isTrue
? SystemMouseCursors.none ? SystemMouseCursors.none
: FlutterCustomMemoryImageCursor( : (cursor.pngData != null
pixbuf: cursor.rgba!, ? FlutterCustomMemoryImageCursor(
hotx: cursor.hotx, pixbuf: cursor.pngData!,
hoty: cursor.hoty, hotx: cursor.hotx,
imageWidth: (cursor.image!.width * s).toInt(), hoty: cursor.hoty,
imageHeight: (cursor.image!.height * s).toInt())) imageWidth: (cursor.image!.width * s).toInt(),
imageHeight: (cursor.image!.height * s).toInt(),
)
: MouseCursor.defer))
: MouseCursor.defer, : MouseCursor.defer,
onHover: (evt) { onHover: (evt) {
pos.value = evt.position; pos.value = evt.position;

View File

@ -4,6 +4,7 @@ import 'dart:io';
import 'dart:math'; import 'dart:math';
import 'dart:typed_data'; import 'dart:typed_data';
import 'dart:ui' as ui; import 'dart:ui' as ui;
import 'dart:ui';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
@ -595,8 +596,9 @@ class CanvasModel with ChangeNotifier {
class CursorModel with ChangeNotifier { class CursorModel with ChangeNotifier {
ui.Image? _image; ui.Image? _image;
Uint8List? _rgba; final _images = <int, Tuple3<ui.Image, double, double>>{};
final _images = <int, Tuple4<Uint8List, ui.Image, double, double>>{}; Uint8List? _pngData;
final _pngs = <int, Uint8List?>{};
double _x = -10000; double _x = -10000;
double _y = -10000; double _y = -10000;
double _hotx = 0; double _hotx = 0;
@ -607,7 +609,7 @@ class CursorModel with ChangeNotifier {
WeakReference<FFI> parent; WeakReference<FFI> parent;
ui.Image? get image => _image; ui.Image? get image => _image;
Uint8List? get rgba => _rgba; Uint8List? get pngData => _pngData;
double get x => _x - _displayOriginX; double get x => _x - _displayOriginX;
@ -757,26 +759,34 @@ class CursorModel with ChangeNotifier {
var pid = parent.target?.id; var pid = parent.target?.id;
ui.decodeImageFromPixels(rgba, width, height, ui.PixelFormat.rgba8888, ui.decodeImageFromPixels(rgba, width, height, ui.PixelFormat.rgba8888,
(image) { (image) {
if (parent.target?.id != pid) return; () async {
_image = image; if (parent.target?.id != pid) return;
_rgba = rgba; _image = image;
_images[id] = Tuple4(rgba, image, _hotx, _hoty); _images[id] = Tuple3(image, _hotx, _hoty);
try { final data = await image.toByteData(format: ImageByteFormat.png);
// my throw exception, because the listener maybe already dispose if (data != null) {
notifyListeners(); _pngData = data.buffer.asUint8List();
} catch (e) { } else {
debugPrint('notify cursor: $e'); _pngData = null;
} }
_pngs[id] = _pngData;
try {
// my throw exception, because the listener maybe already dispose
notifyListeners();
} catch (e) {
debugPrint('notify cursor: $e');
}
}();
}); });
} }
void updateCursorId(Map<String, dynamic> evt) { void updateCursorId(Map<String, dynamic> evt) {
_pngData = _pngs[int.parse(evt['id'])];
final tmp = _images[int.parse(evt['id'])]; final tmp = _images[int.parse(evt['id'])];
if (tmp != null) { if (tmp != null) {
_rgba = tmp.item1; _image = tmp.item1;
_image = tmp.item2; _hotx = tmp.item2;
_hotx = tmp.item3; _hoty = tmp.item3;
_hoty = tmp.item4;
notifyListeners(); notifyListeners();
} }
} }
@ -786,7 +796,7 @@ class CursorModel with ChangeNotifier {
_x = double.parse(evt['x']); _x = double.parse(evt['x']);
_y = double.parse(evt['y']); _y = double.parse(evt['y']);
try { try {
RemoteCursorMovedState.find(id).value = false; RemoteCursorMovedState.find(id).value = true;
} catch (e) { } catch (e) {
// //
} }
@ -1011,7 +1021,7 @@ class FFI {
Peer.fromJson(s[0] as String, s[1] as Map<String, dynamic>)) Peer.fromJson(s[0] as String, s[1] as Map<String, dynamic>))
.toList(); .toList();
} catch (e) { } catch (e) {
print('peers(): $e'); debugPrint('peers(): $e');
} }
return []; return [];
} }