Hi,
Currently I don't see any way how to tell an element that another one has
been dropped onto him. For example if I want to drag an element into a
container (see example at the end).
Unfortunately in my solution i had to change the behaviour of Trachel
(RTMorph), so could this be in some (better) way incorporated into Roassal
(Trachel)?
My solution is making a subclass
-------------------------------------
TRAbstractMouseEvent subclass: #TRMouseDragDrop
-------------------------------------
And altering mouseDragEnd
-------------------------------------
RTMorph>>rtMouseDragEnd: evt
| ee dropEvent dropShape relativePosition |
"notify the dragged element"
ee := TRMouseDragEnd new.
ee shape: shapeBeingPointed.
ee canvas: trachelCanvas.
ee morph: self.
shapeBeingPointed announce: ee.
"notify the element onto which was the drag performed"
shapeBeingPointed = trachelCanvas
ifFalse: [
shapeBeingPointed element attributes
at: #rtDroppable
ifPresent: [
relativePosition := self relativePositionFor: evt.
dropShape := self shapeWithAction: TRMouseDragDrop forPositionInPixels:
relativePosition.
dropShape = shapeBeingPointed
ifFalse: [
dropEvent := TRMouseDragDrop new
shape: shapeBeingPointed;
canvas: trachelCanvas;
morph: self.
dropShape announce: dropEvent ] ] ].
eventBeginingDragging := nil.
shapeBeingPointed := nil
-------------------------------------
Example (use case) is:
-------------------------------------
view := RTView new.
container := RTBox new size: 200; color: Color white; borderColor: Color
black; element.
group := RTGroup new.
RTNest new on: container nest: group.
container trachelShape size: 200.
box := RTBox new size: 50; color: Color magenta; element.
box translateTo: 250 @ 0.
container @ RTDraggable.
container @ RTResizeable.
box @ RTDraggable.
box attributes at: #rtDroppable put: true.
container
when: TRMouseDragDrop
do: [ :event |
| el |
el := event shape element.
el attributes at: #container ifPresent: [
group remove: el.
].
group add: el.
el attributes at: #container put: group.
].
view canvas
when: TRMouseDragDrop
do: [ :event |
| el |
el := event shape element.
el attributes at: #container ifPresent: [ :parent |
parent remove: el.
el attributes removeKey: #container.
].
].
view
add: container;
add: box.
view open.
-------------------------------------
Also it would be nice to have an option to highlight the drop area. There
is TRMouseEnter/TRMouseLeave but it fires only for the top level shape,
perhaps it should for all? Or less invasive to add
TRMouseDragEnter/TRMouseDragLeave which would work like regular Enter/Leave
but on the next (on z-axis) shape.
Please let me know what you think.
Peter