# HG changeset patch # User ca # Date 891259335 -7200 # Node ID 0730cf44f59393037c7d56b724cf19e31c1294ae # Parent c5cd8f56dc6eb30a64694b80964e662e97de3df0 support of Drop -Source -Target and Context diff -r c5cd8f56dc6e -r 0730cf44f593 DragAndDropManager.st --- a/DragAndDropManager.st Mon Mar 30 14:00:30 1998 +0200 +++ b/DragAndDropManager.st Mon Mar 30 14:02:15 1998 +0200 @@ -12,34 +12,11 @@ Object subclass:#DragAndDropManager - instanceVariableNames:'dragView motionAction releaseAction initialPoint previousPoint - rememberedDelegate dragBlock lineMode dropAction opaque saveUnder - dragSize dragOffset dropObjects saveCursor lastView - lastScreenPosition' + instanceVariableNames:'dropContext dragView dropAction dragOffset handler restoreBlock + alienCursor enabledCursor disabledCursor canDrop' classVariableNames:'DragOriginatorQuerySignal DragOffsetQuerySignal' poolDictionaries:'' - category:'Interface-Support' -! - -View subclass:#DemoView - instanceVariableNames:'' - classVariableNames:'' - poolDictionaries:'' - privateIn:DragAndDropManager -! - -View subclass:#DemoView2 - instanceVariableNames:'' - classVariableNames:'' - poolDictionaries:'' - privateIn:DragAndDropManager -! - -View subclass:#DemoView3 - instanceVariableNames:'' - classVariableNames:'' - poolDictionaries:'' - privateIn:DragAndDropManager + category:'Interface-DragAndDrop' ! !DragAndDropManager class methodsFor:'documentation'! @@ -152,7 +129,7 @@ Claus Gittinger [see also:] - DemoView DemoView2 DemoView3 - examples + DemoView1, DemoView2, ... SelectionInListView FileBrowser - for a concrete example " @@ -217,6 +194,36 @@ top openWithExtent:200@200 [exEnd] + more drag & drop; offset, displayObjects, ... + [exBegin] + |dropObj topView pannel icon buttonAction addButton| + + topView := StandardSystemView new. + pannel := VerticalPanelView origin:(0.0 @ 0.0) corner:(1.0 @ 1.0) in:topView. + pannel horizontalLayout:#fit. + pannel verticalLayout:#fitSpace. + + icon := Image fromFile:('xpmBitmaps/QUESTION3.xpm'). + dropObj := DropObject newFile:('.'). + + addButton := [:offset :label :dispObj| |button| + button := Button label:label in:pannel. + + button pressAction:[ + DragAndDropManager startDrag:dropObj from:button offset:offset display:dispObj. + button turnOff. + ] + ]. + + addButton value:#topLeft value:'String' value:'String'. + addButton value:#topRight value:'Text' value:(Text string:'hello' emphasis:#bold). + addButton value:#bottomLeft value:'Icon' value:icon. + addButton value:#bottomRight value:'LabelAndIcon' value:(LabelAndIcon icon:icon string:'Label & Icon'). + addButton value:#center value:'Mixed' value:(Array with:'String' with:icon). + + topView label:'Drag & Drop'. + topView openWithExtent:200@200. + [exEnd] " ! ! @@ -231,6 +238,10 @@ " "Modified: 11.8.1997 / 00:54:21 / cg" +! + +new + ^ self basicNew initialize ! ! !DragAndDropManager class methodsFor:'Signal constants'! @@ -245,189 +256,371 @@ ^ DragOriginatorQuerySignal ! ! -!DragAndDropManager class methodsFor:'simple start'! +!DragAndDropManager class methodsFor:'simple start - drop source'! + +startDragFrom:aView dropSource:aDropSource + "start a drop at the current pointer position. + " + ^ (self new) startDragFrom:aView dropSource:aDropSource +! ! + +!DragAndDropManager class methodsFor:'simple start - generic'! + +startDrag:draggableObjects from:aView + "start a drop at the current pointer position + " + ^ self startDrag:draggableObjects + from:aView + offset:0@0 + atEnd:nil + display:draggableObjects + +" +EXAMPLE: + + |button| + + button := (Button label:'press me'). + + button pressAction:[ + DragAndDropManager startDrag:(DropObject newFile:('.')) from:button. + button turnOff + ]. + + button openAt:100@100 +" +! + +startDrag:draggableObjects from:aView atEnd:aFourArgEndBlock + "start a drop at the current pointer position + 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 startDrag:draggableObjects + from:aView + offset:0@0 + atEnd:aFourArgEndBlock + display:draggableObjects + +" +EXAMPLE: + + |button| + + button := (Button label:'press me'). + + button pressAction:[ + DragAndDropManager startDrag:(DropObject newFile:('.')) + from:button + atEnd:[:targetView :targetViewId :screenPoint :targetPoint| + Transcript showCR:'target view: ', targetView printString. + Transcript showCR:'target id: ', targetViewId printString. + Transcript showCR:'point screen: ', screenPoint printString. + Transcript showCR:'point target: ', targetPoint printString. + ]. + button turnOff + ]. + + button openAt:100@100 +" + +! + +startDrag:draggableObjects from:aView atEnd:aFourArgEndBlock display:something + "start a drop at the current pointer position + 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 startDrag:draggableObjects + from:aView + offset:0@0 + atEnd:aFourArgEndBlock + display:something + +" +EXAMPLE: + + |button| + + button := (Button label:'press me'). + + button pressAction:[ + DragAndDropManager startDrag:(DropObject newFile:('.')) + from:button + atEnd:[:targetView :targetViewId :screenPoint :targetPoint| + Transcript showCR:'target view: ', targetView printString. + Transcript showCR:'target id: ', targetViewId printString. + Transcript showCR:'point screen: ', screenPoint printString. + Transcript showCR:'point target: ', targetPoint printString. + ] + display:(Array with:'String' with:(Image fromFile:('xpmBitmaps/QUESTION3.xpm'))). + button turnOff + ]. + + button openAt:100@100 +" +! + +startDrag:draggableObjects from:aView display:something + "start a drop at the current pointer position + " + ^ self startDrag:draggableObjects + from:aView + offset:0@0 + atEnd:nil + display:something + +" +EXAMPLE: + + |dropObj topView pannel icon buttonAction addButton| + + topView := StandardSystemView new. + pannel := VerticalPanelView origin:(0.0 @ 0.0) corner:(1.0 @ 1.0) in:topView. + pannel horizontalLayout:#fit. + pannel verticalLayout:#fitSpace. + + icon := Image fromFile:('xpmBitmaps/QUESTION3.xpm'). + dropObj := DropObject newFile:('.'). + + addButton := [:label :dispObj| |button| + button := Button label:label in:pannel. + + button pressAction:[ + DragAndDropManager startDrag:dropObj from:button display:dispObj. + button turnOff. + ] + ]. + + addButton value:'String' value:'String'. + addButton value:'Text' value:(Text string:'hello' emphasis:#bold). + addButton value:'Icon' value:icon. + addButton value:'LabelAndIcon' value:(LabelAndIcon icon:icon string:'Label & Icon'). + addButton value:'Mixed' value:(Array with:'String' with:icon). + + topView label:'Drag & Drop'. + topView openWithExtent:200@200. +" +! + +startDrag:draggableObjects from:aView offset:anOffset + "start a drop at the current pointer position + " + ^ self startDrag:draggableObjects + from:aView + offset:anOffset + atEnd:nil + display:draggableObjects + +" +EXAMPLE: + + |button| + + button := (Button label:'press me'). + + button pressAction:[ + DragAndDropManager startDrag:(DropObject newFile:('.')) from:button offset:(-10 @ -10). + button turnOff + ]. + + button openAt:100@100 +" + +! + +startDrag:draggableObjects from:aView offset:anOffset atEnd:aFourArgEndBlock + "start a drop at the current pointer position + 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 startDrag:draggableObjects + from:aView + offset:anOffset + atEnd:aFourArgEndBlock + display:draggableObjects + +" +EXAMPLE: + + |button| + + button := (Button label:'press me'). + + button pressAction:[ + DragAndDropManager startDrag:(DropObject newFile:('.')) + from:button + offset:(-10 @ -10) + atEnd:[:targetView :targetViewId :screenPoint :targetPoint| + Transcript showCR:'target view: ', targetView printString. + Transcript showCR:'target id: ', targetViewId printString. + Transcript showCR:'point screen: ', screenPoint printString. + Transcript showCR:'point target: ', targetPoint printString. + ]. + button turnOff + ]. + + button openAt:100@100 +" + +! + +startDrag:draggableObjects from:aView offset:anOffset atEnd:aFourArgEndBlock display:something + "start a drop at the current pointer position + 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 + " + |manager| + + manager := self new. + + manager startDrag:draggableObjects + from:aView + offset:anOffset + atEnd:aFourArgEndBlock + display:something. + + ^ manager + +" +EXAMPLE: + + |button| + + button := (Button label:'press me'). + + button pressAction:[ + DragAndDropManager startDrag:(DropObject newFile:('.')) + from:button + offset:(-10 @ -10) + atEnd:[:targetView :targetViewId :screenPoint :targetPoint| + Transcript showCR:'target view: ', targetView printString. + Transcript showCR:'target id: ', targetViewId printString. + Transcript showCR:'point screen: ', screenPoint printString. + Transcript showCR:'point target: ', targetPoint printString. + ] + display:(Array with:'String' with:(Image fromFile:('xpmBitmaps/QUESTION3.xpm'))). + button turnOff + ]. + + button openAt:100@100 +" + +! + +startDrag:draggableObjects from:aView offset:anOffset display:something + "start a drop at the current pointer position + " + ^ self startDrag:draggableObjects + from:aView + offset:anOffset + atEnd:nil + display:something + +" +EXAMPLE: + + |dropObj topView pannel icon buttonAction addButton| + + topView := StandardSystemView new. + pannel := VerticalPanelView origin:(0.0 @ 0.0) corner:(1.0 @ 1.0) in:topView. + pannel horizontalLayout:#fit. + pannel verticalLayout:#fitSpace. + + icon := Image fromFile:('xpmBitmaps/QUESTION3.xpm'). + dropObj := DropObject newFile:('.'). + + addButton := [:offset :label :dispObj| |button| + button := Button label:label in:pannel. + + button pressAction:[ + DragAndDropManager startDrag:dropObj from:button offset:offset display:dispObj. + button turnOff. + ] + ]. + + addButton value:#topLeft value:'String' value:'String'. + addButton value:#topRight value:'Text' value:(Text string:'hello' emphasis:#bold). + addButton value:#bottomLeft value:'Icon' value:icon. + addButton value:#bottomRight value:'LabelAndIcon' value:(LabelAndIcon icon:icon string:'Label & Icon'). + addButton value:#center value:'Mixed' value:(Array with:'String' with:icon). + + topView label:'Drag & Drop'. + topView openWithExtent:200@200. +" + +! ! + +!DragAndDropManager class methodsFor:'simple start - lines'! startArrowDragIn:aView at:dragPoint atEnd:aFourArgBlock "start a rubber-arrow-line dragging in aView at dragPoint. When finished, evaluate the fourArgBlock with targetView, - targetID, screenPosition and targetViewPosition as arguments" - - ^ self new - startArrowDragIn:aView at:dragPoint atEnd:aFourArgBlock - + targetID, screenPosition and targetViewPosition as arguments " - |o v| + ^ self new startArrowDragIn:aView at:dragPoint atEnd:aFourArgBlock - v := Button label:'press me'. - v pressAction:[ - |o| - o := DropObject newFile:('.'). - v turnOff; repairDamage. - DragAndDropManager - startArrowDragIn:v - at:0@0 - atEnd:[:v :vID :sPos :vPos | - v isNil ifTrue:[ - Transcript show:'alien view' - ] ifFalse:[ - Transcript show:'view: '; - show:v - ]. - Transcript show:' screen: '; show:sPos; - show:' inView: '; showCR:vPos. - ]. - ]. - v openAt:100@100 - " - - "Modified: 19.4.1997 / 12:04:08 / cg" -! +" +EXAMPLE: -startDrag:anObjectOrCollection from:aView - "start a drop at the current pointer position" - - self startDrag:anObjectOrCollection from:aView offset:0@0 atEnd:nil - - " - |o v| - - v := (Button label:'press me'). - v pressAction:[ - |o| - o := DropObject newFile:('.'). - DragAndDropManager startDrag:o from:v. - v turnOff - ]. - v openAt:100@100 - " + |button| - "Modified: 19.4.1997 / 11:42:40 / cg" - -! - -startDrag:anObjectOrCollection from:aView atEnd:aFourArgEndBlock - "start a drop at the current pointer position - 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" + button := (Button label:'press me'). - self startDrag:anObjectOrCollection from:aView offset:0@0 atEnd:aFourArgEndBlock - -! - -startDrag:anObjectOrCollection from:aView atEnd:aFourArgEndBlock useIcon:anIcon - "start a drop at the current pointer position - 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" + button pressAction:[ + button turnOff. - self startDrag:anObjectOrCollection from:aView offset:0@0 atEnd:aFourArgEndBlock useIcon:anIcon - -! - -startDrag:anObjectOrCollection from:aView offset:offset - "start a drop at the current pointer position" - - self startDrag:anObjectOrCollection from:aView offset:offset atEnd:nil - - " - |o v| - - v := (Button label:'press me'). - v pressAction:[ - |o| - o := DropObject newFile:('.'). - DragAndDropManager startDrag:o from:v offset:10@10. - v turnOff - ]. - v openAt:100@100 - " - - "Modified: 19.4.1997 / 11:42:45 / cg" - -! - -startDrag:anObjectOrCollection from:aView offset:offset atEnd:aFourArgEndBlock - "start a drop at the current pointer position - 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 new) startDrag:anObjectOrCollection from:aView offset:offset atEnd:aFourArgEndBlock - - -! - -startDrag:anObjectOrCollection from:aView offset:anOffset atEnd:aFourArgEndBlock useIcon:anIcon - - (self new) startDrag:anObjectOrCollection - from:aView - offset:anOffset - atEnd:aFourArgEndBlock - useIcon:anIcon - - -! - -startDrag:anObjectOrCollection from:aView useIcon:anIcon - "start a drop at the current pointer position" - - self startDrag:anObjectOrCollection from:aView offset:0@0 atEnd:nil useIcon:anIcon - - " - |o v| - - v := (Button label:'press me'). - v pressAction:[ - |o| - o := DropObject newFile:('.'). - DragAndDropManager startDrag:o from:v useIcon:( - Image fromFile:('xpmBitmaps/cursors/hand_with_document.xpm') - ). - v turnOff - ]. - v openAt:100@100 - " - - "Modified: 19.4.1997 / 11:42:40 / cg" - + DragAndDropManager startArrowDragIn:button + at:(button preferredExtent // 2) + atEnd:[:targetView :targetViewId :screenPoint :targetPoint| + targetView isNil ifTrue:[ + Transcript show:'alien view' + ] ifFalse:[ + Transcript showCR:'target: ', targetView printString + ]. + Transcript showCR:'point screen: ', screenPoint printString. + Transcript showCR:'point target: ', targetPoint printString. + ] + ]. + button openAt:100@100 +" ! startLineDragIn:aView at:dragPoint atEnd:aFourArgBlock "start a rubber-line dragging in aView at dragPoint. When finished, evaluate the fourArgBlock with targetView, - targetID, screenPosition and targetViewPosition as arguments" + targetID, screenPosition and targetViewPosition as arguments + " + ^ self new startLineDragIn:aView at:dragPoint atEnd:aFourArgBlock + +" +EXAMPLE: - ^ self new - startLineDragIn:aView at:dragPoint atEnd:aFourArgBlock + |button| - " - |o v| + button := (Button label:'press me'). + + button pressAction:[ + button turnOff. - v := (Button label:'press me'). - v pressAction:[ - |o| - o := DropObject newFile:('.'). - v turnOff; repairDamage. - DragAndDropManager - startLineDragIn:v - at:0@0 - atEnd:[:v :vID :sPos :vPos | - v isNil ifTrue:[ - Transcript show:'alien view' - ] ifFalse:[ - Transcript show:'view: '; - show:v - ]. - Transcript show:' screen: '; show:sPos; - show:' inView: '; showCR:vPos. - ]. - ]. - v openAt:100@100 - " - - "Modified: 19.4.1997 / 12:02:02 / cg" + DragAndDropManager startLineDragIn:button + at:(button preferredExtent // 2) + atEnd:[:targetView :targetViewId :screenPoint :targetPoint| + targetView isNil ifTrue:[ + Transcript show:'alien view' + ] ifFalse:[ + Transcript showCR:'target: ', targetView printString + ]. + Transcript showCR:'point screen: ', screenPoint printString. + Transcript showCR:'point target: ', targetPoint printString. + ] + ]. + button openAt:100@100 +" ! ! !DragAndDropManager methodsFor:'accessing'! @@ -440,10 +633,16 @@ ! +dropContext + "return the current context + " + ^ dropContext +! + dropObjects "return the current dropObject collection" - ^ dropObjects + ^ dropContext dropObjects "Modified: 19.4.1997 / 10:19:06 / cg" ! @@ -451,13 +650,7 @@ dropObjects:aCollectionOfDropObjects "set the current dropObject collection" - aCollectionOfDropObjects isCollection ifTrue:[ - dropObjects := aCollectionOfDropObjects - ] ifFalse:[ - dropObjects := Array with:aCollectionOfDropObjects - ]. - - "Modified: 19.4.1997 / 10:19:33 / cg" + ^ dropContext dropObjects:aCollectionOfDropObjects ! font @@ -466,71 +659,184 @@ ^ dragView font +! + +sourceWidget + ^ dragView +! ! + +!DragAndDropManager methodsFor:'accessing cursor'! + +alienCursor:aCursorOrImage + "set the cursor used for an alien widget; not an ST/X view + " + aCursorOrImage isImage ifTrue:[ + alienCursor := Cursor fromImage:aCursorOrImage + ] ifFalse:[ + (aCursorOrImage isMemberOf:Cursor) ifTrue:[ + alienCursor := aCursorOrImage + ] ifFalse:[ + "/ + "/ use disabled cursor + "/ + alienCursor := nil + ] + ] +! + +disabledCursor:aCursorOrImage + "set the cursor for an ST/X view, which can not drop the objects + " + aCursorOrImage isImage ifTrue:[ + disabledCursor := Cursor fromImage:aCursorOrImage + ] ifFalse:[ + (aCursorOrImage isMemberOf:Cursor) ifTrue:[ + disabledCursor := aCursorOrImage + ] + ] +! + +enabledCursor:aCursorOrImage + "set the cursor for an ST/X view, which can drop the objects + " + aCursorOrImage isImage ifTrue:[ + enabledCursor := Cursor fromImage:aCursorOrImage + ] ifFalse:[ + (aCursorOrImage isMemberOf:Cursor) ifTrue:[ + enabledCursor := aCursorOrImage + ] + ] + +! ! + +!DragAndDropManager methodsFor:'dragging - drop source'! + +startDragFrom:aView dropSource:aDropSource + "start a drop at the current pointer position. + " + ^ self startDragFrom:aView dropSource:aDropSource offset:#topLeft "/ #center +! + +startDragFrom:aView dropSource:aDropSource offset:anOffset + "start a drop at the current pointer position. + " + dropContext dropSource:aDropSource. + + ^ self startDrag:(aDropSource dropObjects) + from:aView + offset:anOffset + atEnd:nil + display:(aDropSource displayObjects) +! ! + +!DragAndDropManager methodsFor:'dragging - easy startup'! + +startDrag:draggableObjects from:aView + "start a drop at the current pointer position + " + ^ self startDrag:draggableObjects + from:aView + offset:0@0 +! + +startDrag:draggableObjects from:aView display:something + "start a drop at the current pointer position. + " + ^ self startDrag:draggableObjects + from:aView + offset:nil + atEnd:nil + display:something +! + +startDrag:draggableObjects from:aView offset:anOffset + "start a drop at the current pointer position with an offset + " + ^ self startDrag:draggableObjects + from:aView + offset:anOffset + atEnd:nil +! + +startDrag:draggableObjects from:aView offset:anOffset atEnd:aFourArgEndBlock + "start a drop at the current pointer position. + 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 startDrag:draggableObjects + from:aView + offset:anOffset + atEnd:aFourArgEndBlock + display:draggableObjects +! + +startDrag:draggableObjects from:aView offset:anOffset atEnd:aFourArgBlock display:something + "start a drop at the current pointer position. + 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. + " + |height width fontWdt dispObj offset ascent device dispObjs list space| + + self dropObjects:draggableObjects. + + self dropObjects size == 0 ifTrue:[ + ^ self + ]. + + device := aView device. + space := 1. + height := space negated. + width := 0. + fontWdt := aView font width. + ascent := aView font ascent. + + (list := something) isNil ifTrue:[ + list := self dropObjects + ] ifFalse:[ + (list isCollection not or:[list isString]) ifTrue:[ + list := Array with:something + ] + ]. + dispObjs := OrderedCollection new. + + list do:[:el| + |obj asc| + + obj := self displayObjectFor:el on:device. + asc := (obj respondsTo:#string) ifTrue:[ascent] ifFalse:[0]. + height := height + space. + + dispObjs add:(Array with:obj with:(0 @ (height + asc))). + width := width max:(obj widthOn:aView). + height := height + (obj heightOn:aView). + ]. + + offset := self computeOffset:anOffset w:width h:height. + + dispObjs do:[:el| el at:2 put:((el at:2) - offset) ]. + + self startOpaqueDrag:[:p :v| dispObjs do:[:el| (el at:1) displayOn:v at:p + (el at:2)] ] + offset:offset + extent:width @ height + in:aView + at:nil + atEnd:aFourArgBlock +! + +startDrag:draggableObjects from:aView offset:anOffset display:something + "start a drop at the current pointer position. + " + ^ self startDrag:draggableObjects + from:aView + offset:anOffset + atEnd:nil + display:something ! ! !DragAndDropManager methodsFor:'dragging - generic'! -doGenericDragX:x y:y - "drag to x/y; see if the target view allows a drop - and change the mouse pointer as appropriate" - - |view newCursor| - - previousPoint notNil ifTrue:[ - (opaque and:[dragSize notNil]) ifTrue:[ - self restoreGenericAt:previousPoint - ] ifFalse:[ - self invertGenericAt:previousPoint - ] - ]. - previousPoint := x @ y. - lastScreenPosition := nil. - - view := self destinationViewAt:previousPoint. - view ~~ lastView ifTrue:[ - view isNil ifTrue:[ - "/ alien view - dont know if it likes a drop - newCursor := Cursor questionMark - ] ifFalse:[ - "/ ST/X view - ask it. - (self askIfCanDrop:dropObjects in:view) ifTrue:[ - newCursor := Cursor thumbsUp - ] ifFalse:[ - newCursor := Cursor thumbsDown - ] - ]. - dragView cursor:newCursor now:true. - lastView := view - ]. - - (opaque and:[dragSize notNil]) ifTrue:[ - self drawGenericAt:previousPoint. - ] ifFalse:[ - self invertGenericAt:previousPoint - ]. - - "Modified: 19.4.1997 / 11:33:54 / cg" -! - -endGenericDragX:x y:y - "finish a drag; restore from saveUnder (or reinvert), - then call for the endAction" - - previousPoint notNil ifTrue:[ - (opaque and:[dragSize notNil]) ifTrue:[ - self restoreGenericAt:previousPoint - ] ifFalse:[ - self invertGenericAt:previousPoint - ] - ]. - previousPoint := nil. - self uncatchEvents. - self endDragAt:x @ y - - "Created: 26.10.1996 / 15:17:20 / cg" - "Modified: 19.4.1997 / 10:41:57 / cg" -! - startGenericDrag:aTwoArgDragBlock in:aView at:p atEnd:aFourArgEndBlock "start a generic (caller-provided drag); Here, an inverting drag is initiated (i.e. the drawing is undone @@ -540,292 +846,163 @@ 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. - - "Created: 26.10.1996 / 15:16:13 / cg" - "Modified: 19.4.1997 / 10:44:32 / cg" + the dropPoint in root-coordinates and the dropPoint within the targetView + " + ^ self startOpaqueDrag:aTwoArgDragBlock + offset:nil + extent:nil + in:aView + at:nil + atEnd:aFourArgEndBlock ! -startOpaqueDrag:aTwoArgDragBlock offset:offs extent:ext in:aView at:p atEnd:aFourArgEndBlock - "start a generic opaque (caller-provided drag); +startOpaqueDrag:aDragBlock offset:offs extent:anExtent in:aView at:aDummyPoint atEnd:aFourArgEndBlock + "start an opaque or 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. + and restored. The areas size to be saved/restored is passed in anExtent. + the dragBlock, aDragBlock will be called with up to three args aPoint, a + drawingGC and the display objects, 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. + the dropPoint in root-coordinates and the dropPoint within the targetView + " + |handler numArgs dragBlock dobjs| - "Modified: 26.10.1996 / 15:09:26 / cg" - "Created: 26.10.1996 / 15:16:13 / cg" - -! ! - -!DragAndDropManager methodsFor:'dragging - generic - inverting'! - -invertGenericAt:ip - "draw for a generic inverting drag" - - |t offs p rootView| - - rootView := dragView device rootView. + dragOffset := offs ? (Point x:0 y:0). + numArgs := aDragBlock numArgs. - (p := lastScreenPosition) isNil ifTrue:[ - 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. - - lastScreenPosition := p. - ]. - - rootView clippedByChildren:false. - rootView xoring:[ - rootView lineWidth:0. - self callForDragActionAt:p in:rootView. - rootView flush + numArgs == 3 ifTrue:[ + dobjs := self dropObjects. + dragBlock := [:p :v| aDragBlock value:p value:v value:dobjs ] + ] ifFalse:[ + numArgs == 1 ifTrue:[ + dragBlock := [:p :v| aDragBlock value:p ] + ] ifFalse:[ + dragBlock := aDragBlock + ] ]. - "Created: 26.10.1996 / 15:15:26 / cg" - "Modified: 19.4.1997 / 11:35:33 / cg" -! ! - -!DragAndDropManager methodsFor:'dragging - generic - opaque'! - -drawGenericAt:ip - "draw for a generic opaque drag" - - |t offs p rootView szX szY| - - rootView := dragView device rootView. - - p := ip. - - "/ - "/ get device coordinates - "/ - (t := dragView transformation) notNil ifTrue:[ - p := t applyTo:p. + anExtent isNil ifTrue:[ + handler := DragHandler startGenericDrag:dragBlock. + ] ifFalse:[ + handler := DragHandler startOpaqueDrag:dragBlock extent:anExtent offset:dragOffset. ]. - - "/ - "/ translate to screen - "/ - offs := dragView device - translatePoint:0@0 - from:(dragView id) to:(rootView id). - p := p + offs. - - rootView clippedByChildren:false. + self doStart:handler for:aView atEnd:aFourArgEndBlock - "/ - "/ copy from screen to saveUnder - "/ - szX := dragSize x. - szY := dragSize y. - saveUnder isNil ifTrue:[ - saveUnder := Form - width:szX - height:szY - depth:rootView device depth - on:dragView device. - saveUnder clippedByChildren:false. - ]. - - lastScreenPosition := p - dragOffset. - saveUnder - copyFrom:rootView - x:lastScreenPosition x - y:lastScreenPosition y - toX:0 - y:0 - width:szX - height:szY. - - "/ - "/ draw using the dragAction block - "/ - rootView lineWidth:0. - self callForDragActionAt:p in:rootView. - rootView flush - - "Modified: 19.4.1997 / 10:45:48 / cg" -! - -restoreGenericAt:ip - "restore from saveUnder for a generic opaque drag" - - |rootView| - - rootView := dragView device rootView. - - "/ - "/ copy from saveUnder back to screen - "/ - rootView clippedByChildren:false. - rootView - copyFrom:saveUnder - x:0 y:0 - toX:lastScreenPosition x y:lastScreenPosition y - width:dragSize x - height:dragSize y. - - "Modified: 19.4.1997 / 10:46:39 / cg" ! ! !DragAndDropManager methodsFor:'dragging - lines'! -doLineDragX:x y:y - "do a line drag - invert previous and draw at new position" - - previousPoint notNil ifTrue:[ - self invertLineFrom:initialPoint to:previousPoint - ]. - previousPoint := x @ y. - self invertLineFrom:initialPoint to:previousPoint - - "Modified: 19.4.1997 / 12:39:43 / cg" -! +startArrowDragIn:aView at:aStartPoint atEnd:aFourArgEndBlock + "start a line-drag of an arrow-line. + The drag starts in aView at point aStartPoint. + 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 + " + |p| -endLineDragX:x y:y - "end a line drag - invert previous, deinstall event catcher - and call for endDrag action" - - previousPoint notNil ifTrue:[ - self invertLineFrom:initialPoint to:previousPoint - ]. + p := self translatePointToScreen:aStartPoint from:aView. - previousPoint := nil. - dragView device sync. - - self uncatchEvents. - self endDragAt:x @ y. - - "Created: 26.10.1996 / 15:17:20 / cg" - "Modified: 19.4.1997 / 12:40:14 / cg" + self doStart:(DragHandler startArrowDragAt:p) + for:aView + atEnd:aFourArgEndBlock ! -invertLineFrom:ip1 to:ip2 - "invert for a line drag" - - |t offs p1 p2 rootView a| - - rootView := dragView device rootView. - - p1 := ip1. - p2 := ip2. - - " - get device coordinates - " - (t := dragView transformation) notNil ifTrue:[ - p1 := t applyTo:p1. - p2 := t applyTo:p2. - ]. - - " - translate to screen - " - offs := dragView device - translatePoint:0@0 - from:(dragView id) to:(rootView id). - p1 := p1 + offs. - p2 := p2 + offs. - - rootView clippedByChildren:false. - rootView xoring:[ - rootView lineWidth:0. - lineMode == #arrow ifTrue:[ - a := Arrow from:p1 to:p2. - a arrowHeadLength:(rootView device horizontalPixelPerMillimeter * 4) rounded. - a displayFilledOn:rootView. - ] ifFalse:[ - rootView displayLineFrom:p1 to:p2. - ]. - rootView flush - ]. - - "Created: 26.10.1996 / 15:15:26 / cg" - "Modified: 19.4.1997 / 12:40:29 / cg" -! - -startArrowDragIn:aView at:p atEnd:aBlock - "start a line-drag of an arrow-line. - The drag starts in aView at point p. +startLineDragIn:aView at:aStartPoint atEnd:aFourArgEndBlock + "start a line-drag of a normal line. + The drag starts in aView at point aStartPoint. 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 := #doLineDragX:y:. - releaseAction := #endLineDragX:y:. - initialPoint := p. - previousPoint := nil. - dragBlock := nil. - lineMode := #arrow. - dropAction := aBlock. - - "Modified: 26.10.1996 / 15:09:26 / cg" - "Created: 26.10.1996 / 15:16:13 / cg" - -! + the dropPoint in root-coordinates and the dropPoint within the targetView + " + |p| -startLineDragIn:aView at:p atEnd:aFourArgEndBlock - "start a line-drag of a normal line. - 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" + p := self translatePointToScreen:aStartPoint from:aView. - self catchEventsFrom:aView. - motionAction := #doLineDragX:y:. - releaseAction := #endLineDragX:y:. - initialPoint := p. - previousPoint := nil. - dragBlock := nil. - lineMode := nil. - dropAction := aFourArgEndBlock. - - "Modified: 26.10.1996 / 15:09:26 / cg" - "Created: 26.10.1996 / 15:16:13 / cg" - + self doStart:(DragHandler startLineDragAt:p) + for:aView + atEnd:aFourArgEndBlock ! ! !DragAndDropManager methodsFor:'drawing'! +computeOffset:anOffset w:w h:h + |p| + + anOffset isSymbol ifFalse:[ + ^ anOffset notNil ifTrue:[anOffset] ifFalse:[0@0] + ]. + anOffset == #topLeft ifTrue:[ ^ 0 @ 0]. + anOffset == #topRight ifTrue:[ ^ w @ 0]. + + anOffset == #bottomLeft ifTrue:[ ^ 0 @ h]. + anOffset == #bottomRight ifTrue:[ ^ w @ h]. + + p := (w @ h) // 2. + + anOffset == #center ifTrue:[ ^ p ]. + + anOffset == #topCenter ifTrue:[ ^ p x @ 0 ]. + anOffset == #bottomCenter ifTrue:[ ^ p x @ h ]. + + anOffset == #leftCenter ifTrue:[ ^ 0 @ p y ]. + anOffset == #rightCenter ifTrue:[ ^ w @ p y ]. + + Transcript showCR:'unsupported offset: ', anOffset printString. + ^ 0 @ 0 +! + +displayObjectFor:anObject on:aDevice + "converts an object to a display object + " + |obj icon s1 s2| + + obj := (anObject respondsTo:#displayObject) ifTrue:[anObject displayObject] + ifFalse:[anObject]. + + obj isString ifTrue:[ + ^ obj + ]. + + obj messageNotUnderstoodSignal handle:[:ex|] do:[ + obj := obj on:aDevice + ]. + + obj isImage ifTrue:[ + ^ obj clearMaskedPixels + ]. + + obj class == LabelAndIcon ifTrue:[ + obj image notNil ifTrue:[obj image clearMaskedPixels]. + obj icon notNil ifTrue:[obj icon clearMaskedPixels]. + ^ obj + ]. + + (obj class == MultiColListEntry) ifFalse:[ + ^ obj + ]. + s1 := obj colAt:1. + s2 := obj colAt:2. + + s1 isImage ifTrue:[ + s2 isImage ifTrue:[ ^ self displayObjectFor:(LabelAndIcon form:s1 image:s2) on:aDevice ]. + s2 isString ifTrue:[ ^ self displayObjectFor:(LabelAndIcon icon:s1 string:s2) on:aDevice ]. + ^ (s1 on:aDevice) clearMaskedPixels + ]. + + s2 isImage ifTrue:[ + s1 isString ifTrue:[ ^ self displayObjectFor:(LabelAndIcon icon:s2 string:s1) on:aDevice ]. + ^ (s2 on:aDevice) clearMaskedPixels + ]. + + s1 isString ifTrue:[^ s1]. + s2 isString ifTrue:[^ s2]. + ^ obj +! + showDragging:items in:aView at:p "helper for dragging dragObjects: draw them all" @@ -840,499 +1017,299 @@ "Modified: 19.4.1997 / 12:41:24 / cg" ! ! -!DragAndDropManager methodsFor:'dropping'! - -drop:something in:targetView at:aPoint from:sourceView ifOk:okAction ifFail:failAction - "try to drop some object in a targetView; - if any view along the targetViews superView chain takes it, - the okAction is evaluated; if not, failAction is evaluated. - This may be sent from a drag initiators endDrag block." - - |v pnt| - - v := targetView. - pnt := aPoint. - - [v notNil] whileTrue:[ - (self askIfCanDrop:something in:v) ifTrue:[ - v - drop:something - at:aPoint - from:sourceView - with:[:o | okAction. ^ true] - ifFail:[:o | failAction. ^ false]. - ]. - v := v superView. - pnt := nil - ]. - failAction value. - ^ false - - "Modified: 19.4.1997 / 12:42:36 / cg" -! ! - -!DragAndDropManager methodsFor:'easy drag & drop'! - -startDrag:anObjectOrCollection from:aView offset:anOffset - "start a drop at the current pointer position" - - self startDrag:anObjectOrCollection from:aView offset:anOffset atEnd:nil - -! - -startDrag:anObjectOrCollection from:aView offset:anOffset atEnd:aFourArgEndBlock - "start a drop at the current pointer position. - 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" - - - |x y pos displayObjects device width height| - - self dropObjects:anObjectOrCollection. - - device := aView device. - pos := device translatePoint:(device pointerPosition) - from:(device rootView id) - to:(aView id). - - displayObjects := dropObjects collect:[:each | each displayObject on:device]. - height := displayObjects inject:0 into:[:sum :each | sum + (each heightOn:aView)]. - width := displayObjects inject:0 into:[:max :each | max max:(each widthOn:aView)]. - - x := anOffset x. - y := anOffset y. - - (displayObjects at:1) class == LabelAndIcon ifTrue:[ - y := y + aView font ascent. - width := width * 2. - ]. - - self startOpaqueDrag:[:aPoint :aView|self showDragging:displayObjects in:aView at:(aPoint - anOffset)] - offset:(x @ y) - extent:(width @ height) - in:aView - at:pos - atEnd:aFourArgEndBlock. - -! - -startDrag:anObjectOrCollection from:aView offset:anOffset atEnd:aFourArgEndBlock useIcon:anIcon - "start a drop at the current pointer position. - 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" - - - |pos displayObjects device| - - self dropObjects:anObjectOrCollection. - - device := aView device. - pos := device translatePoint:(device pointerPosition) - from:(device rootView id) - to:(aView id). - - displayObjects := Array with:(anIcon on:device). - - self startOpaqueDrag:[:aPoint :aView|self showDragging:displayObjects in:aView at:(aPoint - anOffset)] - offset:anOffset - extent:(anIcon extent) - in:aView - at:pos - atEnd:aFourArgEndBlock. - -! - -startDrag:anObjectOrCollection from:aView offset:anOffset useIcon:anIcon - "start a drop at the current pointer position. - 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 startDrag:anObjectOrCollection from:aView offset:anOffset atEnd:nil useIcon:anIcon -! ! - !DragAndDropManager methodsFor:'event catching'! buttonMotion:button x:x y:y view:aView - self perform:motionAction with:x with:y + "handle a button motion event + " + |oldPt oldTgt oldWg oldId newWg newId newTgt point rootId cursor device isDroppable| + + device := dragView device. + rootId := device rootView id. + point := self translatePointToScreen:(x @ y) from:dragView. + oldWg := dropContext targetWidget. + oldId := dropContext targetId. + oldPt := dropContext rootPoint. + + dropContext rootPoint:point. + + "/ + "/ search view the drop is in + "/ + [ newId := rootId. + (rootId := device viewIdFromPoint:point in:newId) notNil + ] whileTrue. + + newWg := device viewFromId:newId. + dropContext targetWidget:newWg id:newId. + + handler isInterestedInDropTarget ifFalse:[ + "/ + "/ line or arrow handler + "/ + handler dragTo:point. + ^ self + ]. + + oldWg ~~ newWg ifTrue:[ + "/ + "/ widget has changed: drop target might change + "/ + oldTgt := dropContext dropTarget. + newTgt := self doFindDropTargetIn:newWg at:point. + + newTgt ~= oldTgt ifTrue:[ + "/ + "/ drop target changed: handler might restore the screen + "/ + handler dropTargetWillChange. - "Created: 26.10.1996 / 15:09:00 / cg" + oldTgt notNil ifTrue:[ + "/ + "/ setup old context + "/ + dropContext targetWidget:oldWg id:oldId. + oldTgt leave:dropContext. + dropContext targetWidget:newWg id:newId. + ]. + dropContext dropTarget:newTgt. + newTgt notNil ifTrue:[ newTgt enter:dropContext ] + ] ifFalse:[ + dropContext dropTarget:newTgt + ] + ] ifFalse:[ + (oldPt notNil and:[(oldPt dist:point) < 2 ]) ifTrue:[ + "/ + "/ ignorre the button motion event; restore old rootPoint + "/ + dropContext rootPoint:oldPt. + ^ self + ]. + newTgt := dropContext dropTarget + ]. + "/ + "/ update the cursor + "/ + (isDroppable := dropContext canDrop) ifTrue:[ + cursor := enabledCursor + ] ifFalse:[ + cursor := dropContext isAlienView ifFalse:[disabledCursor] + ifTrue:[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 + ]. + newTgt notNil ifTrue:[ newTgt over:dropContext ]. + handler dragTo:point. +! +buttonMultiPress:button x:x y:y view:aView + "discard each buttonMultiPress event + " +! + +buttonPress:button x:x y:y view:aView + "discard each buttonPress event + " ! buttonRelease:button x:x y:y view:aView - self perform:releaseAction with:x with:y. + "button released; do the drop + " + ((button == 2) or:[button == #menu]) ifTrue:[ + ^ self + ]. + "/ + "/ update the context + "/ + self buttonMotion:button x:x y:y view:aView. + + "/ + "/ restore source view + "/ + restoreBlock value. - "Modified: 19.4.1997 / 12:37:02 / cg" + "/ + "/ at least do the drop operation + "/ + dropAction isNil ifTrue:[ + dropContext doDrop + ] ifFalse:[ + "/ + "/ initiator wants to do it himself, manually. + "/ Thus, no feedBack operation invoked. + "/ + dropAction value:(dropContext targetWidget) + value:(dropContext targetId) + value:(dropContext rootPoint) + value:(dropContext targetPoint). + ] ! handlesButtonMotion:button inView:aView "query from event processor: am I interested in button-events ? yes I am (to activate the clicked-on field)." - ^ aView == dragView + ^ dragView == aView +! + +handlesButtonMultiPress:button inView:aView + "query from event processor: am I interested in button-events ? + yes I am (to activate the clicked-on field)." - "Created: 26.10.1996 / 15:05:36 / cg" + ^ dragView == aView +! +handlesButtonPress:button inView:aView + "query from event processor: am I interested in button-events ? + yes I am (to activate the clicked-on field)." + + ^ dragView == aView ! handlesButtonRelease:button inView:aView "query from event processor: am I interested in button-events ? yes I am (to activate the clicked-on field)." - ^ aView == dragView + ^ dragView == aView +! ! + +!DragAndDropManager methodsFor:'initialization'! - "Created: 26.10.1996 / 15:05:48 / cg" +initialize + super initialize. + dragOffset := 0 @ 0. + dropContext := DropContext new. + alienCursor := Cursor questionMark. + enabledCursor := Cursor thumbsUp. + disabledCursor := Cursor thumbsDown. + canDrop := false. ! ! !DragAndDropManager methodsFor:'private'! -askIfCanDrop:dropObjects in:aView - |canDrop| +doDrop:aContext in:aWidget + "old drop mechanism + " + |point| DragOriginatorQuerySignal answer:dragView do:[ DragOffsetQuerySignal answer:dragOffset do:[ - canDrop := aView canDrop:dropObjects - ]. - ]. - ^ canDrop - - "Modified: 11.8.1997 / 00:55:10 / cg" -! - -callForDragActionAt:aPoint in:aView - "evaluate the user supplied dragAction. - Look how many args it expects and invoke with - position - dragView - dragObjects" - - |numArgs| - - (numArgs := dragBlock numArgs) == 1 ifTrue:[ - dragBlock value:aPoint - ] ifFalse:[ - numArgs == 2 ifTrue:[ - dragBlock value:aPoint value:aView - ] ifFalse:[ - dragBlock value:aPoint value:aView value:dropObjects. - ] - ] - - "Created: 19.4.1997 / 10:05:55 / cg" -! - -catchEventsFrom:aView - dragView := aView. - saveCursor := dragView cursor. - - rememberedDelegate := aView delegate. - aView delegate:self. - aView device grabPointerInView:aView. - - "Modified: 19.4.1997 / 12:36:04 / 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 rootId viewId offs destinationId lastViewId destinationView - rootView destinationPoint device| - - dragView cursor:saveCursor now:true. - device := dragView device. - device ungrabPointer. - rootView := device rootView. - rootPoint := ip. - - " - get device coordinates - " - (t := dragView transformation) notNil ifTrue:[ - rootPoint := t applyTo:ip. - ]. - viewId := rootId := rootView id. - - " - translate to screen - " - offs := device translatePoint:0@0 from:(dragView id) to:rootId. - 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. - - "/ - "/ translate to destination view - "/ - destinationPoint := device translatePoint:rootPoint from:rootId to:destinationId. - - "/ - "/ if the destinationView has a transformation, - "/ also translate to logical coordinates .. - "/ - destinationView notNil ifTrue:[ - (t := destinationView transformation) notNil ifTrue:[ - destinationPoint := t applyInverseTo:destinationPoint + aContext targetWidget == aWidget ifTrue:[ + point := aContext targetPoint + ] ifFalse:[ + point := nil. + "/ + "/ FeedBack: set the widget which handles the drop + "/ + aContext targetWidget:aWidget id:(aWidget id). + ]. + aWidget drop:(aContext dropObjects) at:point ] ]. - "/ - "/ if this dragOperation has an explicit dropAction, - "/ perform it. - "/ - dropAction notNil ifTrue:[ - "/ initiator wants to do it himself, manually. - - dropAction value:destinationView - value:destinationId - value:rootPoint - value:destinationPoint. - ^ self - ]. - - "/ default drop behavior: - "/ if its one of my own views, ask if dropping is ok. - "/ if not, ask the device to drop it. - - destinationView notNil ifTrue:[ - "/ - "/ one of my views - "/ - - DragOriginatorQuerySignal answer:dragView do:[ - DragOffsetQuerySignal answer:dragOffset do:[ - "/ - "/ see if the view itself can drop that stuff ... - "/ - (destinationView canDrop:dropObjects) ifTrue:[ - destinationView drop:dropObjects at:destinationPoint. - ^ self. - ]. - - "/ - "/ try superViews along the chain ... - "/ - destinationView := destinationView superView. - [destinationView notNil] whileTrue:[ - (destinationView canDrop:dropObjects) ifTrue:[ - destinationView drop:dropObjects at:nil. - ^ self. - ]. - destinationView := destinationView superView. - ]. - ]. - ]. - ^ self - ]. - - "/ - "/ not one of my views - "/ - - "/ external clipboard mechanism via display - device - drop:dropObjects - inWindowID:destinationId - position:destinationPoint - rootPosition:rootPoint - - "Modified: 11.8.1997 / 00:55:41 / cg" ! -uncatchEvents - dragView delegate:rememberedDelegate. - - "Created: 26.10.1996 / 15:22:29 / cg" - +doFindDropTargetIn:aView at:aPoint + "get the drop target for a view and source at a point or nil " - DragAndDropManager allInstancesDo:[:m | - m uncatchEvents - ] - " -! ! - -!DragAndDropManager::DemoView class methodsFor:'documentation'! + |target view dobj| -documentation -" - demonstrates rubber-line dragging. - - See the buttonPress method, where a drag is initiated. - At endDrop, look at the transcript. + aView isNil ifTrue:[ ^ nil ]. + "/ + "/ new mechanism to get a dropTarget + "/ + aView messageNotUnderstoodSignal handle:[:ex| + target := nil. + ] do:[ + target := aView dropTarget + ]. + target notNil ifTrue:[ ^ target ]. + "/ + "/ old mechanism to get a dropTarget + "/ + view := aView. + dobj := dropContext dropObjects. - [author:] - Claus Gittinger - - [start with:] - DemoView new open -" -! ! - -!DragAndDropManager::DemoView methodsFor:'events'! + DragOriginatorQuerySignal answer:dragView do:[ + DragOffsetQuerySignal answer:dragOffset do:[ + [ (view canDrop:dobj) ifTrue:[ + ^ DropTarget receiver:self argument:view dropSelector:#doDrop:in:. + ]. + (view := view superView) notNil -buttonPress:button x:x y:y - DragAndDropManager new - startLineDragIn:self at:(x@y) - atEnd:[:view - :viewID - :rootPoint - :viewPoint | + ] whileTrue. + ] + ]. + ^ nil +! - Transcript show:'dropped at '; - show:viewPoint; - show:' (screen: '; - show:rootPoint; - show:') in '. - view notNil ifTrue:[ - Transcript showCR:view - ] ifFalse:[ - Transcript show:'alien view '; - showCR:viewID address - ] - ]. - +doStart:aHandler for:aView atEnd:aFourArgEndBlock + "setup a handler and a restore block " - self new open - " - - "Modified: 19.4.1997 / 11:40:46 / cg" -! ! + |cursor delegate| -!DragAndDropManager::DemoView2 class methodsFor:'documentation'! + dropContext sourceWidget:aView. -documentation -" - demonstrates string dragging. + dragOffset isNil ifTrue:[ dragOffset := 0 @ 0 ]. + alienCursor isNil ifTrue:[ alienCursor := disabledCursor ]. - See the buttonPress method, where a drag is initiated. - At endDrop, look at the transcript. - + dragView := aView. + dropAction := aFourArgEndBlock. + cursor := aView cursor. + delegate := aView delegate. + handler := aHandler. - [author:] - Claus Gittinger + restoreBlock := [ + aHandler postDragging. + aView delegate:delegate. + aView cursor:cursor now:true. + aView device ungrabPointer + ]. - [start with:] - DemoView2 new open -" - + aHandler preDraggingIn:aView. + aView delegate:self. + aView device grabPointerInView:aView. ! ! -!DragAndDropManager::DemoView2 methodsFor:'events'! +!DragAndDropManager methodsFor:'translation'! -buttonPress:button x:x y:y - DragAndDropManager new - startGenericDrag:[:p :v | v displayString:'hello' at:p] - in:self - at:(x@y) - atEnd:[:view - :viewID - :rootPoint - :viewPoint | ] - - - " - self new open +translatePointToScreen:aPoint from:aView + "translate a point to screen " - - -! ! - -!DragAndDropManager::DemoView3 class methodsFor:'documentation'! - -documentation -" - demonstrates arrow-line dragging. - - See the buttonPress method, where a drag is initiated. - At endDrop, look at the transcript. - - [author:] - Claus Gittinger + |device trans point offset| - [start with:] - DemoView3 new open -" - - -! ! - -!DragAndDropManager::DemoView3 methodsFor:'events'! - -buttonPress:button x:x y:y - DragAndDropManager new - startArrowDragIn:self - at:(x@y) - atEnd:[:view - :viewID - :rootPoint - :viewPoint | + device := aView device. + "/ + "/ get device coordinates + "/ + (trans := aView transformation) notNil ifTrue:[ + point := trans applyTo:aPoint + ] ifFalse:[ + point := aPoint + ]. + "/ + "/ translate to screen + "/ + offset := device translatePoint:0@0 from:(aView id) to:(device rootView id). + ^ offset + point - Transcript show:'dropped at '; - show:viewPoint; - show:' (screen: '; - show:rootPoint; - show:') in '. - view notNil ifTrue:[ - Transcript showCR:view - ] ifFalse:[ - Transcript show:'alien view '; - showCR:viewID address - ] - ]. - - " - self new open - " - - "Modified: 19.4.1997 / 12:45:29 / cg" ! ! !DragAndDropManager class methodsFor:'documentation'! version - ^ '$Header: /cvs/stx/stx/libview2/DragAndDropManager.st,v 1.18 1998-03-09 16:06:35 ca Exp $' + ^ '$Header: /cvs/stx/stx/libview2/DragAndDropManager.st,v 1.19 1998-03-30 12:02:15 ca Exp $' ! ! DragAndDropManager initialize!