fix: long press auto-scroll speed on mobile (#1191)
* fix: long press auto-scroll speed on mobile When long pressing and dragging on mobile, auto-scroll was too fast because cursor drag mode used Duration.zero (instant) instead of animated scrolling, and the proxy rect was a large centered square triggering in both directions. - Add AxisDirection.down handling in auto_scroller for directional proxy rects extending downward from cursor position - Add cursor drag mode case in scroll_service_widget with direction detection based on cursor movement relative to last selection - Include cursor mode in isDragOperation for animated scroll duration - Pass dragMode in Android long press selectionExtraInfo so scroll service can detect cursor drag on Android * fix: correct auto-scroller test for downward scroll rect
This commit is contained in:
parent
9bb1ca1fc5
commit
99e7e1efa2
4 changed files with 30 additions and 7 deletions
|
|
@ -50,6 +50,13 @@ class AutoScroller extends EdgeDraggingAutoScroller
|
|||
);
|
||||
}
|
||||
|
||||
if (direction != null && direction == AxisDirection.down) {
|
||||
return startAutoScrollIfNecessary(
|
||||
Rect.fromLTWH(offset.dx, offset.dy, 1, edgeOffset),
|
||||
duration: duration,
|
||||
);
|
||||
}
|
||||
|
||||
final dragTarget = Rect.fromCenter(
|
||||
center: offset,
|
||||
width: edgeOffset,
|
||||
|
|
|
|||
|
|
@ -121,6 +121,16 @@ class _ScrollServiceWidgetState extends State<ScrollServiceWidget>
|
|||
direction = AxisDirection.down;
|
||||
break;
|
||||
|
||||
case 'MobileSelectionDragMode.cursor':
|
||||
targetRect = selectionRects.last;
|
||||
if (lastSelection != null) {
|
||||
final isMovingUp = selection.end.path < lastSelection!.end.path ||
|
||||
(selection.end.path.equals(lastSelection!.end.path) &&
|
||||
selection.end.offset < lastSelection!.end.offset);
|
||||
direction = isMovingUp ? AxisDirection.up : AxisDirection.down;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
targetRect = selectionRects.last;
|
||||
|
||||
|
|
@ -146,7 +156,8 @@ class _ScrollServiceWidgetState extends State<ScrollServiceWidget>
|
|||
(dragMode.toString() ==
|
||||
'MobileSelectionDragMode.leftSelectionHandle' ||
|
||||
dragMode.toString() ==
|
||||
'MobileSelectionDragMode.rightSelectionHandle');
|
||||
'MobileSelectionDragMode.rightSelectionHandle' ||
|
||||
dragMode.toString() == 'MobileSelectionDragMode.cursor');
|
||||
|
||||
// Use animation for drag operations, instant for others
|
||||
final scrollDuration =
|
||||
|
|
|
|||
|
|
@ -787,6 +787,7 @@ class _MobileSelectionServiceWidgetState
|
|||
selection,
|
||||
reason: SelectionUpdateReason.uiEvent,
|
||||
extraInfo: {
|
||||
selectionDragModeKey: dragMode,
|
||||
selectionExtraInfoDisableFloatingToolbar: true,
|
||||
},
|
||||
);
|
||||
|
|
@ -835,6 +836,7 @@ class _MobileSelectionServiceWidgetState
|
|||
newSelection,
|
||||
reason: SelectionUpdateReason.uiEvent,
|
||||
extraInfo: {
|
||||
selectionDragModeKey: dragMode,
|
||||
selectionExtraInfoDisableFloatingToolbar: true,
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -102,14 +102,17 @@ void main() {
|
|||
|
||||
expect(scroller.capturedRect, isNotNull);
|
||||
|
||||
// For AxisDirection.down the generic Rect.fromCenter path is used.
|
||||
// For AxisDirection.down the rect starts at offset and extends downward.
|
||||
expect(
|
||||
scroller.capturedRect!.center,
|
||||
offset,
|
||||
reason:
|
||||
'right handle proxy rect should be centered on the handle offset',
|
||||
scroller.capturedRect!.top,
|
||||
offset.dy,
|
||||
reason: 'proxy rect should start at the handle position',
|
||||
);
|
||||
expect(
|
||||
scroller.capturedRect!.bottom,
|
||||
offset.dy + edgeOffset,
|
||||
reason: 'proxy rect should extend edgeOffset pixels BELOW the handle',
|
||||
);
|
||||
expect(scroller.capturedRect!.width, edgeOffset);
|
||||
expect(scroller.capturedRect!.height, edgeOffset);
|
||||
},
|
||||
);
|
||||
|
|
|
|||
Loading…
Reference in a new issue