*** empty log message ***
authorca
Fri, 31 Jan 1997 17:01:33 +0100
changeset 394 0539d7b29aa7
parent 393 9e9f2272b524
child 395 bd27655f4354
*** empty log message ***
DragAndDropManager.st
--- 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 $'
 ! !