--- 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!