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
46fc8e6a
Commit
46fc8e6a
authored
Aug 17, 2015
by
Adam Barth
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #653 from abarth/drag_target
Add support for drag-and-drop
parents
fca0c3c9
ac0ec322
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
291 additions
and
10 deletions
+291
-10
drag_and_drop.dart
examples/widgets/drag_and_drop.dart
+151
-0
sky_binding.dart
packages/flutter/lib/rendering/sky_binding.dart
+8
-5
widgets.dart
packages/flutter/lib/widgets.dart
+1
-0
drag_target.dart
packages/flutter/lib/widgets/drag_target.dart
+119
-0
framework.dart
packages/flutter/lib/widgets/framework.dart
+12
-5
No files found.
examples/widgets/drag_and_drop.dart
0 → 100644
View file @
46fc8e6a
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:sky'
as
sky
;
import
'package:sky/theme/colors.dart'
as
colors
;
import
'package:sky/widgets.dart'
;
final
double
kTop
=
10.0
+
sky
.
view
.
paddingTop
;
final
double
kLeft
=
10.0
;
class
DragData
{
DragData
(
this
.
text
);
final
String
text
;
}
class
ExampleDragTarget
extends
StatefulComponent
{
String
_text
=
'ready'
;
void
syncFields
(
ExampleDragTarget
source
)
{
}
void
_handleAccept
(
DragData
data
)
{
setState
(()
{
_text
=
data
.
text
;
});
}
Widget
build
()
{
return
new
DragTarget
<
DragData
>(
onAccept:
_handleAccept
,
builder:
(
List
<
DragData
>
data
,
_
)
{
return
new
Container
(
width:
100.0
,
height:
100.0
,
margin:
new
EdgeDims
.
all
(
10.0
),
decoration:
new
BoxDecoration
(
border:
new
Border
.
all
(
width:
3.0
,
color:
data
.
isEmpty
?
colors
.
white
:
colors
.
Blue
[
500
]
),
backgroundColor:
data
.
isEmpty
?
colors
.
Grey
[
500
]
:
colors
.
Green
[
500
]
),
child:
new
Center
(
child:
new
Text
(
_text
)
)
);
}
);
}
}
class
Dot
extends
Component
{
Widget
build
()
{
return
new
Container
(
width:
50.0
,
height:
50.0
,
decoration:
new
BoxDecoration
(
backgroundColor:
colors
.
DeepOrange
[
500
]
)
);
}
}
class
DragAndDropApp
extends
App
{
DragController
_dragController
;
Offset
_displacement
=
Offset
.
zero
;
EventDisposition
_startDrag
(
sky
.
PointerEvent
event
)
{
setState
(()
{
_dragController
=
new
DragController
(
new
DragData
(
"Orange"
));
_dragController
.
update
(
new
Point
(
event
.
x
,
event
.
y
));
_displacement
=
Offset
.
zero
;
});
return
EventDisposition
.
consumed
;
}
EventDisposition
_updateDrag
(
sky
.
PointerEvent
event
)
{
setState
(()
{
_dragController
.
update
(
new
Point
(
event
.
x
,
event
.
y
));
_displacement
+=
new
Offset
(
event
.
dx
,
event
.
dy
);
});
return
EventDisposition
.
consumed
;
}
EventDisposition
_cancelDrag
(
sky
.
PointerEvent
event
)
{
setState
(()
{
_dragController
.
cancel
();
_dragController
=
null
;
});
return
EventDisposition
.
consumed
;
}
EventDisposition
_drop
(
sky
.
PointerEvent
event
)
{
setState
(()
{
_dragController
.
update
(
new
Point
(
event
.
x
,
event
.
y
));
_dragController
.
drop
();
_dragController
=
null
;
_displacement
=
Offset
.
zero
;
});
return
EventDisposition
.
consumed
;
}
Widget
build
()
{
List
<
Widget
>
layers
=
<
Widget
>[
new
Flex
([
new
ExampleDragTarget
(),
new
ExampleDragTarget
(),
new
ExampleDragTarget
(),
new
ExampleDragTarget
(),
]),
new
Positioned
(
top:
kTop
,
left:
kLeft
,
child:
new
Listener
(
onPointerDown:
_startDrag
,
onPointerMove:
_updateDrag
,
onPointerCancel:
_cancelDrag
,
onPointerUp:
_drop
,
child:
new
Dot
()
)
),
];
if
(
_dragController
!=
null
)
{
layers
.
add
(
new
Positioned
(
top:
kTop
+
_displacement
.
dy
,
left:
kLeft
+
_displacement
.
dx
,
child:
new
IgnorePointer
(
child:
new
Opacity
(
opacity:
0.5
,
child:
new
Dot
()
)
)
)
);
}
return
new
Container
(
decoration:
new
BoxDecoration
(
backgroundColor:
colors
.
Pink
[
500
]),
child:
new
Stack
(
layers
)
);
}
}
void
main
(
)
{
runApp
(
new
DragAndDropApp
());
}
packages/flutter/lib/rendering/sky_binding.dart
View file @
46fc8e6a
...
...
@@ -85,9 +85,7 @@ class SkyBinding {
if
(
event
is
sky
.
PointerEvent
)
{
_handlePointerEvent
(
event
);
}
else
if
(
event
is
sky
.
GestureEvent
)
{
HitTestResult
result
=
new
HitTestResult
();
_renderView
.
hitTest
(
result
,
position:
new
Point
(
event
.
x
,
event
.
y
));
dispatchEvent
(
event
,
result
);
dispatchEvent
(
event
,
hitTest
(
new
Point
(
event
.
x
,
event
.
y
)));
}
else
{
for
(
EventListener
e
in
_eventListeners
)
e
(
event
);
...
...
@@ -97,8 +95,7 @@ class SkyBinding {
Map
<
int
,
PointerState
>
_stateForPointer
=
new
Map
<
int
,
PointerState
>();
PointerState
_createStateForPointer
(
sky
.
PointerEvent
event
,
Point
position
)
{
HitTestResult
result
=
new
HitTestResult
();
_renderView
.
hitTest
(
result
,
position:
position
);
HitTestResult
result
=
hitTest
(
position
);
PointerState
state
=
new
PointerState
(
result:
result
,
lastPosition:
position
);
_stateForPointer
[
event
.
pointer
]
=
state
;
return
state
;
...
...
@@ -128,6 +125,12 @@ class SkyBinding {
return
dispatchEvent
(
event
,
state
.
result
);
}
HitTestResult
hitTest
(
Point
position
)
{
HitTestResult
result
=
new
HitTestResult
();
_renderView
.
hitTest
(
result
,
position:
position
);
return
result
;
}
EventDisposition
dispatchEvent
(
sky
.
Event
event
,
HitTestResult
result
)
{
assert
(
result
!=
null
);
EventDisposition
disposition
=
EventDisposition
.
ignored
;
...
...
packages/flutter/lib/widgets.dart
View file @
46fc8e6a
...
...
@@ -14,6 +14,7 @@ export 'widgets/checkbox.dart';
export
'widgets/default_text_style.dart'
;
export
'widgets/dialog.dart'
;
export
'widgets/dismissable.dart'
;
export
'widgets/drag_target.dart'
;
export
'widgets/drawer.dart'
;
export
'widgets/drawer_divider.dart'
;
export
'widgets/drawer_header.dart'
;
...
...
packages/flutter/lib/widgets/drag_target.dart
0 → 100644
View file @
46fc8e6a
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:collection'
;
import
'package:sky/base/hit_test.dart'
;
import
'package:sky/rendering/sky_binding.dart'
;
import
'package:sky/widgets/basic.dart'
;
import
'package:sky/widgets/framework.dart'
;
typedef
bool
DragTargetWillAccept
<
T
>(
T
data
);
typedef
void
DragTargetAccept
<
T
>(
T
data
);
typedef
Widget
DragTargetBuilder
<
T
>(
List
<
T
>
candidateData
,
List
<
dynamic
>
rejectedData
);
class
DragTarget
<
T
>
extends
StatefulComponent
{
DragTarget
({
Key
key
,
this
.
builder
,
this
.
onWillAccept
,
this
.
onAccept
})
:
super
(
key:
key
);
DragTargetBuilder
<
T
>
builder
;
DragTargetWillAccept
<
T
>
onWillAccept
;
DragTargetAccept
<
T
>
onAccept
;
final
List
<
T
>
_candidateData
=
new
List
<
T
>();
final
List
<
dynamic
>
_rejectedData
=
new
List
<
dynamic
>();
void
syncFields
(
DragTarget
source
)
{
builder
=
source
.
builder
;
onWillAccept
=
source
.
onWillAccept
;
onAccept
=
source
.
onAccept
;
}
bool
didEnter
(
dynamic
data
)
{
assert
(!
_candidateData
.
contains
(
data
));
assert
(!
_rejectedData
.
contains
(
data
));
if
(
data
is
T
&&
(
onWillAccept
==
null
||
onWillAccept
(
data
)))
{
setState
(()
{
_candidateData
.
add
(
data
);
});
return
true
;
}
_rejectedData
.
add
(
data
);
return
false
;
}
void
didLeave
(
dynamic
data
)
{
assert
(
_candidateData
.
contains
(
data
)
||
_rejectedData
.
contains
(
data
));
setState
(()
{
_candidateData
.
remove
(
data
);
_rejectedData
.
remove
(
data
);
});
}
void
didDrop
(
dynamic
data
)
{
assert
(
_candidateData
.
contains
(
data
));
setState
(()
{
_candidateData
.
remove
(
data
);
});
if
(
onAccept
!=
null
)
onAccept
(
data
);
}
Widget
build
()
{
return
builder
(
new
UnmodifiableListView
<
T
>(
_candidateData
),
new
UnmodifiableListView
<
dynamic
>(
_rejectedData
));
}
}
class
DragController
{
DragController
(
this
.
data
);
final
dynamic
data
;
DragTarget
_activeTarget
;
bool
_activeTargetWillAcceptDrop
=
false
;
DragTarget
_getDragTarget
(
List
<
HitTestEntry
>
path
)
{
for
(
HitTestEntry
entry
in
path
.
reversed
)
{
for
(
Widget
widget
in
RenderObjectWrapper
.
getWidgetsForRenderObject
(
entry
.
target
))
{
if
(
widget
is
DragTarget
)
return
widget
;
}
}
return
null
;
}
void
update
(
Point
globalPosition
)
{
HitTestResult
result
=
SkyBinding
.
instance
.
hitTest
(
globalPosition
);
DragTarget
target
=
_getDragTarget
(
result
.
path
);
if
(
target
==
_activeTarget
)
return
;
if
(
_activeTarget
!=
null
)
_activeTarget
.
didLeave
(
data
);
_activeTarget
=
target
;
_activeTargetWillAcceptDrop
=
_activeTarget
!=
null
&&
_activeTarget
.
didEnter
(
data
);
}
void
cancel
()
{
if
(
_activeTarget
!=
null
)
_activeTarget
.
didLeave
(
data
);
_activeTarget
=
null
;
_activeTargetWillAcceptDrop
=
false
;
}
void
drop
()
{
if
(
_activeTarget
==
null
)
return
;
if
(
_activeTargetWillAcceptDrop
)
_activeTarget
.
didDrop
(
data
);
else
_activeTarget
.
didLeave
(
data
);
_activeTarget
=
null
;
_activeTargetWillAcceptDrop
=
false
;
}
}
packages/flutter/lib/widgets/framework.dart
View file @
46fc8e6a
...
...
@@ -866,6 +866,17 @@ abstract class RenderObjectWrapper extends Widget {
new
HashMap
<
RenderObject
,
RenderObjectWrapper
>();
static
RenderObjectWrapper
_getMounted
(
RenderObject
node
)
=>
_nodeMap
[
node
];
static
Iterable
<
Widget
>
getWidgetsForRenderObject
(
RenderObject
renderObject
)
sync
*
{
Widget
target
=
RenderObjectWrapper
.
_getMounted
(
renderObject
);
if
(
target
==
null
)
return
;
RenderObject
targetRoot
=
target
.
root
;
while
(
target
!=
null
&&
target
.
root
==
targetRoot
)
{
yield
target
;
target
=
target
.
parent
;
}
}
RenderObjectWrapper
_ancestor
;
void
insertChildRoot
(
RenderObjectWrapper
child
,
dynamic
slot
);
void
detachChildRoot
(
RenderObjectWrapper
child
);
...
...
@@ -1209,11 +1220,7 @@ class WidgetSkyBinding extends SkyBinding {
if
(
disposition
==
EventDisposition
.
consumed
)
return
EventDisposition
.
consumed
;
for
(
HitTestEntry
entry
in
result
.
path
.
reversed
)
{
Widget
target
=
RenderObjectWrapper
.
_getMounted
(
entry
.
target
);
if
(
target
==
null
)
continue
;
RenderObject
targetRoot
=
target
.
root
;
while
(
target
!=
null
&&
target
.
root
==
targetRoot
)
{
for
(
Widget
target
in
RenderObjectWrapper
.
getWidgetsForRenderObject
(
entry
.
target
))
{
if
(
target
is
Listener
)
{
EventDisposition
targetDisposition
=
target
.
_handleEvent
(
event
);
if
(
targetDisposition
==
EventDisposition
.
consumed
)
{
...
...
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