Commit b0ee29d7 authored by Andrew Wilson's avatar Andrew Wilson Committed by GitHub

Fix _DragAvatar to display in the proper position for Overlays whose...

Fix _DragAvatar to display in the proper position for Overlays whose Point.origin is not the global Point.origin. (#7223)
parent 1272e053
......@@ -267,7 +267,7 @@ class _DraggableState<T> extends State<Draggable<T>> {
_activeCount += 1;
});
final _DragAvatar<T> avatar = new _DragAvatar<T>(
overlay: Overlay.of(context, debugRequiredFor: config),
overlayState: Overlay.of(context, debugRequiredFor: config),
data: config.data,
initialPosition: position,
dragStartPoint: dragStartPoint,
......@@ -406,7 +406,7 @@ typedef void _OnDragEnd(Velocity velocity, Offset offset, bool wasAccepted);
// eeding this object pointer events even after it has been disposed.
class _DragAvatar<T> extends Drag {
_DragAvatar({
OverlayState overlay,
this.overlayState,
this.data,
Point initialPosition,
this.dragStartPoint: Point.origin,
......@@ -414,11 +414,11 @@ class _DragAvatar<T> extends Drag {
this.feedbackOffset: Offset.zero,
this.onDragEnd
}) {
assert(overlay != null);
assert(overlayState != null);
assert(dragStartPoint != null);
assert(feedbackOffset != null);
_entry = new OverlayEntry(builder: _build);
overlay.insert(_entry);
overlayState.insert(_entry);
_position = initialPosition;
updateDrag(initialPosition);
}
......@@ -428,6 +428,7 @@ class _DragAvatar<T> extends Drag {
final Widget feedback;
final Offset feedbackOffset;
final _OnDragEnd onDragEnd;
final OverlayState overlayState;
_DragTargetState<T> _activeTarget;
List<_DragTargetState<T>> _enteredTargets = <_DragTargetState<T>>[];
......@@ -525,9 +526,11 @@ class _DragAvatar<T> extends Drag {
}
Widget _build(BuildContext context) {
RenderBox box = overlayState.context.findRenderObject();
Point overlayTopLeft = box.localToGlobal(Point.origin);
return new Positioned(
left: _lastOffset.dx,
top: _lastOffset.dy,
left: _lastOffset.dx - overlayTopLeft.x,
top: _lastOffset.dy - overlayTopLeft.y,
child: new IgnorePointer(
child: feedback
)
......
......@@ -1223,6 +1223,82 @@ void main() {
await tester.tap(find.text('X'));
expect(events, equals(<String>['tap']));
});
testWidgets('Drag feedback with child anchor positions correctly', (WidgetTester tester) async {
await _testChildAnchorFeedbackPosition(tester: tester);
});
testWidgets('Drag feedback with child anchor within a non-global Overlay positions correctly', (WidgetTester tester) async {
await _testChildAnchorFeedbackPosition(tester: tester, left: 100.0, top: 100.0);
});
}
Future<Null> _testChildAnchorFeedbackPosition({WidgetTester tester, double top: 0.0, double left: 0.0}) async {
List<int> accepted = <int>[];
int dragStartedCount = 0;
await tester.pumpWidget(new Stack(children: <Widget>[
new Positioned(
left: left,
top: top,
right: 0.0,
bottom: 0.0,
child: new MaterialApp(
home: new Column(
children: <Widget>[
new Draggable<int>(
data: 1,
child: new Text('Source'),
feedback: new Text('Dragging'),
onDragStarted: () {
++dragStartedCount;
},
),
new DragTarget<int>(
builder: (BuildContext context, List<int> data, List<dynamic> rejects) {
return new Container(height: 100.0, child: new Text('Target'));
},
onAccept: (int data) {
accepted.add(data);
}
),
]
)
)
)
]));
expect(accepted, isEmpty);
expect(find.text('Source'), findsOneWidget);
expect(find.text('Dragging'), findsNothing);
expect(find.text('Target'), findsOneWidget);
expect(dragStartedCount, 0);
Point firstLocation = tester.getCenter(find.text('Source'));
TestGesture gesture = await tester.startGesture(firstLocation, pointer: 7);
await tester.pump();
expect(accepted, isEmpty);
expect(find.text('Source'), findsOneWidget);
expect(find.text('Dragging'), findsOneWidget);
expect(find.text('Target'), findsOneWidget);
expect(dragStartedCount, 1);
Point secondLocation = tester.getBottomRight(find.text('Target'));
await gesture.moveTo(secondLocation);
await tester.pump();
expect(accepted, isEmpty);
expect(find.text('Source'), findsOneWidget);
expect(find.text('Dragging'), findsOneWidget);
expect(find.text('Target'), findsOneWidget);
expect(dragStartedCount, 1);
Point feedbackTopLeft = tester.getTopLeft(find.text('Dragging'));
Point sourceTopLeft = tester.getTopLeft(find.text('Source'));
Offset dragOffset = secondLocation - firstLocation;
expect(feedbackTopLeft, equals(sourceTopLeft + dragOffset));
}
class DragTargetData { }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment