flutter_desktop: try mouse handler

Signed-off-by: fufesou <shuanglongchen@yeah.net>
This commit is contained in:
fufesou 2022-08-12 20:14:53 +08:00
parent 4e4f837160
commit c38c9d275b
2 changed files with 113 additions and 79 deletions

View File

@ -831,22 +831,23 @@ class ImagePaint extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final m = Provider.of<ImageModel>(context); final m = Provider.of<ImageModel>(context);
final c = Provider.of<CanvasModel>(context); var c = Provider.of<CanvasModel>(context);
var s = c.scale; final s = c.scale;
final paintChild = SizedBox(
width: (m.image?.width ?? kDefaultDisplayWidth) * s,
height: (m.image?.height ?? kDefaultDisplayHeight) * s,
child: CustomPaint(
painter: new ImagePainter(
// image: m.image, x: c.x / s, y: c.y / s, scale: s),
image: m.image,
x: 0,
y: 0,
scale: s),
));
if (c.scrollStyle == ScrollStyle.scrollbar) { if (c.scrollStyle == ScrollStyle.scrollbar) {
return Center( return Center(
child: NotificationListener<ScrollNotification>(
onNotification: (_notification) {
final percentX = _horizontal.position.extentBefore /
(_horizontal.position.extentBefore +
_horizontal.position.extentInside +
_horizontal.position.extentAfter);
final percentY = _vertical.position.extentBefore /
(_vertical.position.extentBefore +
_vertical.position.extentInside +
_vertical.position.extentAfter);
c.setScrollPercent(percentX, percentY);
return false;
},
child: Scrollbar( child: Scrollbar(
controller: _vertical, controller: _vertical,
thumbVisibility: true, thumbVisibility: true,
@ -861,19 +862,21 @@ class ImagePaint extends StatelessWidget {
child: SingleChildScrollView( child: SingleChildScrollView(
controller: _horizontal, controller: _horizontal,
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
child: paintChild), child: SizedBox(
), width: c.getDisplayWidth() * s,
height: c.getDisplayHeight() * s,
child: CustomPaint(
painter: new ImagePainter(
image: m.image, x: 0, y: 0, scale: s),
))),
), ),
)),
)); ));
} else { } else {
return Center( return CustomPaint(
child: InteractiveViewer( painter:
// boundaryMargin: const EdgeInsets.all(20.0), new ImagePainter(image: m.image, x: c.x / s, y: c.y / s, scale: s),
// minScale: 0.1, );
// maxScale: 1.6,
scaleEnabled: false,
child: paintChild,
));
} }
} }
} }
@ -939,6 +942,8 @@ void showOptions(String id, OverlayDialogManager dialogManager) async {
await bind.getSessionOption(id: id, arg: 'view-style') ?? ''; await bind.getSessionOption(id: id, arg: 'view-style') ?? '';
String scrollStyle = String scrollStyle =
await bind.getSessionOption(id: id, arg: 'scroll-style') ?? ''; await bind.getSessionOption(id: id, arg: 'scroll-style') ?? '';
ffi(id).canvasModel.setScrollStyle(scrollStyle);
var displays = <Widget>[]; var displays = <Widget>[];
final pi = ffi(id).ffiModel.pi; final pi = ffi(id).ffiModel.pi;
final image = ffi(id).ffiModel.getConnectionImage(); final image = ffi(id).ffiModel.getConnectionImage();
@ -1031,7 +1036,7 @@ void showOptions(String id, OverlayDialogManager dialogManager) async {
Divider(color: MyTheme.border), Divider(color: MyTheme.border),
getRadio('Scrollbar', 'scrollbar', scrollStyle, setScrollStyle), getRadio('Scrollbar', 'scrollbar', scrollStyle, setScrollStyle),
getRadio( getRadio(
'ScrollMouse', 'scrollmouse', scrollStyle, setScrollStyle), 'ScrollAuto', 'scrollauto', scrollStyle, setScrollStyle),
Divider(color: MyTheme.border), Divider(color: MyTheme.border),
getRadio('Good image quality', 'best', quality, setQuality), getRadio('Good image quality', 'best', quality, setQuality),
getRadio('Balanced', 'balanced', quality, setQuality), getRadio('Balanced', 'balanced', quality, setQuality),

View File

@ -434,10 +434,14 @@ class ImageModel with ChangeNotifier {
enum ScrollStyle { enum ScrollStyle {
scrollbar, scrollbar,
scrollmouse, scrollauto,
} }
class CanvasModel with ChangeNotifier { class CanvasModel with ChangeNotifier {
// scroll offset x percent
double _scrollX = 0.0;
// scroll offset y percent
double _scrollY = 0.0;
double _x = 0; double _x = 0;
double _y = 0; double _y = 0;
double _scale = 1.0; double _scale = 1.0;
@ -454,6 +458,14 @@ class CanvasModel with ChangeNotifier {
double get scale => _scale; double get scale => _scale;
ScrollStyle get scrollStyle => _scrollStyle; ScrollStyle get scrollStyle => _scrollStyle;
setScrollPercent(double x, double y) {
_scrollX = x;
_scrollY = y;
}
double get scrollX => _scrollX;
double get scrollY => _scrollY;
set tabBarHeight(double h) => _tabBarHeight = h; set tabBarHeight(double h) => _tabBarHeight = h;
double get tabBarHeight => _tabBarHeight; double get tabBarHeight => _tabBarHeight;
@ -462,11 +474,8 @@ class CanvasModel with ChangeNotifier {
if (s == null) { if (s == null) {
return; return;
} }
final size = MediaQueryData.fromWindow(ui.window).size; final s1 = size.width / (parent.target?.ffiModel.display.width ?? 720);
final canvasWidth = size.width; final s2 = size.height / (parent.target?.ffiModel.display.height ?? 1280);
final canvasHeight = size.height - _tabBarHeight;
final s1 = canvasWidth / (parent.target?.ffiModel.display.width ?? 720);
final s2 = canvasHeight / (parent.target?.ffiModel.display.height ?? 1280);
// Closure to perform shrink operation. // Closure to perform shrink operation.
final shrinkOp = () { final shrinkOp = () {
final s = s1 < s2 ? s1 : s2; final s = s1 < s2 ? s1 : s2;
@ -476,7 +485,7 @@ class CanvasModel with ChangeNotifier {
}; };
// Closure to perform stretch operation. // Closure to perform stretch operation.
final stretchOp = () { final stretchOp = () {
final s = s1 > s2 ? s1 : s2; final s = s1 < s2 ? s1 : s2;
if (s > 1) { if (s > 1) {
_scale = s; _scale = s;
} }
@ -485,31 +494,39 @@ class CanvasModel with ChangeNotifier {
final defaultOp = () { final defaultOp = () {
_scale = 1.0; _scale = 1.0;
}; };
// // On desktop, shrink is the default behavior.
// if (isDesktop) {
// shrinkOp();
// } else {
defaultOp();
// }
if (s == 'shrink') { if (s == 'shrink') {
shrinkOp(); shrinkOp();
} else if (s == 'stretch') { } else if (s == 'stretch') {
stretchOp(); stretchOp();
} else {
// On desktop, shrink is the default behavior.
if (isDesktop) {
shrinkOp();
} else {
defaultOp();
} }
}
_x = (canvasWidth - getDisplayWidth() * _scale) / 2; _x = (size.width - getDisplayWidth() * _scale) / 2;
_y = (canvasHeight - getDisplayHeight() * _scale) / 2; _y = (size.height - getDisplayHeight() * _scale) / 2;
notifyListeners(); notifyListeners();
} }
void updateScrollStyle() async { updateScrollStyle() async {
final s = await bind.getSessionOption(id: id, arg: 'scroll-style'); final s = await bind.getSessionOption(id: id, arg: 'scroll-style');
if (s == 'scrollmouse') { setScrollStyle(s);
_scrollStyle = ScrollStyle.scrollmouse; notifyListeners();
}
setScrollStyle(String? style) {
if (style == 'scrollauto') {
_scrollStyle = ScrollStyle.scrollauto;
} else { } else {
_scrollStyle = ScrollStyle.scrollbar; _scrollStyle = ScrollStyle.scrollbar;
_scrollX = 0.0;
_scrollY = 0.0;
} }
notifyListeners();
} }
void update(double x, double y, double scale) { void update(double x, double y, double scale) {
@ -527,28 +544,30 @@ class CanvasModel with ChangeNotifier {
return parent.target?.ffiModel.display.height ?? 720; return parent.target?.ffiModel.display.height ?? 720;
} }
Size get size {
final size = MediaQueryData.fromWindow(ui.window).size;
return Size(size.width, size.height - _tabBarHeight);
}
void moveDesktopMouse(double x, double y) { void moveDesktopMouse(double x, double y) {
// On mobile platforms, move the canvas with the cursor. // On mobile platforms, move the canvas with the cursor.
if (!isDesktop) { //if (!isDesktop) {
final size = MediaQueryData.fromWindow(ui.window).size;
final canvasWidth = size.width;
final canvasHeight = size.height - _tabBarHeight;
final dw = getDisplayWidth() * _scale; final dw = getDisplayWidth() * _scale;
final dh = getDisplayHeight() * _scale; final dh = getDisplayHeight() * _scale;
var dxOffset = 0; var dxOffset = 0;
var dyOffset = 0; var dyOffset = 0;
if (dw > canvasWidth) { if (dw > size.width) {
dxOffset = (x - dw * (x / canvasWidth) - _x).toInt(); dxOffset = (x - dw * (x / size.width) - _x).toInt();
} }
if (dh > canvasHeight) { if (dh > size.height) {
dyOffset = (y - dh * (y / canvasHeight) - _y).toInt(); dyOffset = (y - dh * (y / size.height) - _y).toInt();
} }
_x += dxOffset; _x += dxOffset;
_y += dyOffset; _y += dyOffset;
if (dxOffset != 0 || dyOffset != 0) { if (dxOffset != 0 || dyOffset != 0) {
notifyListeners(); notifyListeners();
} }
} //}
parent.target?.cursorModel.moveLocal(x, y); parent.target?.cursorModel.moveLocal(x, y);
} }
@ -1106,13 +1125,23 @@ class FFI {
canvasModel.moveDesktopMouse(x, y); canvasModel.moveDesktopMouse(x, y);
} }
final d = ffiModel.display; final d = ffiModel.display;
if (canvasModel.scrollStyle == ScrollStyle.scrollbar) {
final imageWidth = d.width * canvasModel.scale;
final imageHeight = d.height * canvasModel.scale;
x += imageWidth * canvasModel.scrollX;
y += imageHeight * canvasModel.scrollY;
} else {
x -= canvasModel.x; x -= canvasModel.x;
y -= canvasModel.y; y -= canvasModel.y;
}
if (!isMove && (x < 0 || x > d.width || y < 0 || y > d.height)) { if (!isMove && (x < 0 || x > d.width || y < 0 || y > d.height)) {
return; return;
} }
x /= canvasModel.scale; x /= canvasModel.scale;
y /= canvasModel.scale; y /= canvasModel.scale;
x += d.x; x += d.x;
y += d.y; y += d.y;
if (type != '') { if (type != '') {