DragAndDropManager.st
changeset 2625 3ad1c3a78c8d
parent 2540 253ce2688c49
child 2652 4d7395b74cf0
--- a/DragAndDropManager.st	Thu Apr 30 18:25:27 2009 +0200
+++ b/DragAndDropManager.st	Fri May 01 19:36:47 2009 +0200
@@ -15,7 +15,7 @@
 	instanceVariableNames:'dropContext dragView dropAction dragOffset handler restoreBlock
 		alienCursor enabledCursor disabledCursor canDrop escapePressed
 		passiveAction autoScrollTask disabledFlag giveFocusToTargetWidget
-		notifyEndOfDropAction'
+		notifyEndOfDropAction savedCursor'
 	classVariableNames:'DragContextQuerySignal DragOriginatorQuerySignal
 		DragOffsetQuerySignal ActiveDragAndDropManagers'
 	poolDictionaries:''
@@ -754,93 +754,6 @@
 
 !DragAndDropManager methodsFor:'accessing'!
 
-buttonMotion:buttonAndModifierState x:x y:y view:aView
-    |device screenPoint oldWidget oldId oldPoint newId newWidget oldTarget newTarget 
-     isDroppable cursor|
-
-    self isDisabled ifTrue: [ ^ self ].
-
-    escapePressed == true ifTrue:[
-        self removePassiveAction.
-        ^ self
-    ].
-
-    (dragView notNil and:[dragView sensor motionEventPending]) ifTrue:[
-        ^ self
-    ].
-    self removePassiveAction.
-
-    device := dragView device.
-    oldWidget  := dropContext targetWidget.
-    oldId  := dropContext targetId.
-    oldPoint  := dropContext rootPoint.
-
-    screenPoint := self class translatePointToScreen:(x @ y) from:aView.
-    dropContext rootPoint:screenPoint.
-
-    newId := device viewIdFromPoint:screenPoint.
-    newWidget := device viewFromId:newId.
-
-    dropContext rootPoint:screenPoint.
-    dropContext targetWidget:newWidget id:newId.
-    handler dropContext:dropContext.
-    handler isInterestedInDropTarget ifFalse:[
-        "/
-        "/ line or arrow handler
-        "/
-        handler dragTo:screenPoint.
-        ^ self
-    ].
-
-    oldTarget := dropContext dropTarget.
-    newTarget := self doFindDropTargetIn:newWidget at:screenPoint.
-
-    newTarget ~= oldTarget ifTrue:[
-        "/
-        "/ drop target changed: handler might restore the screen
-        "/
-        handler dropTargetWillChange.
-
-        oldTarget notNil ifTrue:[
-            "/
-            "/ setup old context
-            "/
-            dropContext targetWidget:oldWidget id:oldId.
-            oldTarget leave:dropContext.
-            dropContext targetWidget:newWidget id:newId.
-        ].
-        dropContext dropTarget:newTarget.
-        newTarget notNil ifTrue:[ newTarget enter:dropContext ]
-    ] ifFalse:[
-        dropContext dropTarget:newTarget
-    ].
-
-    "/
-    "/ update the cursor
-    "/
-    (isDroppable := dropContext canDrop) ifTrue:[
-        cursor := enabledCursor
-    ] ifFalse:[
-        dropContext isAlienView ifFalse:[cursor := disabledCursor]
-                                 ifTrue:[cursor := alienCursor]
-    ].
-
-    dragView cursor:cursor now:true.
-    "/
-    "/ test if droppable state changed
-    "/
-    canDrop == isDroppable ifFalse:[
-        "/
-        "/ droppable state changed: handler might restore the screen
-        "/
-        canDrop := isDroppable.
-        handler dropTargetWillChange
-    ].
-
-    newTarget notNil ifTrue:[ newTarget over:dropContext ].
-    handler dragTo:screenPoint.
-!
-
 device
     "returns the device of the source view"
 
@@ -1284,6 +1197,93 @@
 
 !DragAndDropManager methodsFor:'event catching'!
 
