--- a/DragAndDropManager.st Fri Jan 31 10:51:54 1997 +0100
+++ b/DragAndDropManager.st Fri Jan 31 17:01:33 1997 +0100
@@ -1,6 +1,7 @@
Object subclass:#DragAndDropManager
instanceVariableNames:'dragView motionAction releaseAction initialPoint previousPoint
- rememberedDelegate dragBlock lineMode dropAction'
+ rememberedDelegate dragBlock lineMode dropAction opaque saveUnder
+ dragSize dragOffset dropObject saveCursor lastView'
classVariableNames:''
poolDictionaries:''
category:'Interface-Support'
@@ -45,21 +46,92 @@
"Modified: 26.10.1996 / 15:21:42 / cg"
! !
+!DragAndDropManager methodsFor:'accessing'!
+
+dropObject:aDropObject
+ dropObject := aDropObject
+! !
+
!DragAndDropManager methodsFor:'dragging - generic'!
doGenericDragX:x y:y
+ |view|
+
previousPoint notNil ifTrue:[
- self invertGenericAt:previousPoint
+ opaque ifTrue:[
+ self restoreGenericAt:previousPoint
+ ] ifFalse:[
+ self invertGenericAt:previousPoint
+ ]
].
previousPoint := x @ y.
- self invertGenericAt:previousPoint
+
+ view := self destinationViewAt:previousPoint.
+ view ~~ lastView ifTrue:[
+ (view notNil and:[view canDrop:dropObject]) ifTrue:[
+ dragView cursor:(Cursor thumbsUp) now:true.
+ ] ifFalse:[
+ dragView cursor:(Cursor thumbsDown) now:true
+ ].
+ lastView := view
+ ].
+
+ opaque ifTrue:[
+ self drawGenericAt:previousPoint.
+ ] ifFalse:[
+ self invertGenericAt:previousPoint
+ ].
+!
+
+drawGenericAt:ip
+ |t offs p rootView|
+
+ rootView := dragView device rootView.
+
+ p := ip.
- "Modified: 26.10.1996 / 15:16:59 / cg"
+ "
+ get device coordinates
+ "
+ (t := dragView transformation) notNil ifTrue:[
+ p := t applyTo:p.
+ ].
+
+ "
+ translate to screen
+ "
+ offs := dragView device
+ translatePoint:0@0
+ from:(dragView id) to:(rootView id).
+ p := p + offs.
+
+ rootView clippedByChildren:false.
+ saveUnder isNil ifTrue:[
+ saveUnder := Form width:dragSize x height:dragSize y depth:rootView device depth on:dragView device.
+ saveUnder clippedByChildren:false.
+ ].
+ saveUnder
+ copyFrom:rootView
+ x:p x - dragOffset x
+ y:p y - dragOffset y
+ toX:0
+ y:0
+ width:dragSize x
+ height:dragSize y.
+
+ rootView lineWidth:0.
+ dragBlock value:p value:rootView.
+ rootView flush
+
!
endGenericDragX:x y:y
previousPoint notNil ifTrue:[
- self invertGenericAt:previousPoint
+ opaque ifTrue:[
+ self restoreGenericAt:previousPoint
+ ] ifFalse:[
+ self invertGenericAt:previousPoint
+ ]
].
previousPoint := nil.
self uncatchEvents.
@@ -67,6 +139,7 @@
"Created: 26.10.1996 / 15:17:20 / cg"
"Modified: 26.10.1996 / 15:22:41 / cg"
+
!
invertGenericAt:ip
@@ -100,6 +173,42 @@
"Created: 26.10.1996 / 15:15:26 / cg"
"Modified: 26.10.1996 / 15:27:09 / cg"
+
+!
+
+restoreGenericAt:ip
+ |t offs p rootView|
+
+
+ rootView := dragView device rootView.
+ p := ip.
+
+ "
+ get device coordinates
+ "
+ (t := dragView transformation) notNil ifTrue:[
+ p := t applyTo:p.
+ ].
+
+ "
+ translate to screen
+ "
+ offs := dragView device
+ translatePoint:0@0
+ from:(dragView id) to:(rootView id).
+ p := p + offs.
+
+ rootView clippedByChildren:false.
+ rootView
+ copyFrom:saveUnder
+ x:0
+ y:0
+ toX:p x - dragOffset x
+ y:p y - dragOffset y
+ width:dragSize x
+ height:dragSize y.
+
+
!
startGenericDrag:aTwoArgDragBlock in:aView at:p atEnd:aFourArgEndBlock
@@ -121,6 +230,35 @@
"Modified: 26.10.1996 / 15:09:26 / cg"
"Created: 26.10.1996 / 15:16:13 / cg"
+
+!
+
+startOpaqueDrag:aTwoArgDragBlock offset:offs extent:ext in:aView at:p atEnd:aFourArgEndBlock
+ "start a generic opaque (caller-provided drag);
+ opaque drag means, that the drawing cannot be undone by two inverting
+ draws, but instead, the area under the dragged object must be saved
+ and restored. The areas size to be saved/restored is passed in ext.
+ the dragBlock, aTwoArgDragBlock will be called with two args
+ aPoint and a drawingGC, to perform the drawing at some dragPoint.
+ The drag starts in aView at point p.
+ When finished, the endAction is called with four args:
+ the targetView, the targetViews windowID (useful, if its an alien view),
+ the dropPoint in root-coordinates and the dropPoint within the targetView"
+
+ self catchEventsFrom:aView.
+ motionAction := #doGenericDragX:y:.
+ releaseAction := #endGenericDragX:y:.
+ initialPoint := p.
+ previousPoint := nil.
+ dragBlock := aTwoArgDragBlock.
+ dropAction := aFourArgEndBlock.
+ opaque := true.
+ dragSize := ext.
+ dragOffset := offs.
+
+ "Modified: 26.10.1996 / 15:09:26 / cg"
+ "Created: 26.10.1996 / 15:16:13 / cg"
+
! !
!DragAndDropManager methodsFor:'dragging - lines'!
@@ -133,6 +271,8 @@
self invertLineFrom:initialPoint to:previousPoint
"Modified: 26.10.1996 / 15:16:59 / cg"
+
+
!
endLineDragX:x y:y
@@ -145,6 +285,7 @@
"Created: 26.10.1996 / 15:17:20 / cg"
"Modified: 26.10.1996 / 15:22:41 / cg"
+
!
invertLineFrom:ip1 to:ip2
@@ -187,6 +328,7 @@
"Created: 26.10.1996 / 15:15:26 / cg"
"Modified: 26.10.1996 / 15:27:09 / cg"
+
!
startArrowDragIn:aView at:p atEnd:aBlock
@@ -207,6 +349,7 @@
"Modified: 26.10.1996 / 15:09:26 / cg"
"Created: 26.10.1996 / 15:16:13 / cg"
+
!
startLineDragIn:aView at:p atEnd:aFourArgEndBlock
@@ -227,6 +370,7 @@
"Modified: 26.10.1996 / 15:09:26 / cg"
"Created: 26.10.1996 / 15:16:13 / cg"
+
! !
!DragAndDropManager methodsFor:'event catching'!
@@ -235,12 +379,35 @@
self perform:motionAction with:x with:y
"Created: 26.10.1996 / 15:09:00 / cg"
+
+
!
buttonRelease:button x:x y:y view:aView
self perform:releaseAction with:x with:y
"Created: 26.10.1996 / 15:09:14 / cg"
+
+!
+
+drop:something in:targetView at:aPoint from:sourceView ifOk:okAction ifFail:failAction
+ "try to drop some object in a targetView;
+ if the targetView takes it, okAction is evaluated ;
+ if not, failAction is evaluated"
+
+ (targetView canDrop:something) ifFalse:[
+ failAction value.
+ ^ false
+ ].
+ targetView drop:something at:aPoint from:sourceView
+ with:[:o | okAction. ^ true]
+ ifFail:[:o | failAction. ^ false].
+ ^ false
+
+
+
+
+
!
handlesButtonMotion:button inView:aView
@@ -250,6 +417,7 @@
^ aView == dragView
"Created: 26.10.1996 / 15:05:36 / cg"
+
!
handlesButtonRelease:button inView:aView
@@ -259,79 +427,121 @@
^ aView == dragView
"Created: 26.10.1996 / 15:05:48 / cg"
+
! !
!DragAndDropManager methodsFor:'private'!
catchEventsFrom:aView
- dragView := aView.
+ dragView := aView.
+ saveCursor := dragView cursor.
+
rememberedDelegate := aView delegate.
- aView delegate:self
+ aView delegate:self.
"Created: 26.10.1996 / 15:03:12 / cg"
"Modified: 26.10.1996 / 15:21:57 / cg"
+
+
+!
+
+destinationViewAt:ip
+ |rootPoint t viewId offs destinationId lastViewId destinationView
+ rootView destinationPoint device|
+
+ device := dragView device.
+ rootView := device rootView.
+ rootPoint := ip.
+
+ "
+ get device coordinates
+ "
+ (t := dragView transformation) notNil ifTrue:[
+ rootPoint := t applyTo:ip.
+ ].
+ viewId := rootView id.
+
+ "
+ translate to screen
+ "
+ offs := device translatePoint:0@0 from:(dragView id) to:viewId.
+ rootPoint := rootPoint + offs.
+
+ "search view the drop is in"
+
+ [viewId notNil] whileTrue:[
+ destinationId := device viewIdFromPoint:rootPoint in:viewId.
+ lastViewId := viewId.
+ viewId := destinationId
+ ].
+ ^ device viewFromId:lastViewId
!
endDragAt:ip
|rootPoint t viewId offs destinationId lastViewId destinationView
rootView destinationPoint device|
- dropAction notNil ifTrue:[
- device := dragView device.
- rootView := device rootView.
- rootPoint := ip.
+ dragView cursor:saveCursor now:true.
+ device := dragView device.
+ rootView := device rootView.
+ rootPoint := ip.
- "
- get device coordinates
- "
- (t := dragView transformation) notNil ifTrue:[
- rootPoint := t applyTo:ip.
- ].
- viewId := rootView id.
-
- "
- translate to screen
- "
- offs := device translatePoint:0@0 from:(dragView id) to:viewId.
- rootPoint := rootPoint + offs.
+ "
+ get device coordinates
+ "
+ (t := dragView transformation) notNil ifTrue:[
+ rootPoint := t applyTo:ip.
+ ].
+ viewId := rootView id.
- "search view the drop is in"
+ "
+ translate to screen
+ "
+ offs := device translatePoint:0@0 from:(dragView id) to:viewId.
+ rootPoint := rootPoint + offs.
+
+ "search view the drop is in"
- [viewId notNil] whileTrue:[
- destinationId := device viewIdFromPoint:rootPoint in:viewId.
- lastViewId := viewId.
- viewId := destinationId
- ].
- destinationView := device viewFromId:lastViewId.
- destinationId := lastViewId.
+ [viewId notNil] whileTrue:[
+ destinationId := device viewIdFromPoint:rootPoint in:viewId.
+ lastViewId := viewId.
+ viewId := destinationId
+ ].
+ destinationView := device viewFromId:lastViewId.
+ destinationId := lastViewId.
- "into another one"
- destinationView notNil ifTrue:[
- destinationPoint := device translatePoint:rootPoint
- from:(rootView id)
- to:(destinationView id).
- destinationView transformation notNil ifTrue:[
- destinationPoint := destinationView transformation applyInverseTo:destinationPoint
- ].
- ] ifFalse:[
- "
- not one of my views
- "
+ "into another one"
+ destinationView notNil ifTrue:[
+ destinationPoint := device translatePoint:rootPoint
+ from:(rootView id)
+ to:(destinationView id).
+ destinationView transformation notNil ifTrue:[
+ destinationPoint := destinationView transformation applyInverseTo:destinationPoint
+ ]
+ ] ifFalse:[
+ "
+ not one of my views
+ "
+ ].
+
+ dropAction isNil ifTrue:[
+ (destinationView notNil and:[destinationView canDrop:dropObject]) ifTrue:[
+ destinationView drop:dropObject to:destinationPoint
].
+ ^ self
+ ].
- dropAction value:destinationView
- value:destinationId
- value:rootPoint
- value:destinationPoint
- ]
-
-
+ dropAction value:destinationView
+ value:destinationId
+ value:rootPoint
+ value:destinationPoint
!
uncatchEvents
dragView delegate:rememberedDelegate.
"Created: 26.10.1996 / 15:22:29 / cg"
+
! !
!DragAndDropManager::DemoView2 methodsFor:'events'!
@@ -399,5 +609,5 @@
!DragAndDropManager class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libview2/DragAndDropManager.st,v 1.6 1996-11-14 15:16:42 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libview2/DragAndDropManager.st,v 1.7 1997-01-31 16:01:33 ca Exp $'
! !