I have the exactly same need :)

On Mon, Oct 13, 2014 at 1:02 AM, Peter Uhnák <i.uhnak@gmail.com> wrote:
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

_______________________________________________
Moose-dev mailing list
Moose-dev@iam.unibe.ch
https://www.iam.unibe.ch/mailman/listinfo/moose-dev


--
Gustavo Santos