"
COPYRIGHT (c) 1998 by eXept Software AG / Claus Gittinger
All Rights Reserved
This software is furnished under a license and may be used
only in accordance with the terms of that license and with the
inclusion of the above copyright notice. This software may not
be provided or otherwise made available to, or used by, any
other person. No title to or ownership of the software is
hereby transferred.
"
"{ Package: 'stx:libview2' }"
Object subclass:#DragHandler
instanceVariableNames:'rootView lastRootPoint'
classVariableNames:''
poolDictionaries:''
category:'Interface-DragAndDrop'
!
DragHandler subclass:#Generic
instanceVariableNames:'prevPoint lastPoint dragBlock'
classVariableNames:''
poolDictionaries:''
privateIn:DragHandler
!
DragHandler subclass:#Line
instanceVariableNames:'startPoint endPoint lineMode'
classVariableNames:''
poolDictionaries:''
privateIn:DragHandler
!
DragHandler subclass:#Opaque
instanceVariableNames:'dragSize dragBlock dragOffset saveUnder saveArea tmpForm'
classVariableNames:''
poolDictionaries:''
privateIn:DragHandler
!
!DragHandler class methodsFor:'documentation'!
copyright
"
COPYRIGHT (c) 1998 by eXept Software AG / Claus Gittinger
All Rights Reserved
This software is furnished under a license and may be used
only in accordance with the terms of that license and with the
inclusion of the above copyright notice. This software may not
be provided or otherwise made available to, or used by, any
other person. No title to or ownership of the software is
hereby transferred.
"
!
documentation
"
this abstract class describes the protocol common to any DragHandler.
The DragAndDropManger creates one instance responsible to show the
dragging objects on the screen.
[author:]
Claus Gittinger
[see also:]
DragAndDropManager
"
! !
!DragHandler class methodsFor:'instance creation'!
startArrowDragAt:aStartPoint
"creates and returns the drag handler which is responsible
for an arrow drag.
"
^ Line new startPoint:aStartPoint mode:#arrow
!
startGenericDrag:aTwoArgDragBlock
"creates and returns the drag handler which is responsible
for a generic drag.
"
^ Generic new dragBlock:aTwoArgDragBlock
!
startLineDragAt:aStartPoint
"creates and returns the drag handler which is responsible
for a line drag.
"
^ Line new startPoint:aStartPoint mode:nil
!
startOpaqueDrag:aTwoArgDragBlock extent:anExtent offset:anOffset
"creates and returns the drag handler which is responsible
for a generic opaque drag.
"
^ Opaque new dragSize:anExtent dragOffset:anOffset dragBlock:aTwoArgDragBlock
! !
!DragHandler methodsFor:'event dropTarget'!
dropTargetWillChange
"called before the drop target or widget changed.
restore root view ... (optional)
"
!
isInterestedInDropTarget
"returns true, if the handler is interested in the underlying
drop target and the target should be tested to be able to drop
the objects.
"
^ true
! !
!DragHandler methodsFor:'protocol'!
dragTo:aRootPoint
"drag to a root point
"
self subclassResponsibility
!
flushSaveArea
!
postDragging
"after dragging; restore root view ...
"
self subclassResponsibility
!
preDraggingIn:aSourceWidget
"called before starting the drag & drop operation
"
rootView := aSourceWidget device rootView.
!
rereadSaveArea
! !
!DragHandler::Generic class methodsFor:'documentation'!
documentation
"
this class handles a generic drag on the screen. It is not visible to
the user and is created automatically by the DragAndDropManger.
[author:]
Claus Gittinger
[see also:]
DragAndDropManager
"
! !
!DragHandler::Generic methodsFor:'instance creation'!
dragBlock:aTwoArgBlock
"the dragBlock will be called with two arguments, aPoint and the drawing GC,
to perform the drawing at some dragPoint.
"
dragBlock := aTwoArgBlock
! !
!DragHandler::Generic methodsFor:'protocol'!
dragTo:aRootPoint
"drag to a root point
"
prevPoint notNil ifTrue:[
self postDragging
].
lastPoint := nil.
prevPoint := lastRootPoint := aRootPoint.
self postDragging
!
postDragging
lastPoint isNil ifTrue:[
lastPoint := prevPoint.
].
rootView clippedByChildren:false.
rootView xoring:[
rootView lineWidth:0.
dragBlock value:lastPoint value:rootView.
rootView flush
]
! !
!DragHandler::Line class methodsFor:'documentation'!
documentation
"
this class handles a line or arrow drag on the screen. It is not visible to
the user and is created automatically by the DragAndDropManger.
[author:]
Claus Gittinger
[see also:]
DragAndDropManager
"
! !
!DragHandler::Line methodsFor:'event dropTarget'!
isInterestedInDropTarget
^ false
! !
!DragHandler::Line methodsFor:'instance creation'!
startPoint:aPoint mode:aMode
lineMode := aMode.
startPoint := aPoint.
! !
!DragHandler::Line methodsFor:'protocol'!
dragTo:aRootPoint
"do a line or arrow drag
"
self postDragging.
endPoint := lastRootPoint := aRootPoint.
self postDragging.
!
postDragging
"invert for a line or arrow drag
"
|arrow|
endPoint isNil ifTrue:[
^ self
].
rootView clippedByChildren:false.
rootView xoring:[
rootView lineWidth:0.
lineMode == #arrow ifTrue:[
arrow := Arrow from:startPoint to:endPoint.
arrow arrowHeadLength:(rootView device horizontalPixelPerMillimeter * 4) rounded.
arrow displayFilledOn:rootView.
] ifFalse:[
rootView displayLineFrom:startPoint to:endPoint.
].
rootView flush
]
! !
!DragHandler::Opaque class methodsFor:'constants'!
additionalSaveSize
^ 50 @ 50
! !
!DragHandler::Opaque class methodsFor:'documentation'!
documentation
"
this class handles an generic opaque drag on the screen. It is not visible
to the user and is created automatically by the DragAndDropManger.
[author:]
Claus Gittinger
[see also:]
DragAndDropManager
"
! !
!DragHandler::Opaque methodsFor:'instance creation'!
dragSize:anExtent dragOffset:anOffset dragBlock:aTwoArgBlock
"the dragBlock will be called with two arguments, aPoint and the drawing GC,
to perform the drawing at some dragPoint.
"
dragSize := anExtent.
dragOffset := anOffset.
dragBlock := aTwoArgBlock
! !
!DragHandler::Opaque methodsFor:'protocol'!
dragTo:aRootPoint
"drag to a root point
"
|p extent point area|
(saveArea notNil and:[lastRootPoint notNil]) ifTrue:[
( lastRootPoint x == aRootPoint x
and:[lastRootPoint y == aRootPoint y]
) ifTrue:[
"/ nothing changed
^ self
].
].
lastRootPoint := aRootPoint.
"/
"/ copy from screen to saveUnder
"/
rootView clippedByChildren:false.
extent := saveUnder extent.
point := aRootPoint - dragOffset.
saveArea notNil ifTrue:[
( (saveArea left <= point x)
and:[(saveArea top <= point y)
and:[(saveArea right >= (point x + dragSize x))
and:[(saveArea bottom >= (point y + dragSize y))]]]
) ifFalse:[
"/
"/ draggable objects no longer contained in saved area;
"/ thus we have to restore the saved area on the screen.
"/
self postDragging
]
].
saveArea isNil ifTrue:[
"/
"/ screen not yet saved; thus we have to save the area
"/
p := point - (self class additionalSaveSize).
saveUnder copyFrom:rootView
x:p x
y:p y
toX:0
y:0
width:extent x
height:extent y.
saveArea := p extent:extent.
].
area := saveArea.
"/
"/ draw into the form using the dragAction block
"/
tmpForm copyFrom:saveUnder toX:0 y:0.
tmpForm paint:Color black.
dragBlock value:(point - saveArea origin + dragOffset) value:tmpForm.
area == saveArea ifFalse:[
"saveArea changed during dragB;lock operation"
^ self
].
rootView copyFrom:tmpForm
x:area origin x
y:area origin y
width:extent x
height:extent y
!
dropTargetWillChange
"restore old saveArea
"
self postDragging
!
flushSaveArea
saveArea := nil
!
postDragging
"restore from saveUnder for a generic opaque drag
"
saveArea notNil ifTrue:[
rootView clippedByChildren:false.
"/
"/ copy from saveUnder back to screen
"/
rootView copyFrom:saveUnder
x:saveArea origin x
y:saveArea origin y
width:saveArea extent x
height:saveArea extent y.
saveArea := nil.
]
!
preDraggingIn:aSourceWidget
"setup my default values
"
|depth extent device|
super preDraggingIn:aSourceWidget.
device := aSourceWidget device.
depth := rootView device depth.
extent := dragSize + (2 * (self class additionalSaveSize)).
saveUnder := Form extent:extent depth:depth on:device.
tmpForm := Form extent:extent depth:depth on:device.
saveUnder clippedByChildren:false.
tmpForm initGC.
tmpForm font:(aSourceWidget font).
!
rereadSaveArea
saveArea notNil ifTrue:[
rootView clippedByChildren:false.
"/
"/ copy from saveUnder back to screen
"/
saveUnder copyFrom:rootView
x:saveArea origin x
y:saveArea origin y
width:saveArea extent x
height:saveArea extent y.
]
!
restoreFromSaveArea
lastRootPoint notNil ifTrue:[
self dragTo:lastRootPoint
].
! !
!DragHandler class methodsFor:'documentation'!
version
^ '$Header: /cvs/stx/stx/libview2/DragHandler.st,v 1.7 2005-05-30 19:23:27 ab Exp $'
! !