Merge pull request #3028 from fufesou/fix/cursor_without_dpi
cursor scale
This commit is contained in:
commit
29133e074d
flutter/lib
@ -3,7 +3,6 @@ import 'dart:io';
|
|||||||
import 'dart:ui' as ui;
|
import 'dart:ui' as ui;
|
||||||
|
|
||||||
import 'package:desktop_multi_window/desktop_multi_window.dart';
|
import 'package:desktop_multi_window/desktop_multi_window.dart';
|
||||||
import 'package:flutter/gestures.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_custom_cursor/cursor_manager.dart'
|
import 'package:flutter_custom_cursor/cursor_manager.dart'
|
||||||
@ -363,10 +362,10 @@ class _RemotePageState extends State<RemotePage>
|
|||||||
|
|
||||||
class ImagePaint extends StatefulWidget {
|
class ImagePaint extends StatefulWidget {
|
||||||
final String id;
|
final String id;
|
||||||
final Rx<bool> zoomCursor;
|
final RxBool zoomCursor;
|
||||||
final Rx<bool> cursorOverImage;
|
final RxBool cursorOverImage;
|
||||||
final Rx<bool> keyboardEnabled;
|
final RxBool keyboardEnabled;
|
||||||
final Rx<bool> remoteCursorMoved;
|
final RxBool remoteCursorMoved;
|
||||||
final Widget Function(Widget)? listenerBuilder;
|
final Widget Function(Widget)? listenerBuilder;
|
||||||
|
|
||||||
ImagePaint(
|
ImagePaint(
|
||||||
@ -389,10 +388,10 @@ class _ImagePaintState extends State<ImagePaint> {
|
|||||||
final ScrollController _vertical = ScrollController();
|
final ScrollController _vertical = ScrollController();
|
||||||
|
|
||||||
String get id => widget.id;
|
String get id => widget.id;
|
||||||
Rx<bool> get zoomCursor => widget.zoomCursor;
|
RxBool get zoomCursor => widget.zoomCursor;
|
||||||
Rx<bool> get cursorOverImage => widget.cursorOverImage;
|
RxBool get cursorOverImage => widget.cursorOverImage;
|
||||||
Rx<bool> get keyboardEnabled => widget.keyboardEnabled;
|
RxBool get keyboardEnabled => widget.keyboardEnabled;
|
||||||
Rx<bool> get remoteCursorMoved => widget.remoteCursorMoved;
|
RxBool get remoteCursorMoved => widget.remoteCursorMoved;
|
||||||
Widget Function(Widget)? get listenerBuilder => widget.listenerBuilder;
|
Widget Function(Widget)? get listenerBuilder => widget.listenerBuilder;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -400,6 +399,20 @@ class _ImagePaintState extends State<ImagePaint> {
|
|||||||
final m = Provider.of<ImageModel>(context);
|
final m = Provider.of<ImageModel>(context);
|
||||||
var c = Provider.of<CanvasModel>(context);
|
var c = Provider.of<CanvasModel>(context);
|
||||||
final s = c.scale;
|
final s = c.scale;
|
||||||
|
var cursorScale = 1.0;
|
||||||
|
|
||||||
|
if (Platform.isWindows) {
|
||||||
|
// debug win10
|
||||||
|
final isViewAdaptive = c.viewStyle.style == kRemoteViewStyleAdaptive;
|
||||||
|
if (zoomCursor.value && isViewAdaptive) {
|
||||||
|
cursorScale = s * c.devicePixelRatio;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
final isViewOriginal = c.viewStyle.style == kRemoteViewStyleOriginal;
|
||||||
|
if (zoomCursor.value || isViewOriginal) {
|
||||||
|
cursorScale = s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mouseRegion({child}) => Obx(() => MouseRegion(
|
mouseRegion({child}) => Obx(() => MouseRegion(
|
||||||
cursor: cursorOverImage.isTrue
|
cursor: cursorOverImage.isTrue
|
||||||
@ -415,10 +428,10 @@ class _ImagePaintState extends State<ImagePaint> {
|
|||||||
_lastRemoteCursorMoved = false;
|
_lastRemoteCursorMoved = false;
|
||||||
_firstEnterImage.value = true;
|
_firstEnterImage.value = true;
|
||||||
}
|
}
|
||||||
return _buildCustomCursor(context, s);
|
return _buildCustomCursor(context, cursorScale);
|
||||||
}
|
}
|
||||||
}())
|
}())
|
||||||
: _buildDisabledCursor(context, s)
|
: _buildDisabledCursor(context, cursorScale)
|
||||||
: MouseCursor.defer,
|
: MouseCursor.defer,
|
||||||
onHover: (evt) {},
|
onHover: (evt) {},
|
||||||
child: child));
|
child: child));
|
||||||
@ -467,7 +480,7 @@ class _ImagePaintState extends State<ImagePaint> {
|
|||||||
if (cache == null) {
|
if (cache == null) {
|
||||||
return MouseCursor.defer;
|
return MouseCursor.defer;
|
||||||
} else {
|
} else {
|
||||||
final key = cache.updateGetKey(scale, zoomCursor.value);
|
final key = cache.updateGetKey(scale);
|
||||||
if (!cursor.cachedKeys.contains(key)) {
|
if (!cursor.cachedKeys.contains(key)) {
|
||||||
debugPrint("Register custom cursor with key $key");
|
debugPrint("Register custom cursor with key $key");
|
||||||
// [Safety]
|
// [Safety]
|
||||||
@ -633,7 +646,8 @@ class CursorPaint extends StatelessWidget {
|
|||||||
double x = (m.x - hotx) * c.scale + cx;
|
double x = (m.x - hotx) * c.scale + cx;
|
||||||
double y = (m.y - hoty) * c.scale + cy;
|
double y = (m.y - hoty) * c.scale + cy;
|
||||||
double scale = 1.0;
|
double scale = 1.0;
|
||||||
if (zoomCursor.isTrue) {
|
final isViewOriginal = c.viewStyle.style == kRemoteViewStyleOriginal;
|
||||||
|
if (zoomCursor.value || isViewOriginal) {
|
||||||
x = m.x - hotx + cx / c.scale;
|
x = m.x - hotx + cx / c.scale;
|
||||||
y = m.y - hoty + cy / c.scale;
|
y = m.y - hoty + cy / c.scale;
|
||||||
scale = c.scale;
|
scale = c.scale;
|
||||||
|
@ -540,6 +540,7 @@ class CanvasModel with ChangeNotifier {
|
|||||||
double _y = 0;
|
double _y = 0;
|
||||||
// image scale
|
// image scale
|
||||||
double _scale = 1.0;
|
double _scale = 1.0;
|
||||||
|
double _devicePixelRatio = 1.0;
|
||||||
Size _size = Size.zero;
|
Size _size = Size.zero;
|
||||||
// the tabbar over the image
|
// the tabbar over the image
|
||||||
// double tabBarHeight = 0.0;
|
// double tabBarHeight = 0.0;
|
||||||
@ -563,6 +564,7 @@ class CanvasModel with ChangeNotifier {
|
|||||||
double get x => _x;
|
double get x => _x;
|
||||||
double get y => _y;
|
double get y => _y;
|
||||||
double get scale => _scale;
|
double get scale => _scale;
|
||||||
|
double get devicePixelRatio => _devicePixelRatio;
|
||||||
Size get size => _size;
|
Size get size => _size;
|
||||||
ScrollStyle get scrollStyle => _scrollStyle;
|
ScrollStyle get scrollStyle => _scrollStyle;
|
||||||
ViewStyle get viewStyle => _lastViewStyle;
|
ViewStyle get viewStyle => _lastViewStyle;
|
||||||
@ -611,8 +613,9 @@ class CanvasModel with ChangeNotifier {
|
|||||||
_lastViewStyle = viewStyle;
|
_lastViewStyle = viewStyle;
|
||||||
_scale = viewStyle.scale;
|
_scale = viewStyle.scale;
|
||||||
|
|
||||||
|
_devicePixelRatio = ui.window.devicePixelRatio;
|
||||||
if (kIgnoreDpi && style == kRemoteViewStyleOriginal) {
|
if (kIgnoreDpi && style == kRemoteViewStyleOriginal) {
|
||||||
_scale = 1.0 / ui.window.devicePixelRatio;
|
_scale = 1.0 / _devicePixelRatio;
|
||||||
}
|
}
|
||||||
_x = (size.width - displayWidth * _scale) / 2;
|
_x = (size.width - displayWidth * _scale) / 2;
|
||||||
_y = (size.height - displayHeight * _scale) / 2;
|
_y = (size.height - displayHeight * _scale) / 2;
|
||||||
@ -747,7 +750,7 @@ class CanvasModel with ChangeNotifier {
|
|||||||
class CursorData {
|
class CursorData {
|
||||||
final String peerId;
|
final String peerId;
|
||||||
final int id;
|
final int id;
|
||||||
final img2.Image? image;
|
final img2.Image image;
|
||||||
double scale;
|
double scale;
|
||||||
Uint8List? data;
|
Uint8List? data;
|
||||||
final double hotxOrigin;
|
final double hotxOrigin;
|
||||||
@ -772,33 +775,40 @@ class CursorData {
|
|||||||
|
|
||||||
int _doubleToInt(double v) => (v * 10e6).round().toInt();
|
int _doubleToInt(double v) => (v * 10e6).round().toInt();
|
||||||
|
|
||||||
double _checkUpdateScale(double scale, bool shouldScale) {
|
double _checkUpdateScale(double scale) {
|
||||||
double oldScale = this.scale;
|
double oldScale = this.scale;
|
||||||
if (!shouldScale) {
|
if (scale != 1.0) {
|
||||||
scale = 1.0;
|
|
||||||
} else {
|
|
||||||
// Update data if scale changed.
|
// Update data if scale changed.
|
||||||
if (Platform.isWindows) {
|
final tgtWidth = (width * scale).toInt();
|
||||||
final tgtWidth = (width * scale).toInt();
|
final tgtHeight = (width * scale).toInt();
|
||||||
final tgtHeight = (width * scale).toInt();
|
if (tgtWidth < kMinCursorSize || tgtHeight < kMinCursorSize) {
|
||||||
if (tgtWidth < kMinCursorSize || tgtHeight < kMinCursorSize) {
|
double sw = kMinCursorSize.toDouble() / width;
|
||||||
double sw = kMinCursorSize.toDouble() / width;
|
double sh = kMinCursorSize.toDouble() / height;
|
||||||
double sh = kMinCursorSize.toDouble() / height;
|
scale = sw < sh ? sh : sw;
|
||||||
scale = sw < sh ? sh : sw;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Platform.isWindows) {
|
if (_doubleToInt(oldScale) != _doubleToInt(scale)) {
|
||||||
if (_doubleToInt(oldScale) != _doubleToInt(scale)) {
|
if (Platform.isWindows) {
|
||||||
data = img2
|
data = img2
|
||||||
.copyResize(
|
.copyResize(
|
||||||
image!,
|
image,
|
||||||
width: (width * scale).toInt(),
|
width: (width * scale).toInt(),
|
||||||
height: (height * scale).toInt(),
|
height: (height * scale).toInt(),
|
||||||
interpolation: img2.Interpolation.average,
|
interpolation: img2.Interpolation.average,
|
||||||
)
|
)
|
||||||
.getBytes(format: img2.Format.bgra);
|
.getBytes(format: img2.Format.bgra);
|
||||||
|
} else {
|
||||||
|
data = Uint8List.fromList(
|
||||||
|
img2.encodePng(
|
||||||
|
img2.copyResize(
|
||||||
|
image,
|
||||||
|
width: (width * scale).toInt(),
|
||||||
|
height: (height * scale).toInt(),
|
||||||
|
interpolation: img2.Interpolation.average,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -808,8 +818,8 @@ class CursorData {
|
|||||||
return scale;
|
return scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
String updateGetKey(double scale, bool shouldScale) {
|
String updateGetKey(double scale) {
|
||||||
scale = _checkUpdateScale(scale, shouldScale);
|
scale = _checkUpdateScale(scale);
|
||||||
return '${peerId}_${id}_${_doubleToInt(width * scale)}_${_doubleToInt(height * scale)}';
|
return '${peerId}_${id}_${_doubleToInt(width * scale)}_${_doubleToInt(height * scale)}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -867,7 +877,7 @@ class PredefinedCursor {
|
|||||||
_cache = CursorData(
|
_cache = CursorData(
|
||||||
peerId: '',
|
peerId: '',
|
||||||
id: id,
|
id: id,
|
||||||
image: _image2?.clone(),
|
image: _image2!.clone(),
|
||||||
scale: scale,
|
scale: scale,
|
||||||
data: data,
|
data: data,
|
||||||
hotxOrigin:
|
hotxOrigin:
|
||||||
@ -1067,9 +1077,9 @@ class CursorModel with ChangeNotifier {
|
|||||||
Future<bool> _updateCache(
|
Future<bool> _updateCache(
|
||||||
Uint8List rgba, ui.Image image, int id, int w, int h) async {
|
Uint8List rgba, ui.Image image, int id, int w, int h) async {
|
||||||
Uint8List? data;
|
Uint8List? data;
|
||||||
img2.Image? imgOrigin;
|
img2.Image imgOrigin =
|
||||||
|
img2.Image.fromBytes(w, h, rgba, format: img2.Format.rgba);
|
||||||
if (Platform.isWindows) {
|
if (Platform.isWindows) {
|
||||||
imgOrigin = img2.Image.fromBytes(w, h, rgba, format: img2.Format.rgba);
|
|
||||||
data = imgOrigin.getBytes(format: img2.Format.bgra);
|
data = imgOrigin.getBytes(format: img2.Format.bgra);
|
||||||
} else {
|
} else {
|
||||||
ByteData? imgBytes =
|
ByteData? imgBytes =
|
||||||
|
Loading…
x
Reference in New Issue
Block a user