+buttonMotion:buttonAndModifierState x:x y:y view:aView
+    |device screenPoint oldWidget oldId oldPoint newId newWidget oldTarget newTarget 
+     isDroppable cursor|
+
+    self isDisabled ifTrue: [ ^ self ].
+
+    escapePressed == true ifTrue:[
+        self removePassiveAction.
+        ^ self
+    ].
+
+    (dragView notNil and:[dragView sensor motionEventPending]) ifTrue:[
+        ^ self
+    ].
+    self removePassiveAction.
+
+    device := dragView device.
+    oldWidget  := dropContext targetWidget.
+    oldId  := dropContext targetId.
+    oldPoint  := dropContext rootPoint.
+
+    screenPoint := self class translatePointToScreen:(x @ y) from:aView.
+    dropContext rootPoint:screenPoint.
+
+    newId := device viewIdFromPoint:screenPoint.
+    newWidget := device viewFromId:newId.
+
+    dropContext rootPoint:screenPoint.
+    dropContext targetWidget:newWidget id:newId.
+    handler dropContext:dropContext.
+    handler isInterestedInDropTarget ifFalse:[
+        "/
+        "/ line or arrow handler
+        "/
+        handler dragTo:screenPoint.
+        ^ self
+    ].
+
+    oldTarget := dropContext dropTarget.
+    newTarget := self doFindDropTargetIn:newWidget at:screenPoint.
+
+    newTarget ~= oldTarget ifTrue:[
+        "/
+        "/ drop target changed: handler might restore the screen
+        "/
+        handler dropTargetWillChange.
+
+        oldTarget notNil ifTrue:[
+            "/
+            "/ setup old context
+            "/
+            dropContext targetWidget:oldWidget id:oldId.
+            oldTarget leave:dropContext.
+            dropContext targetWidget:newWidget id:newId.
+        ].
+        dropContext dropTarget:newTarget.
+        newTarget notNil ifTrue:[ newTarget enter:dropContext ]
+    ] ifFalse:[
+        dropContext dropTarget:newTarget
+    ].
+
+    "/
+    "/ update the cursor
+    "/
+    (isDroppable := dropContext canDrop) ifTrue:[
+        cursor := enabledCursor
+    ] ifFalse:[
+        dropContext isAlienView ifFalse:[cursor := disabledCursor]
+                                 ifTrue:[cursor := alienCursor]
+    ].
+
+    dragView cursor:cursor now:true.
+    "/
+    "/ test if droppable state changed
+    "/
+    canDrop == isDroppable ifFalse:[
+        "/
+        "/ droppable state changed: handler might restore the screen
+        "/
+        canDrop := isDroppable.
+        handler dropTargetWillChange
+    ].
+
+    newTarget notNil ifTrue:[ newTarget over:dropContext ].
+    handler dragTo:screenPoint.
+!
+
 buttonRelease:button x:x y:y view:aView
     |targetWidget|
 
