Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
c0c22777
Commit
c0c22777
authored
Feb 13, 2016
by
Ian Hickson
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1849 from Hixie/drag-horiz
Horizontal and Vertical Draggables
parents
6c2ab9d3
19a2f5ef
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
345 additions
and
0 deletions
+345
-0
multidrag.dart
packages/flutter/lib/src/gestures/multidrag.dart
+55
-0
drag_target.dart
packages/flutter/lib/src/widgets/drag_target.dart
+64
-0
draggable_test.dart
packages/flutter/test/widget/draggable_test.dart
+226
-0
No files found.
packages/flutter/lib/src/gestures/multidrag.dart
View file @
c0c22777
...
...
@@ -252,6 +252,61 @@ class ImmediateMultiDragGestureRecognizer extends MultiDragGestureRecognizer<_Im
}
}
class
_HorizontalPointerState
extends
MultiDragPointerState
{
_HorizontalPointerState
(
Point
initialPosition
)
:
super
(
initialPosition
);
void
checkForResolutionAfterMove
()
{
assert
(
pendingDelta
!=
null
);
if
(
pendingDelta
.
dx
.
abs
()
>
kTouchSlop
)
resolve
(
GestureDisposition
.
accepted
);
}
void
accepted
(
GestureMultiDragStartCallback
starter
)
{
starter
(
initialPosition
);
}
}
class
HorizontalMultiDragGestureRecognizer
extends
MultiDragGestureRecognizer
<
_HorizontalPointerState
>
{
HorizontalMultiDragGestureRecognizer
({
PointerRouter
pointerRouter
,
GestureArena
gestureArena
,
GestureMultiDragStartCallback
onStart
})
:
super
(
pointerRouter:
pointerRouter
,
gestureArena:
gestureArena
,
onStart:
onStart
);
_HorizontalPointerState
createNewPointerState
(
PointerDownEvent
event
)
{
return
new
_HorizontalPointerState
(
event
.
position
);
}
}
class
_VerticalPointerState
extends
MultiDragPointerState
{
_VerticalPointerState
(
Point
initialPosition
)
:
super
(
initialPosition
);
void
checkForResolutionAfterMove
()
{
assert
(
pendingDelta
!=
null
);
if
(
pendingDelta
.
dy
.
abs
()
>
kTouchSlop
)
resolve
(
GestureDisposition
.
accepted
);
}
void
accepted
(
GestureMultiDragStartCallback
starter
)
{
starter
(
initialPosition
);
}
}
class
VerticalMultiDragGestureRecognizer
extends
MultiDragGestureRecognizer
<
_VerticalPointerState
>
{
VerticalMultiDragGestureRecognizer
({
PointerRouter
pointerRouter
,
GestureArena
gestureArena
,
GestureMultiDragStartCallback
onStart
})
:
super
(
pointerRouter:
pointerRouter
,
gestureArena:
gestureArena
,
onStart:
onStart
);
_VerticalPointerState
createNewPointerState
(
PointerDownEvent
event
)
{
return
new
_VerticalPointerState
(
event
.
position
);
}
}
class
_DelayedPointerState
extends
MultiDragPointerState
{
_DelayedPointerState
(
Point
initialPosition
,
Duration
delay
)
:
super
(
initialPosition
)
{
assert
(
delay
!=
null
);
...
...
packages/flutter/lib/src/widgets/drag_target.dart
View file @
c0c22777
...
...
@@ -118,6 +118,70 @@ class Draggable<T> extends DraggableBase<T> {
}
}
/// Makes its child draggable. When competing with other gestures,
/// this will only start the drag horizontally.
class
HorizontalDraggable
<
T
>
extends
DraggableBase
<
T
>
{
HorizontalDraggable
({
Key
key
,
T
data
,
Widget
child
,
Widget
childWhenDragging
,
Widget
feedback
,
Offset
feedbackOffset:
Offset
.
zero
,
DragAnchor
dragAnchor:
DragAnchor
.
child
,
int
maxSimultaneousDrags
})
:
super
(
key:
key
,
data:
data
,
child:
child
,
childWhenDragging:
childWhenDragging
,
feedback:
feedback
,
feedbackOffset:
feedbackOffset
,
dragAnchor:
dragAnchor
,
maxSimultaneousDrags:
maxSimultaneousDrags
);
MultiDragGestureRecognizer
createRecognizer
(
PointerRouter
router
,
GestureArena
arena
,
GestureMultiDragStartCallback
starter
)
{
return
new
HorizontalMultiDragGestureRecognizer
(
pointerRouter:
router
,
gestureArena:
arena
,
onStart:
starter
);
}
}
/// Makes its child draggable. When competing with other gestures,
/// this will only start the drag vertically.
class
VerticalDraggable
<
T
>
extends
DraggableBase
<
T
>
{
VerticalDraggable
({
Key
key
,
T
data
,
Widget
child
,
Widget
childWhenDragging
,
Widget
feedback
,
Offset
feedbackOffset:
Offset
.
zero
,
DragAnchor
dragAnchor:
DragAnchor
.
child
,
int
maxSimultaneousDrags
})
:
super
(
key:
key
,
data:
data
,
child:
child
,
childWhenDragging:
childWhenDragging
,
feedback:
feedback
,
feedbackOffset:
feedbackOffset
,
dragAnchor:
dragAnchor
,
maxSimultaneousDrags:
maxSimultaneousDrags
);
MultiDragGestureRecognizer
createRecognizer
(
PointerRouter
router
,
GestureArena
arena
,
GestureMultiDragStartCallback
starter
)
{
return
new
VerticalMultiDragGestureRecognizer
(
pointerRouter:
router
,
gestureArena:
arena
,
onStart:
starter
);
}
}
/// Makes its child draggable starting from long press.
class
LongPressDraggable
<
T
>
extends
DraggableBase
<
T
>
{
LongPressDraggable
({
...
...
packages/flutter/test/widget/draggable_test.dart
View file @
c0c22777
...
...
@@ -338,6 +338,232 @@ void main() {
tester
.
dispatchEvent
(
pointer
.
up
(),
firstLocation
);
tester
.
pump
();
expect
(
events
,
equals
(<
String
>[
'drop'
]));
});
});
test
(
'Drag and drop - horizontal and vertical draggables in vertical block'
,
()
{
testWidgets
((
WidgetTester
tester
)
{
TestPointer
pointer
=
new
TestPointer
(
7
);
List
<
String
>
events
=
<
String
>[];
Point
firstLocation
,
secondLocation
,
thirdLocation
;
tester
.
pumpWidget
(
new
MaterialApp
(
routes:
<
String
,
RouteBuilder
>{
'/'
:
(
RouteArguments
args
)
{
return
new
Block
(
children:
<
Widget
>[
new
DragTarget
(
builder:
(
context
,
data
,
rejects
)
{
return
new
Text
(
'Target'
);
},
onAccept:
(
data
)
{
events
.
add
(
'drop
$data
'
);
}
),
new
Container
(
height:
400.0
),
new
HorizontalDraggable
(
data:
1
,
child:
new
Text
(
'H'
),
feedback:
new
Text
(
'Dragging'
)
),
new
VerticalDraggable
(
data:
2
,
child:
new
Text
(
'V'
),
feedback:
new
Text
(
'Dragging'
)
),
new
Container
(
height:
500.0
),
new
Container
(
height:
500.0
),
new
Container
(
height:
500.0
),
new
Container
(
height:
500.0
),
]
);
},
}
));
expect
(
events
,
isEmpty
);
expect
(
tester
.
findText
(
'Target'
),
isNotNull
);
expect
(
tester
.
findText
(
'H'
),
isNotNull
);
expect
(
tester
.
findText
(
'V'
),
isNotNull
);
// vertical draggable drags vertically
expect
(
events
,
isEmpty
);
firstLocation
=
tester
.
getCenter
(
tester
.
findText
(
'V'
));
secondLocation
=
tester
.
getCenter
(
tester
.
findText
(
'Target'
));
tester
.
dispatchEvent
(
pointer
.
down
(
firstLocation
),
firstLocation
);
tester
.
pump
();
tester
.
dispatchEvent
(
pointer
.
move
(
secondLocation
),
firstLocation
);
tester
.
pump
();
tester
.
dispatchEvent
(
pointer
.
up
(),
firstLocation
);
tester
.
pump
();
expect
(
events
,
equals
(<
String
>[
'drop 2'
]));
expect
(
tester
.
getCenter
(
tester
.
findText
(
'Target'
)).
y
,
greaterThan
(
0.0
));
events
.
clear
();
// horizontal draggable drags horizontally
expect
(
events
,
isEmpty
);
firstLocation
=
tester
.
getTopLeft
(
tester
.
findText
(
'H'
));
secondLocation
=
tester
.
getTopRight
(
tester
.
findText
(
'H'
));
thirdLocation
=
tester
.
getCenter
(
tester
.
findText
(
'Target'
));
tester
.
dispatchEvent
(
pointer
.
down
(
firstLocation
),
firstLocation
);
tester
.
pump
();
tester
.
dispatchEvent
(
pointer
.
move
(
secondLocation
),
firstLocation
);
tester
.
pump
();
tester
.
dispatchEvent
(
pointer
.
move
(
thirdLocation
),
firstLocation
);
tester
.
pump
();
tester
.
dispatchEvent
(
pointer
.
up
(),
firstLocation
);
tester
.
pump
();
expect
(
events
,
equals
(<
String
>[
'drop 1'
]));
expect
(
tester
.
getCenter
(
tester
.
findText
(
'Target'
)).
y
,
greaterThan
(
0.0
));
events
.
clear
();
// vertical draggable drags horizontally when there's no competition
// from other gesture detectors
expect
(
events
,
isEmpty
);
firstLocation
=
tester
.
getTopLeft
(
tester
.
findText
(
'V'
));
secondLocation
=
tester
.
getTopRight
(
tester
.
findText
(
'V'
));
thirdLocation
=
tester
.
getCenter
(
tester
.
findText
(
'Target'
));
tester
.
dispatchEvent
(
pointer
.
down
(
firstLocation
),
firstLocation
);
tester
.
pump
();
tester
.
dispatchEvent
(
pointer
.
move
(
secondLocation
),
firstLocation
);
tester
.
pump
();
tester
.
dispatchEvent
(
pointer
.
move
(
thirdLocation
),
firstLocation
);
tester
.
pump
();
tester
.
dispatchEvent
(
pointer
.
up
(),
firstLocation
);
tester
.
pump
();
expect
(
events
,
equals
(<
String
>[
'drop 2'
]));
expect
(
tester
.
getCenter
(
tester
.
findText
(
'Target'
)).
y
,
greaterThan
(
0.0
));
events
.
clear
();
// horizontal draggable doesn't drag vertically when there is competition
// for vertical gestures
expect
(
events
,
isEmpty
);
firstLocation
=
tester
.
getCenter
(
tester
.
findText
(
'H'
));
secondLocation
=
tester
.
getCenter
(
tester
.
findText
(
'Target'
));
tester
.
dispatchEvent
(
pointer
.
down
(
firstLocation
),
firstLocation
);
tester
.
pump
();
tester
.
dispatchEvent
(
pointer
.
move
(
secondLocation
),
firstLocation
);
tester
.
pump
();
// scrolls off screen!
tester
.
dispatchEvent
(
pointer
.
up
(),
firstLocation
);
tester
.
pump
();
expect
(
events
,
equals
(<
String
>[]));
expect
(
tester
.
getCenter
(
tester
.
findText
(
'Target'
)).
y
,
lessThan
(
0.0
));
events
.
clear
();
});
});
test
(
'Drag and drop - horizontal and vertical draggables in horizontal block'
,
()
{
testWidgets
((
WidgetTester
tester
)
{
TestPointer
pointer
=
new
TestPointer
(
7
);
List
<
String
>
events
=
<
String
>[];
Point
firstLocation
,
secondLocation
,
thirdLocation
;
tester
.
pumpWidget
(
new
MaterialApp
(
routes:
<
String
,
RouteBuilder
>{
'/'
:
(
RouteArguments
args
)
{
return
new
Block
(
scrollDirection:
Axis
.
horizontal
,
children:
<
Widget
>[
new
DragTarget
(
builder:
(
context
,
data
,
rejects
)
{
return
new
Text
(
'Target'
);
},
onAccept:
(
data
)
{
events
.
add
(
'drop
$data
'
);
}
),
new
Container
(
width:
400.0
),
new
HorizontalDraggable
(
data:
1
,
child:
new
Text
(
'H'
),
feedback:
new
Text
(
'Dragging'
)
),
new
VerticalDraggable
(
data:
2
,
child:
new
Text
(
'V'
),
feedback:
new
Text
(
'Dragging'
)
),
new
Container
(
width:
500.0
),
new
Container
(
width:
500.0
),
new
Container
(
width:
500.0
),
new
Container
(
width:
500.0
),
]
);
},
}
));
expect
(
events
,
isEmpty
);
expect
(
tester
.
findText
(
'Target'
),
isNotNull
);
expect
(
tester
.
findText
(
'H'
),
isNotNull
);
expect
(
tester
.
findText
(
'V'
),
isNotNull
);
// horizontal draggable drags horizontally
expect
(
events
,
isEmpty
);
firstLocation
=
tester
.
getCenter
(
tester
.
findText
(
'H'
));
secondLocation
=
tester
.
getCenter
(
tester
.
findText
(
'Target'
));
tester
.
dispatchEvent
(
pointer
.
down
(
firstLocation
),
firstLocation
);
tester
.
pump
();
tester
.
dispatchEvent
(
pointer
.
move
(
secondLocation
),
firstLocation
);
tester
.
pump
();
tester
.
dispatchEvent
(
pointer
.
up
(),
firstLocation
);
tester
.
pump
();
expect
(
events
,
equals
(<
String
>[
'drop 1'
]));
expect
(
tester
.
getCenter
(
tester
.
findText
(
'Target'
)).
x
,
greaterThan
(
0.0
));
events
.
clear
();
// vertical draggable drags vertically
expect
(
events
,
isEmpty
);
firstLocation
=
tester
.
getTopLeft
(
tester
.
findText
(
'V'
));
secondLocation
=
tester
.
getBottomLeft
(
tester
.
findText
(
'V'
));
thirdLocation
=
tester
.
getCenter
(
tester
.
findText
(
'Target'
));
tester
.
dispatchEvent
(
pointer
.
down
(
firstLocation
),
firstLocation
);
tester
.
pump
();
tester
.
dispatchEvent
(
pointer
.
move
(
secondLocation
),
firstLocation
);
tester
.
pump
();
tester
.
dispatchEvent
(
pointer
.
move
(
thirdLocation
),
firstLocation
);
tester
.
pump
();
tester
.
dispatchEvent
(
pointer
.
up
(),
firstLocation
);
tester
.
pump
();
expect
(
events
,
equals
(<
String
>[
'drop 2'
]));
expect
(
tester
.
getCenter
(
tester
.
findText
(
'Target'
)).
x
,
greaterThan
(
0.0
));
events
.
clear
();
// horizontal draggable drags vertically when there's no competition
// from other gesture detectors
expect
(
events
,
isEmpty
);
firstLocation
=
tester
.
getTopLeft
(
tester
.
findText
(
'H'
));
secondLocation
=
tester
.
getBottomLeft
(
tester
.
findText
(
'H'
));
thirdLocation
=
tester
.
getCenter
(
tester
.
findText
(
'Target'
));
tester
.
dispatchEvent
(
pointer
.
down
(
firstLocation
),
firstLocation
);
tester
.
pump
();
tester
.
dispatchEvent
(
pointer
.
move
(
secondLocation
),
firstLocation
);
tester
.
pump
();
tester
.
dispatchEvent
(
pointer
.
move
(
thirdLocation
),
firstLocation
);
tester
.
pump
();
tester
.
dispatchEvent
(
pointer
.
up
(),
firstLocation
);
tester
.
pump
();
expect
(
events
,
equals
(<
String
>[
'drop 1'
]));
expect
(
tester
.
getCenter
(
tester
.
findText
(
'Target'
)).
x
,
greaterThan
(
0.0
));
events
.
clear
();
// vertical draggable doesn't drag horizontally when there is competition
// for horizontal gestures
expect
(
events
,
isEmpty
);
firstLocation
=
tester
.
getCenter
(
tester
.
findText
(
'V'
));
secondLocation
=
tester
.
getCenter
(
tester
.
findText
(
'Target'
));
tester
.
dispatchEvent
(
pointer
.
down
(
firstLocation
),
firstLocation
);
tester
.
pump
();
tester
.
dispatchEvent
(
pointer
.
move
(
secondLocation
),
firstLocation
);
tester
.
pump
();
// scrolls off screen!
tester
.
dispatchEvent
(
pointer
.
up
(),
firstLocation
);
tester
.
pump
();
expect
(
events
,
equals
(<
String
>[]));
expect
(
tester
.
getCenter
(
tester
.
findText
(
'Target'
)).
x
,
lessThan
(
0.0
));
events
.
clear
();
});
});
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment