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
a82b8963
Commit
a82b8963
authored
Feb 09, 2016
by
Ian Hickson
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1741 from Hixie/drags
Draggable: childWhenDragging, maxSimultaneousDrags
parents
02d23e0a
c56d3788
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
166 additions
and
36 deletions
+166
-36
drag_and_drop.dart
examples/widgets/drag_and_drop.dart
+117
-26
drag_target.dart
packages/flutter/lib/src/widgets/drag_target.dart
+49
-10
No files found.
examples/widgets/drag_and_drop.dart
View file @
a82b8963
...
...
@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:math'
as
math
;
import
'dart:ui'
as
ui
;
import
'package:flutter/material.dart'
;
import
'package:flutter/painting.dart'
;
import
'package:flutter/rendering.dart'
;
...
...
@@ -22,7 +25,7 @@ class ExampleDragTargetState extends State<ExampleDragTarget> {
Widget
build
(
BuildContext
context
)
{
return
new
DragTarget
<
Color
>(
onAccept:
_handleAccept
,
builder:
(
BuildContext
context
,
List
<
Color
>
data
,
_
)
{
builder:
(
BuildContext
context
,
List
<
Color
>
data
,
List
<
Color
>
rejectedData
)
{
return
new
Container
(
height:
100.0
,
margin:
new
EdgeDims
.
all
(
10.0
),
...
...
@@ -129,7 +132,83 @@ class ExampleDragSource extends StatelessComponent {
}
}
class
DragAndDropApp
extends
StatelessComponent
{
class
DashOutlineCirclePainter
extends
CustomPainter
{
const
DashOutlineCirclePainter
();
static
const
int
segments
=
17
;
static
const
double
deltaTheta
=
math
.
PI
*
2
/
segments
;
// radians
static
const
double
segmentArc
=
deltaTheta
/
2.0
;
// radians
static
const
double
startOffset
=
1.0
;
// radians
void
paint
(
Canvas
canvas
,
Size
size
)
{
final
double
radius
=
size
.
shortestSide
/
2.0
;
final
Paint
paint
=
new
Paint
()
..
color
=
const
Color
(
0xFF000000
)
..
style
=
ui
.
PaintingStyle
.
stroke
..
strokeWidth
=
radius
/
10.0
;
final
Path
path
=
new
Path
();
final
Rect
box
=
Point
.
origin
&
size
;
for
(
double
theta
=
0.0
;
theta
<
math
.
PI
*
2.0
;
theta
+=
deltaTheta
)
path
.
addArc
(
box
,
theta
+
startOffset
,
segmentArc
);
canvas
.
drawPath
(
path
,
paint
);
}
bool
shouldRepaint
(
DashOutlineCirclePainter
oldPainter
)
=>
false
;
}
class
MovableBall
extends
StatelessComponent
{
MovableBall
(
this
.
position
,
this
.
ballPosition
,
this
.
callback
);
final
int
position
;
final
int
ballPosition
;
final
ValueChanged
<
int
>
callback
;
static
const
double
kBallSize
=
50.0
;
Widget
build
(
BuildContext
context
)
{
Widget
ball
=
new
DefaultTextStyle
(
style:
Theme
.
of
(
context
).
text
.
body1
.
copyWith
(
textAlign:
TextAlign
.
center
,
color:
Colors
.
white
),
child:
new
Dot
(
color:
Colors
.
blue
[
700
],
size:
kBallSize
,
child:
new
Center
(
child:
new
Text
(
'BALL'
))
)
);
Widget
dashedBall
=
new
Container
(
width:
kBallSize
,
height:
kBallSize
,
child:
new
CustomPaint
(
painter:
const
DashOutlineCirclePainter
()
)
);
if
(
position
==
ballPosition
)
{
return
new
Draggable
<
bool
>(
data:
true
,
child:
ball
,
childWhenDragging:
dashedBall
,
feedback:
ball
,
maxSimultaneousDrags:
1
);
}
else
{
return
new
DragTarget
<
bool
>(
onAccept:
(
bool
data
)
{
callback
(
position
);
},
builder:
(
BuildContext
context
,
List
<
bool
>
accepted
,
List
<
bool
>
rejected
)
{
return
dashedBall
;
}
);
}
}
}
class
DragAndDropApp
extends
StatefulComponent
{
DragAndDropAppState
createState
()
=>
new
DragAndDropAppState
();
}
class
DragAndDropAppState
extends
State
<
DragAndDropApp
>
{
int
position
=
1
;
void
moveBall
(
int
newPosition
)
{
setState
(()
{
position
=
newPosition
;
});
}
Widget
build
(
BuildContext
context
)
{
return
new
Scaffold
(
toolBar:
new
ToolBar
(
...
...
@@ -137,30 +216,32 @@ class DragAndDropApp extends StatelessComponent {
),
body:
new
Column
(
children:
<
Widget
>[
new
Flexible
(
child:
new
Row
(
children:
<
Widget
>[
new
ExampleDragSource
(
color:
const
Color
(
0xFFFFF000
),
under:
true
,
heavy:
false
,
child:
new
Text
(
'under'
)
),
new
ExampleDragSource
(
color:
const
Color
(
0xFF0FFF00
),
under:
false
,
heavy:
true
,
child:
new
Text
(
'long-press above'
)
),
new
ExampleDragSource
(
color:
const
Color
(
0xFF00FFF0
),
under:
false
,
heavy:
false
,
child:
new
Text
(
'above'
)
),
],
alignItems:
FlexAlignItems
.
center
,
justifyContent:
FlexJustifyContent
.
spaceAround
)),
new
Flexible
(
child:
new
Row
(
children:
<
Widget
>[
new
ExampleDragSource
(
color:
Colors
.
yellow
[
300
],
under:
true
,
heavy:
false
,
child:
new
Text
(
'under'
)
),
new
ExampleDragSource
(
color:
Colors
.
green
[
300
],
under:
false
,
heavy:
true
,
child:
new
Text
(
'long-press above'
)
),
new
ExampleDragSource
(
color:
Colors
.
indigo
[
300
],
under:
false
,
heavy:
false
,
child:
new
Text
(
'above'
)
),
],
alignItems:
FlexAlignItems
.
center
,
justifyContent:
FlexJustifyContent
.
spaceAround
)
),
new
Flexible
(
child:
new
Row
(
children:
<
Widget
>[
...
...
@@ -171,6 +252,16 @@ class DragAndDropApp extends StatelessComponent {
]
)
),
new
Flexible
(
child:
new
Row
(
children:
<
Widget
>[
new
MovableBall
(
1
,
position
,
moveBall
),
new
MovableBall
(
2
,
position
,
moveBall
),
new
MovableBall
(
3
,
position
,
moveBall
),
],
justifyContent:
FlexJustifyContent
.
spaceAround
)
),
]
)
);
...
...
packages/flutter/lib/src/widgets/drag_target.dart
View file @
a82b8963
...
...
@@ -44,18 +44,28 @@ abstract class DraggableBase<T> extends StatefulComponent {
Key
key
,
this
.
data
,
this
.
child
,
this
.
childWhenDragging
,
this
.
feedback
,
this
.
feedbackOffset
:
Offset
.
zero
,
this
.
dragAnchor
:
DragAnchor
.
child
this
.
dragAnchor
:
DragAnchor
.
child
,
this
.
maxSimultaneousDrags
})
:
super
(
key:
key
)
{
assert
(
child
!=
null
);
assert
(
feedback
!=
null
);
assert
(
maxSimultaneousDrags
==
null
||
maxSimultaneousDrags
>
0
);
}
final
T
data
;
final
Widget
child
;
/// The widget to show when a drag is under way.
/// The widget to show instead of [child] when a drag is under way.
///
/// If this is null, then [child] will be used instead (and so the
/// drag source representation will change while a drag is under
/// way).
final
Widget
childWhenDragging
;
/// The widget to show under the pointer when a drag is under way.
final
Widget
feedback
;
/// The feedbackOffset can be used to set the hit test target point for the
...
...
@@ -66,6 +76,11 @@ abstract class DraggableBase<T> extends StatefulComponent {
/// Where this widget should be anchored during a drag.
final
DragAnchor
dragAnchor
;
/// How many simultaneous drags to support. When null, no limit is applied.
/// Set this to 1 if you want to only allow the drag source to have one item
/// dragged at a time.
final
int
maxSimultaneousDrags
;
/// Should return a GestureRecognizer instance that is configured to call the starter
/// argument when the drag is to begin. The arena for the pointer must not yet have
/// resolved at the time that the callback is invoked, because the draggable itself
...
...
@@ -81,16 +96,20 @@ class Draggable<T> extends DraggableBase<T> {
Key
key
,
T
data
,
Widget
child
,
Widget
childWhenDragging
,
Widget
feedback
,
Offset
feedbackOffset:
Offset
.
zero
,
DragAnchor
dragAnchor:
DragAnchor
.
child
DragAnchor
dragAnchor:
DragAnchor
.
child
,
int
maxSimultaneousDrags
})
:
super
(
key:
key
,
data:
data
,
child:
child
,
childWhenDragging:
childWhenDragging
,
feedback:
feedback
,
feedbackOffset:
feedbackOffset
,
dragAnchor:
dragAnchor
dragAnchor:
dragAnchor
,
maxSimultaneousDrags:
maxSimultaneousDrags
);
GestureRecognizer
createRecognizer
(
PointerRouter
router
,
DragStartCallback
starter
)
{
...
...
@@ -108,16 +127,20 @@ class LongPressDraggable<T> extends DraggableBase<T> {
Key
key
,
T
data
,
Widget
child
,
Widget
childWhenDragging
,
Widget
feedback
,
Offset
feedbackOffset:
Offset
.
zero
,
DragAnchor
dragAnchor:
DragAnchor
.
child
DragAnchor
dragAnchor:
DragAnchor
.
child
,
int
maxSimultaneousDrags
})
:
super
(
key:
key
,
data:
data
,
child:
child
,
childWhenDragging:
childWhenDragging
,
feedback:
feedback
,
feedbackOffset:
feedbackOffset
,
dragAnchor:
dragAnchor
dragAnchor:
dragAnchor
,
maxSimultaneousDrags:
maxSimultaneousDrags
);
GestureRecognizer
createRecognizer
(
PointerRouter
router
,
DragStartCallback
starter
)
{
...
...
@@ -144,6 +167,7 @@ class _DraggableState<T> extends State<DraggableBase<T>> implements GestureArena
GestureRecognizer
_recognizer
;
Map
<
int
,
GestureArenaEntry
>
_activePointers
=
<
int
,
GestureArenaEntry
>{};
int
_activeCount
=
0
;
void
_routePointer
(
PointerEvent
event
)
{
_activePointers
[
event
.
pointer
]
=
Gesturer
.
instance
.
gestureArena
.
add
(
event
.
pointer
,
this
);
...
...
@@ -159,6 +183,8 @@ class _DraggableState<T> extends State<DraggableBase<T>> implements GestureArena
}
void
_startDrag
(
Point
position
,
int
pointer
)
{
if
(
config
.
maxSimultaneousDrags
!=
null
&&
_activeCount
>=
config
.
maxSimultaneousDrags
)
return
;
assert
(
_activePointers
.
containsKey
(
pointer
));
_activePointers
[
pointer
].
resolve
(
GestureDisposition
.
accepted
);
Point
dragStartPoint
;
...
...
@@ -171,6 +197,9 @@ class _DraggableState<T> extends State<DraggableBase<T>> implements GestureArena
dragStartPoint
=
Point
.
origin
;
break
;
}
setState
(()
{
_activeCount
+=
1
;
});
new
_DragAvatar
<
T
>(
pointer:
pointer
,
router:
router
,
...
...
@@ -179,14 +208,20 @@ class _DraggableState<T> extends State<DraggableBase<T>> implements GestureArena
initialPosition:
position
,
dragStartPoint:
dragStartPoint
,
feedback:
config
.
feedback
,
feedbackOffset:
config
.
feedbackOffset
feedbackOffset:
config
.
feedbackOffset
,
onDragEnd:
()
{
_activeCount
-=
1
;
}
);
}
Widget
build
(
BuildContext
context
)
{
final
bool
canDrag
=
config
.
maxSimultaneousDrags
==
null
||
_activeCount
<
config
.
maxSimultaneousDrags
;
final
bool
showChild
=
_activeCount
==
0
||
config
.
childWhenDragging
==
null
;
return
new
Listener
(
onPointerDown:
_routePointer
,
child:
config
.
child
onPointerDown:
canDrag
?
_routePointer
:
null
,
child:
showChild
?
config
.
child
:
config
.
childWhenDragging
);
}
}
...
...
@@ -278,7 +313,8 @@ class _DragAvatar<T> {
Point
initialPosition
,
this
.
dragStartPoint
:
Point
.
origin
,
this
.
feedback
,
this
.
feedbackOffset
:
Offset
.
zero
this
.
feedbackOffset
:
Offset
.
zero
,
this
.
onDragEnd
})
{
assert
(
pointer
!=
null
);
assert
(
router
!=
null
);
...
...
@@ -297,6 +333,7 @@ class _DragAvatar<T> {
final
Point
dragStartPoint
;
final
Widget
feedback
;
final
Offset
feedbackOffset
;
final
VoidCallback
onDragEnd
;
_DragTargetState
_activeTarget
;
bool
_activeTargetWillAcceptDrop
=
false
;
...
...
@@ -353,6 +390,8 @@ class _DragAvatar<T> {
_entry
.
remove
();
_entry
=
null
;
router
.
removeRoute
(
pointer
,
handleEvent
);
if
(
onDragEnd
!=
null
)
onDragEnd
();
}
Widget
_build
(
BuildContext
context
)
{
...
...
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