@@ -1334,6 +1334,8 @@
     escapePressed ~~ true ifTrue:[
         escapePressed := true.
 
+        dragView cursor:savedCursor now:true.
+
         handler notNil ifTrue:[
             "/ restore handler
             dropTarget := dropContext dropTarget.
@@ -1354,11 +1356,33 @@
 
     <resource: #keyboard (#Escape)>
 
-    escapePressed == true ifTrue:[ ^ self ].    "/ ignorred, escaped was pressed
+    escapePressed == true ifTrue:[ ^ self ].    "/ ignored, escaped was already pressed
 
     aKey == #Escape ifTrue:[
         self escapePressed.
     ].
+
+    ((aKey == #Cmd) 
+    or:[ (aKey == #Shift)
+    or:[ (aKey == #Ctrl) ]]) ifTrue:[
+        self updateDragKind.
+        "/ invoke motion, to force a redraw (of the dropKind-indicator)
+        self buttonMotion:nil x:x y:y view:aView    
+    ].
+!
+
+keyRelease:aKey x:x y:y view:aView
+    "redraw if shift, alt or ctrl key is released"
+
+    <resource: #keyboard (#Escape)>
+
+    ((aKey == #Cmd) 
+    or:[ (aKey == #Shift)
+    or:[ (aKey == #Ctrl) ]]) ifTrue:[
+        self updateDragKind.
+        "/ invoke motion, to force a redraw (of the dropKind-indicator)
+        self buttonMotion:nil x:x y:y view:aView    
+    ].
 !
 
 processAutoScroll
@@ -1398,18 +1422,23 @@
         ^ false
     ].
 
-    event isKeyEvent ifTrue:[
+    event isKeyPressEvent ifTrue:[
         self keyPress:(event key) x:(event x) y:(event y) view:evView.
         ^ true
     ].
+    event isKeyReleaseEvent ifTrue:[
+        self keyRelease:(event key) x:(event x) y:(event y) view:evView.
+        ^ true
+    ].
+    event isButtonMotionEvent ifTrue:[
+        self buttonMotion:(event state) x:(event x) y:(event y) view:evView.
+        ^ true
+    ].
+    event isButtonReleaseEvent ifTrue:[
+        self buttonRelease:(event button) x:(event x) y:(event y) view:evView.
+        ^ true
+    ].
 
-    event isButtonMotionEvent ifTrue:[
-        self buttonMotion:(event state) x:(event x) y:(event y) view:evView.
-    ] ifFalse:[
-        event isButtonReleaseEvent ifTrue:[
-            self buttonRelease:(event button) x:(event x) y:(event y) view:evView.
-        ]
-    ].
     ^ true
 !
 
@@ -1423,6 +1452,27 @@
 
     notifyEndOfDropAction := nil.
     action value.
+!
+
+updateDragKind
+    "stop the drag operation, when the escape key is pressed"
+
+    |screen dragType|
+
+    dragType := DropContext dragTypeDefault.
+
+    screen := dragView device.
+    screen ctrlDown ifTrue:[
+        dragType := DropContext dragTypeCopy.
+    ].
+    screen metaDown ifTrue:[
+        dragType := DropContext dragTypeLink.
+    ].
+    screen shiftDown ifTrue:[
+        dragType := DropContext dragTypeMove.
+    ].
+
+    dropContext dragType:dragType.
 ! !
 
 !DragAndDropManager methodsFor:'initialization'!
@@ -1431,8 +1481,7 @@
     super initialize.
 
     dragOffset     := 0 @ 0.
-    dropContext    := DropContext new.
-    dropContext manager:self.
+    dropContext    := DropContext new manager:self.
     alienCursor    := Cursor questionMark.
     enabledCursor  := Cursor thumbsUp.
     disabledCursor := Cursor thumbsDown.
@@ -1530,7 +1579,7 @@
 doStart:aHandler for:aView atEnd:aFourArgEndBlock
     "setup a handler and a restore block"
 
-    |device lastActive windowGroup savedCursor screenPoint|
+    |device lastActive windowGroup screenPoint|
 
     device := aView device.
     lastActive := ActiveDragAndDropManagers at:device ifAbsent:nil.
@@ -1560,23 +1609,24 @@
     windowGroup addPreEventHook:self.
     windowGroup addPostEventHook:self.
 
-    restoreBlock := [
-        restoreBlock := nil.
+    restoreBlock := 
+        [
+            restoreBlock := nil.
 
-        autoScrollTask notNil ifTrue:[
-            autoScrollTask terminate.
-            autoScrollTask := nil.
-        ].
+            autoScrollTask notNil ifTrue:[
+                autoScrollTask terminate.
+                autoScrollTask := nil.
+            ].
 
-        ActiveDragAndDropManagers removeKey:device ifAbsent:nil.
-        escapePressed ifFalse:[ aHandler postDragging ].
+            ActiveDragAndDropManagers removeKey:device ifAbsent:nil.
+            escapePressed ifFalse:[ aHandler postDragging ].
 
-        windowGroup removePreEventHook:self.
-        windowGroup removePostEventHook:self.
-        dragView cursor:savedCursor.
+            windowGroup removePreEventHook:self.
+            windowGroup removePostEventHook:self.
+            dragView cursor:savedCursor.
 
-        self triggerEndOfDropAction.
-    ].
+            self triggerEndOfDropAction.
+        ].
     aHandler preDraggingIn:dragView.
 
     "/ must wait for all pending motion events to arrive, and ignore them
@@ -1640,7 +1690,7 @@
 !DragAndDropManager class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libview2/DragAndDropManager.st,v 1.83 2008-09-11 12:39:38 stefan Exp $'
+    ^ '$Header: /cvs/stx/stx/libview2/DragAndDropManager.st,v 1.84 2009-05-01 17:36:47 cg Exp $'
 ! !
 
 DragAndDropManager initialize!