DragHandler.st
changeset 873 c5cd8f56dc6e
child 1487 6cefff982779
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DragHandler.st	Mon Mar 30 14:00:30 1998 +0200
@@ -0,0 +1,429 @@
+"
+ 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.
+"
+
+
+
+
+Object subclass:#DragHandler
+	instanceVariableNames:'rootView'
+	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
+
+
+!
+
+postDragging
+    "after dragging; restore root view ...
+    "
+    self subclassResponsibility
+
+
+!
+
+preDraggingIn:aSourceWidget
+    "called before starting the drag & drop operation
+    "
+    rootView := aSourceWidget device rootView.
+
+! !
+
+!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 := 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 := 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|
+    "/
+    "/ 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.
+    ].
+    "/
+    "/ 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.
+
+    rootView copyFrom:tmpForm
+                    x:saveArea origin x
+                    y:saveArea origin y 
+                width:extent x 
+               height:extent y
+
+
+
+!
+
+dropTargetWillChange
+    "restore old saveArea
+    "
+    self postDragging
+
+
+!
+
+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).
+
+
+! !
+
+!DragHandler class methodsFor:'documentation'!
+
+version
+    ^ '$Header: /cvs/stx/stx/libview2/DragHandler.st,v 1.1 1998-03-30 12:00:30 ca Exp $'
+! !