DragAndDropManager.st
changeset 874 0730cf44f593
parent 861 10bbb13fcb05
child 881 981e0791ca36
equal deleted inserted replaced
873:c5cd8f56dc6e 874:0730cf44f593
    10  hereby transferred.
    10  hereby transferred.
    11 "
    11 "
    12 
    12 
    13 
    13 
    14 Object subclass:#DragAndDropManager
    14 Object subclass:#DragAndDropManager
    15 	instanceVariableNames:'dragView motionAction releaseAction initialPoint previousPoint
    15 	instanceVariableNames:'dropContext dragView dropAction dragOffset handler restoreBlock
    16 		rememberedDelegate dragBlock lineMode dropAction opaque saveUnder
    16 		alienCursor enabledCursor disabledCursor canDrop'
    17 		dragSize dragOffset dropObjects saveCursor lastView
       
    18 		lastScreenPosition'
       
    19 	classVariableNames:'DragOriginatorQuerySignal DragOffsetQuerySignal'
    17 	classVariableNames:'DragOriginatorQuerySignal DragOffsetQuerySignal'
    20 	poolDictionaries:''
    18 	poolDictionaries:''
    21 	category:'Interface-Support'
    19 	category:'Interface-DragAndDrop'
    22 !
       
    23 
       
    24 View subclass:#DemoView
       
    25 	instanceVariableNames:''
       
    26 	classVariableNames:''
       
    27 	poolDictionaries:''
       
    28 	privateIn:DragAndDropManager
       
    29 !
       
    30 
       
    31 View subclass:#DemoView2
       
    32 	instanceVariableNames:''
       
    33 	classVariableNames:''
       
    34 	poolDictionaries:''
       
    35 	privateIn:DragAndDropManager
       
    36 !
       
    37 
       
    38 View subclass:#DemoView3
       
    39 	instanceVariableNames:''
       
    40 	classVariableNames:''
       
    41 	poolDictionaries:''
       
    42 	privateIn:DragAndDropManager
       
    43 !
    20 !
    44 
    21 
    45 !DragAndDropManager class methodsFor:'documentation'!
    22 !DragAndDropManager class methodsFor:'documentation'!
    46 
    23 
    47 copyright
    24 copyright
   150 
   127 
   151     [author:]
   128     [author:]
   152         Claus Gittinger
   129         Claus Gittinger
   153 
   130 
   154     [see also:]
   131     [see also:]
   155         DemoView DemoView2 DemoView3 - examples
   132         DemoView1, DemoView2, ...
   156         SelectionInListView FileBrowser - for a concrete example
   133         SelectionInListView FileBrowser - for a concrete example
   157 
   134 
   158 "
   135 "
   159 
   136 
   160 !
   137 !
   215                 v turnOff
   192                 v turnOff
   216               ].
   193               ].
   217      top openWithExtent:200@200
   194      top openWithExtent:200@200
   218                                                                 [exEnd]
   195                                                                 [exEnd]
   219 
   196 
       
   197    more drag & drop; offset, displayObjects, ...
       
   198                                                                 [exBegin]
       
   199     |dropObj topView pannel icon buttonAction addButton|
       
   200 
       
   201     topView := StandardSystemView new.
       
   202     pannel  := VerticalPanelView origin:(0.0 @ 0.0) corner:(1.0 @ 1.0) in:topView.
       
   203     pannel  horizontalLayout:#fit.
       
   204     pannel  verticalLayout:#fitSpace.
       
   205 
       
   206     icon    := Image fromFile:('xpmBitmaps/QUESTION3.xpm').
       
   207     dropObj := DropObject newFile:('.').
       
   208 
       
   209     addButton := [:offset :label :dispObj| |button|
       
   210         button := Button label:label in:pannel.
       
   211 
       
   212         button pressAction:[
       
   213             DragAndDropManager startDrag:dropObj from:button offset:offset display:dispObj.
       
   214             button turnOff.
       
   215         ]
       
   216     ].
       
   217 
       
   218     addButton value:#topLeft     value:'String'       value:'String'.
       
   219     addButton value:#topRight    value:'Text'         value:(Text string:'hello' emphasis:#bold).
       
   220     addButton value:#bottomLeft  value:'Icon'         value:icon.
       
   221     addButton value:#bottomRight value:'LabelAndIcon' value:(LabelAndIcon icon:icon string:'Label & Icon').
       
   222     addButton value:#center      value:'Mixed'        value:(Array with:'String' with:icon).
       
   223 
       
   224     topView label:'Drag & Drop'.
       
   225     topView openWithExtent:200@200.
       
   226                                                                 [exEnd]
   220 "
   227 "
   221 ! !
   228 ! !
   222 
   229 
   223 !DragAndDropManager class methodsFor:'initialization'!
   230 !DragAndDropManager class methodsFor:'initialization'!
   224 
   231 
   229     "
   236     "
   230      self initialize
   237      self initialize
   231     "
   238     "
   232 
   239 
   233     "Modified: 11.8.1997 / 00:54:21 / cg"
   240     "Modified: 11.8.1997 / 00:54:21 / cg"
       
   241 !
       
   242 
       
   243 new
       
   244     ^ self basicNew initialize
   234 ! !
   245 ! !
   235 
   246 
   236 !DragAndDropManager class methodsFor:'Signal constants'!
   247 !DragAndDropManager class methodsFor:'Signal constants'!
   237 
   248 
   238 dragOffsetQuerySignal
   249 dragOffsetQuerySignal
   243 
   254 
   244 dragOriginatorQuerySignal
   255 dragOriginatorQuerySignal
   245     ^ DragOriginatorQuerySignal
   256     ^ DragOriginatorQuerySignal
   246 ! !
   257 ! !
   247 
   258 
   248 !DragAndDropManager class methodsFor:'simple start'!
   259 !DragAndDropManager class methodsFor:'simple start - drop source'!
       
   260 
       
   261 startDragFrom:aView dropSource:aDropSource
       
   262     "start a drop at the current pointer position.
       
   263     "
       
   264     ^ (self new) startDragFrom:aView dropSource:aDropSource
       
   265 ! !
       
   266 
       
   267 !DragAndDropManager class methodsFor:'simple start - generic'!
       
   268 
       
   269 startDrag:draggableObjects from:aView
       
   270     "start a drop at the current pointer position
       
   271     "
       
   272     ^ self startDrag:draggableObjects
       
   273                 from:aView
       
   274               offset:0@0
       
   275                atEnd:nil
       
   276              display:draggableObjects
       
   277 
       
   278 "
       
   279 EXAMPLE:
       
   280 
       
   281     |button|
       
   282 
       
   283     button := (Button label:'press me').
       
   284 
       
   285     button pressAction:[
       
   286         DragAndDropManager startDrag:(DropObject newFile:('.')) from:button.
       
   287         button turnOff
       
   288     ].
       
   289 
       
   290     button openAt:100@100
       
   291 "
       
   292 !
       
   293 
       
   294 startDrag:draggableObjects from:aView atEnd:aFourArgEndBlock
       
   295     "start a drop at the current pointer position
       
   296      When finished, the endAction is called with four args:
       
   297      the targetView, the targetViews windowID (useful, if its an alien view),
       
   298      the dropPoint in root-coordinates and the dropPoint within the targetView
       
   299     "
       
   300     ^ self startDrag:draggableObjects
       
   301                 from:aView
       
   302               offset:0@0
       
   303                atEnd:aFourArgEndBlock
       
   304              display:draggableObjects
       
   305 
       
   306 "
       
   307 EXAMPLE:
       
   308 
       
   309     |button|
       
   310 
       
   311     button := (Button label:'press me').
       
   312 
       
   313     button pressAction:[
       
   314         DragAndDropManager startDrag:(DropObject newFile:('.'))
       
   315                                 from:button
       
   316                                atEnd:[:targetView :targetViewId :screenPoint :targetPoint|
       
   317                                         Transcript showCR:'target  view: ', targetView   printString.
       
   318                                         Transcript showCR:'target    id: ', targetViewId printString.
       
   319                                         Transcript showCR:'point screen: ', screenPoint  printString.
       
   320                                         Transcript showCR:'point target: ', targetPoint  printString.
       
   321                                      ].
       
   322         button turnOff
       
   323     ].
       
   324 
       
   325     button openAt:100@100
       
   326 "
       
   327 
       
   328 !
       
   329 
       
   330 startDrag:draggableObjects from:aView atEnd:aFourArgEndBlock display:something
       
   331     "start a drop at the current pointer position
       
   332      When finished, the endAction is called with four args:
       
   333      the targetView, the targetViews windowID (useful, if its an alien view),
       
   334      the dropPoint in root-coordinates and the dropPoint within the targetView
       
   335     "
       
   336     ^ self startDrag:draggableObjects
       
   337                 from:aView
       
   338               offset:0@0
       
   339                atEnd:aFourArgEndBlock
       
   340              display:something
       
   341 
       
   342 "
       
   343 EXAMPLE:
       
   344 
       
   345     |button|
       
   346 
       
   347     button := (Button label:'press me').
       
   348 
       
   349     button pressAction:[
       
   350         DragAndDropManager startDrag:(DropObject newFile:('.'))
       
   351                                 from:button
       
   352                                atEnd:[:targetView :targetViewId :screenPoint :targetPoint|
       
   353                                         Transcript showCR:'target  view: ', targetView   printString.
       
   354                                         Transcript showCR:'target    id: ', targetViewId printString.
       
   355                                         Transcript showCR:'point screen: ', screenPoint  printString.
       
   356                                         Transcript showCR:'point target: ', targetPoint  printString.
       
   357                                      ]
       
   358                              display:(Array with:'String' with:(Image fromFile:('xpmBitmaps/QUESTION3.xpm'))).
       
   359         button turnOff
       
   360     ].
       
   361 
       
   362     button openAt:100@100
       
   363 "
       
   364 !
       
   365 
       
   366 startDrag:draggableObjects from:aView display:something
       
   367     "start a drop at the current pointer position
       
   368     "
       
   369     ^ self startDrag:draggableObjects
       
   370                 from:aView
       
   371               offset:0@0
       
   372                atEnd:nil
       
   373              display:something
       
   374 
       
   375 "
       
   376 EXAMPLE:
       
   377 
       
   378     |dropObj topView pannel icon buttonAction addButton|
       
   379 
       
   380     topView := StandardSystemView new.
       
   381     pannel  := VerticalPanelView origin:(0.0 @ 0.0) corner:(1.0 @ 1.0) in:topView.
       
   382     pannel  horizontalLayout:#fit.
       
   383     pannel  verticalLayout:#fitSpace.
       
   384 
       
   385     icon    := Image fromFile:('xpmBitmaps/QUESTION3.xpm').
       
   386     dropObj := DropObject newFile:('.').
       
   387 
       
   388     addButton := [:label :dispObj| |button|
       
   389         button := Button label:label in:pannel.
       
   390 
       
   391         button pressAction:[
       
   392             DragAndDropManager startDrag:dropObj from:button display:dispObj.
       
   393             button turnOff.
       
   394         ]
       
   395     ].
       
   396 
       
   397     addButton value:'String'       value:'String'.
       
   398     addButton value:'Text'         value:(Text string:'hello' emphasis:#bold).
       
   399     addButton value:'Icon'         value:icon.
       
   400     addButton value:'LabelAndIcon' value:(LabelAndIcon icon:icon string:'Label & Icon').
       
   401     addButton value:'Mixed'        value:(Array with:'String' with:icon).
       
   402 
       
   403     topView label:'Drag & Drop'.
       
   404     topView openWithExtent:200@200.
       
   405 "
       
   406 !
       
   407 
       
   408 startDrag:draggableObjects from:aView offset:anOffset
       
   409     "start a drop at the current pointer position
       
   410     "
       
   411     ^ self startDrag:draggableObjects
       
   412                 from:aView
       
   413               offset:anOffset
       
   414                atEnd:nil
       
   415              display:draggableObjects
       
   416 
       
   417 "
       
   418 EXAMPLE:
       
   419 
       
   420     |button|
       
   421 
       
   422     button := (Button label:'press me').
       
   423 
       
   424     button pressAction:[
       
   425         DragAndDropManager startDrag:(DropObject newFile:('.')) from:button offset:(-10 @ -10).
       
   426         button turnOff
       
   427     ].
       
   428 
       
   429     button openAt:100@100
       
   430 "
       
   431 
       
   432 !
       
   433 
       
   434 startDrag:draggableObjects from:aView offset:anOffset atEnd:aFourArgEndBlock
       
   435     "start a drop at the current pointer position
       
   436      When finished, the endAction is called with four args:
       
   437      the targetView, the targetViews windowID (useful, if its an alien view),
       
   438      the dropPoint in root-coordinates and the dropPoint within the targetView
       
   439     "
       
   440     ^ self startDrag:draggableObjects
       
   441                 from:aView
       
   442               offset:anOffset
       
   443                atEnd:aFourArgEndBlock
       
   444              display:draggableObjects
       
   445 
       
   446 "
       
   447 EXAMPLE:
       
   448 
       
   449     |button|
       
   450 
       
   451     button := (Button label:'press me').
       
   452 
       
   453     button pressAction:[
       
   454         DragAndDropManager startDrag:(DropObject newFile:('.'))
       
   455                                 from:button
       
   456                               offset:(-10 @ -10)
       
   457                                atEnd:[:targetView :targetViewId :screenPoint :targetPoint|
       
   458                                         Transcript showCR:'target  view: ', targetView   printString.
       
   459                                         Transcript showCR:'target    id: ', targetViewId printString.
       
   460                                         Transcript showCR:'point screen: ', screenPoint  printString.
       
   461                                         Transcript showCR:'point target: ', targetPoint  printString.
       
   462                                      ].
       
   463         button turnOff
       
   464     ].
       
   465 
       
   466     button openAt:100@100
       
   467 "
       
   468 
       
   469 !
       
   470 
       
   471 startDrag:draggableObjects from:aView offset:anOffset atEnd:aFourArgEndBlock display:something
       
   472     "start a drop at the current pointer position
       
   473      When finished, the endAction is called with four args:
       
   474      the targetView, the targetViews windowID (useful, if its an alien view),
       
   475      the dropPoint in root-coordinates and the dropPoint within the targetView
       
   476     "
       
   477     |manager|
       
   478 
       
   479     manager := self new.
       
   480 
       
   481     manager startDrag:draggableObjects
       
   482                  from:aView
       
   483                offset:anOffset
       
   484                 atEnd:aFourArgEndBlock
       
   485               display:something.
       
   486 
       
   487     ^ manager
       
   488 
       
   489 "
       
   490 EXAMPLE:
       
   491 
       
   492     |button|
       
   493 
       
   494     button := (Button label:'press me').
       
   495 
       
   496     button pressAction:[
       
   497         DragAndDropManager startDrag:(DropObject newFile:('.'))
       
   498                                 from:button
       
   499                               offset:(-10 @ -10)
       
   500                                atEnd:[:targetView :targetViewId :screenPoint :targetPoint|
       
   501                                         Transcript showCR:'target  view: ', targetView   printString.
       
   502                                         Transcript showCR:'target    id: ', targetViewId printString.
       
   503                                         Transcript showCR:'point screen: ', screenPoint  printString.
       
   504                                         Transcript showCR:'point target: ', targetPoint  printString.
       
   505                                      ]
       
   506                              display:(Array with:'String' with:(Image fromFile:('xpmBitmaps/QUESTION3.xpm'))).
       
   507         button turnOff
       
   508     ].
       
   509 
       
   510     button openAt:100@100
       
   511 "
       
   512 
       
   513 !
       
   514 
       
   515 startDrag:draggableObjects from:aView offset:anOffset display:something
       
   516     "start a drop at the current pointer position
       
   517     "
       
   518     ^ self startDrag:draggableObjects
       
   519                 from:aView
       
   520               offset:anOffset
       
   521                atEnd:nil
       
   522              display:something
       
   523 
       
   524 "
       
   525 EXAMPLE:
       
   526 
       
   527     |dropObj topView pannel icon buttonAction addButton|
       
   528 
       
   529     topView := StandardSystemView new.
       
   530     pannel  := VerticalPanelView origin:(0.0 @ 0.0) corner:(1.0 @ 1.0) in:topView.
       
   531     pannel  horizontalLayout:#fit.
       
   532     pannel  verticalLayout:#fitSpace.
       
   533 
       
   534     icon    := Image fromFile:('xpmBitmaps/QUESTION3.xpm').
       
   535     dropObj := DropObject newFile:('.').
       
   536 
       
   537     addButton := [:offset :label :dispObj| |button|
       
   538         button := Button label:label in:pannel.
       
   539 
       
   540         button pressAction:[
       
   541             DragAndDropManager startDrag:dropObj from:button offset:offset display:dispObj.
       
   542             button turnOff.
       
   543         ]
       
   544     ].
       
   545 
       
   546     addButton value:#topLeft     value:'String'       value:'String'.
       
   547     addButton value:#topRight    value:'Text'         value:(Text string:'hello' emphasis:#bold).
       
   548     addButton value:#bottomLeft  value:'Icon'         value:icon.
       
   549     addButton value:#bottomRight value:'LabelAndIcon' value:(LabelAndIcon icon:icon string:'Label & Icon').
       
   550     addButton value:#center      value:'Mixed'        value:(Array with:'String' with:icon).
       
   551 
       
   552     topView label:'Drag & Drop'.
       
   553     topView openWithExtent:200@200.
       
   554 "
       
   555 
       
   556 ! !
       
   557 
       
   558 !DragAndDropManager class methodsFor:'simple start - lines'!
   249 
   559 
   250 startArrowDragIn:aView at:dragPoint atEnd:aFourArgBlock
   560 startArrowDragIn:aView at:dragPoint atEnd:aFourArgBlock
   251     "start a rubber-arrow-line dragging in aView at dragPoint.
   561     "start a rubber-arrow-line dragging in aView at dragPoint.
   252      When finished, evaluate the fourArgBlock with targetView,
   562      When finished, evaluate the fourArgBlock with targetView,
   253      targetID, screenPosition and targetViewPosition as arguments"
   563      targetID, screenPosition and targetViewPosition as arguments
   254 
   564     "
   255     ^ self new
   565     ^ self new startArrowDragIn:aView at:dragPoint atEnd:aFourArgBlock
   256         startArrowDragIn:aView at:dragPoint atEnd:aFourArgBlock
   566 
   257 
   567 "
   258     "
   568 EXAMPLE:
   259      |o v|
   569 
   260 
   570     |button|
   261      v := Button label:'press me'.
   571 
   262      v pressAction:[
   572     button := (Button label:'press me').
   263                 |o|
   573 
   264                 o := DropObject newFile:('.').
   574     button pressAction:[
   265                 v turnOff; repairDamage.
   575         button turnOff.
   266                 DragAndDropManager 
   576 
   267                     startArrowDragIn:v 
   577         DragAndDropManager startArrowDragIn:button 
   268                     at:0@0 
   578                                          at:(button preferredExtent // 2)
   269                     atEnd:[:v :vID :sPos :vPos |
   579                                       atEnd:[:targetView :targetViewId :screenPoint :targetPoint|
   270                                 v isNil ifTrue:[
   580                                                 targetView isNil ifTrue:[
   271                                     Transcript show:'alien view'
   581                                                     Transcript show:'alien view'
   272                                 ] ifFalse:[
   582                                                 ] ifFalse:[
   273                                     Transcript show:'view: ';
   583                                                     Transcript showCR:'target: ', targetView printString
   274                                                show:v
   584                                                 ].
   275                                 ].
   585                                                 Transcript showCR:'point screen: ', screenPoint printString.
   276                                 Transcript show:' screen: '; show:sPos;
   586                                                 Transcript showCR:'point target: ', targetPoint printString.
   277                                            show:' inView: '; showCR:vPos.
   587                                             ]
   278                           ].
   588      ].
   279               ].
   589      button openAt:100@100
   280      v openAt:100@100
   590 "
   281     "
       
   282 
       
   283     "Modified: 19.4.1997 / 12:04:08 / cg"
       
   284 !
       
   285 
       
   286 startDrag:anObjectOrCollection from:aView
       
   287     "start a drop at the current pointer position"
       
   288 
       
   289     self startDrag:anObjectOrCollection from:aView offset:0@0 atEnd:nil
       
   290 
       
   291     "
       
   292      |o v|
       
   293 
       
   294      v := (Button label:'press me').
       
   295      v pressAction:[
       
   296                 |o|
       
   297                 o := DropObject newFile:('.').
       
   298                 DragAndDropManager startDrag:o from:v.
       
   299                 v turnOff
       
   300               ].
       
   301      v openAt:100@100
       
   302     "
       
   303 
       
   304     "Modified: 19.4.1997 / 11:42:40 / cg"
       
   305 
       
   306 !
       
   307 
       
   308 startDrag:anObjectOrCollection from:aView atEnd:aFourArgEndBlock
       
   309     "start a drop at the current pointer position
       
   310      When finished, the endAction is called with four args:
       
   311      the targetView, the targetViews windowID (useful, if its an alien view),
       
   312      the dropPoint in root-coordinates and the dropPoint within the targetView"
       
   313 
       
   314     self startDrag:anObjectOrCollection from:aView offset:0@0 atEnd:aFourArgEndBlock
       
   315 
       
   316 !
       
   317 
       
   318 startDrag:anObjectOrCollection from:aView atEnd:aFourArgEndBlock useIcon:anIcon
       
   319     "start a drop at the current pointer position
       
   320      When finished, the endAction is called with four args:
       
   321      the targetView, the targetViews windowID (useful, if its an alien view),
       
   322      the dropPoint in root-coordinates and the dropPoint within the targetView"
       
   323 
       
   324     self startDrag:anObjectOrCollection from:aView offset:0@0 atEnd:aFourArgEndBlock useIcon:anIcon
       
   325 
       
   326 !
       
   327 
       
   328 startDrag:anObjectOrCollection from:aView offset:offset
       
   329     "start a drop at the current pointer position"
       
   330 
       
   331     self startDrag:anObjectOrCollection from:aView offset:offset atEnd:nil
       
   332 
       
   333     "
       
   334      |o v|
       
   335 
       
   336      v := (Button label:'press me').
       
   337      v pressAction:[
       
   338                 |o|
       
   339                 o := DropObject newFile:('.').
       
   340                 DragAndDropManager startDrag:o from:v offset:10@10.
       
   341                 v turnOff
       
   342               ].
       
   343      v openAt:100@100
       
   344     "
       
   345 
       
   346     "Modified: 19.4.1997 / 11:42:45 / cg"
       
   347 
       
   348 !
       
   349 
       
   350 startDrag:anObjectOrCollection from:aView offset:offset atEnd:aFourArgEndBlock
       
   351     "start a drop at the current pointer position
       
   352      When finished, the endAction is called with four args:
       
   353      the targetView, the targetViews windowID (useful, if its an alien view),
       
   354      the dropPoint in root-coordinates and the dropPoint within the targetView"
       
   355 
       
   356 
       
   357     (self new) startDrag:anObjectOrCollection from:aView offset:offset atEnd:aFourArgEndBlock
       
   358 
       
   359 
       
   360 !
       
   361 
       
   362 startDrag:anObjectOrCollection from:aView offset:anOffset atEnd:aFourArgEndBlock useIcon:anIcon
       
   363 
       
   364     (self new) startDrag:anObjectOrCollection
       
   365                     from:aView
       
   366                   offset:anOffset
       
   367                    atEnd:aFourArgEndBlock
       
   368                  useIcon:anIcon
       
   369 
       
   370 
       
   371 !
       
   372 
       
   373 startDrag:anObjectOrCollection from:aView useIcon:anIcon
       
   374     "start a drop at the current pointer position"
       
   375 
       
   376     self startDrag:anObjectOrCollection from:aView offset:0@0 atEnd:nil useIcon:anIcon
       
   377 
       
   378     "
       
   379      |o v|
       
   380 
       
   381      v := (Button label:'press me').
       
   382      v pressAction:[
       
   383                 |o|
       
   384                 o := DropObject newFile:('.').
       
   385                 DragAndDropManager startDrag:o from:v useIcon:(
       
   386                     Image fromFile:('xpmBitmaps/cursors/hand_with_document.xpm')
       
   387                 ).
       
   388                 v turnOff
       
   389               ].
       
   390      v openAt:100@100
       
   391     "
       
   392 
       
   393     "Modified: 19.4.1997 / 11:42:40 / cg"
       
   394 
       
   395 !
   591 !
   396 
   592 
   397 startLineDragIn:aView at:dragPoint atEnd:aFourArgBlock
   593 startLineDragIn:aView at:dragPoint atEnd:aFourArgBlock
   398     "start a rubber-line dragging in aView at dragPoint.
   594     "start a rubber-line dragging in aView at dragPoint.
   399      When finished, evaluate the fourArgBlock with targetView,
   595      When finished, evaluate the fourArgBlock with targetView,
   400      targetID, screenPosition and targetViewPosition as arguments"
   596      targetID, screenPosition and targetViewPosition as arguments
   401 
   597     "
   402     ^ self new
   598     ^ self new startLineDragIn:aView at:dragPoint atEnd:aFourArgBlock
   403         startLineDragIn:aView at:dragPoint atEnd:aFourArgBlock
   599 
   404 
   600 "
   405     "
   601 EXAMPLE:
   406      |o v|
   602 
   407 
   603     |button|
   408      v := (Button label:'press me').
   604 
   409      v pressAction:[
   605     button := (Button label:'press me').
   410                 |o|
   606 
   411                 o := DropObject newFile:('.').
   607     button pressAction:[
   412                 v turnOff; repairDamage.
   608         button turnOff.
   413                 DragAndDropManager 
   609 
   414                     startLineDragIn:v 
   610         DragAndDropManager startLineDragIn:button 
   415                     at:0@0 
   611                                         at:(button preferredExtent // 2)
   416                     atEnd:[:v :vID :sPos :vPos |
   612                                      atEnd:[:targetView :targetViewId :screenPoint :targetPoint|
   417                                 v isNil ifTrue:[
   613                                                targetView isNil ifTrue:[
   418                                     Transcript show:'alien view'
   614                                                    Transcript show:'alien view'
   419                                 ] ifFalse:[
   615                                                ] ifFalse:[
   420                                     Transcript show:'view: ';
   616                                                    Transcript showCR:'target: ', targetView printString
   421                                                show:v
   617                                                ].
   422                                 ].
   618                                                Transcript showCR:'point screen: ', screenPoint printString.
   423                                 Transcript show:' screen: '; show:sPos;
   619                                                Transcript showCR:'point target: ', targetPoint printString.
   424                                            show:' inView: '; showCR:vPos.
   620                                            ]
   425                           ].
   621      ].
   426               ].
   622      button openAt:100@100
   427      v openAt:100@100
   623 "
   428     "
       
   429 
       
   430     "Modified: 19.4.1997 / 12:02:02 / cg"
       
   431 ! !
   624 ! !
   432 
   625 
   433 !DragAndDropManager methodsFor:'accessing'!
   626 !DragAndDropManager methodsFor:'accessing'!
   434 
   627 
   435 device
   628 device
   438     ^ dragView device
   631     ^ dragView device
   439 
   632 
   440 
   633 
   441 !
   634 !
   442 
   635 
       
   636 dropContext
       
   637     "return the current context
       
   638     "
       
   639     ^ dropContext
       
   640 !
       
   641 
   443 dropObjects
   642 dropObjects
   444     "return the current dropObject collection"
   643     "return the current dropObject collection"
   445 
   644 
   446     ^ dropObjects
   645     ^ dropContext dropObjects
   447 
   646 
   448     "Modified: 19.4.1997 / 10:19:06 / cg"
   647     "Modified: 19.4.1997 / 10:19:06 / cg"
   449 !
   648 !
   450 
   649 
   451 dropObjects:aCollectionOfDropObjects
   650 dropObjects:aCollectionOfDropObjects
   452     "set the current dropObject collection"
   651     "set the current dropObject collection"
   453 
   652 
   454     aCollectionOfDropObjects isCollection ifTrue:[
   653     ^ dropContext dropObjects:aCollectionOfDropObjects
   455         dropObjects := aCollectionOfDropObjects
       
   456     ] ifFalse:[
       
   457         dropObjects := Array with:aCollectionOfDropObjects
       
   458     ].
       
   459 
       
   460     "Modified: 19.4.1997 / 10:19:33 / cg"
       
   461 !
   654 !
   462 
   655 
   463 font
   656 font
   464     "returns the font of the source view
   657     "returns the font of the source view
   465     "
   658     "
   466     ^ dragView font
   659     ^ dragView font
   467 
   660 
   468 
   661 
       
   662 !
       
   663 
       
   664 sourceWidget
       
   665     ^ dragView
       
   666 ! !
       
   667 
       
   668 !DragAndDropManager methodsFor:'accessing cursor'!
       
   669 
       
   670 alienCursor:aCursorOrImage
       
   671     "set the cursor used for an alien widget; not an ST/X view
       
   672     "
       
   673     aCursorOrImage isImage ifTrue:[
       
   674         alienCursor := Cursor fromImage:aCursorOrImage
       
   675     ] ifFalse:[
       
   676         (aCursorOrImage isMemberOf:Cursor) ifTrue:[
       
   677             alienCursor := aCursorOrImage
       
   678         ] ifFalse:[
       
   679             "/
       
   680             "/ use disabled cursor
       
   681             "/
       
   682             alienCursor := nil
       
   683         ]
       
   684     ]
       
   685 !
       
   686 
       
   687 disabledCursor:aCursorOrImage
       
   688     "set the cursor for an ST/X view, which can not drop the objects
       
   689     "
       
   690     aCursorOrImage isImage ifTrue:[
       
   691         disabledCursor := Cursor fromImage:aCursorOrImage
       
   692     ] ifFalse:[
       
   693         (aCursorOrImage isMemberOf:Cursor) ifTrue:[
       
   694             disabledCursor := aCursorOrImage
       
   695         ]
       
   696     ]
       
   697 !
       
   698 
       
   699 enabledCursor:aCursorOrImage
       
   700     "set the cursor for an ST/X view, which can drop the objects
       
   701     "
       
   702     aCursorOrImage isImage ifTrue:[
       
   703         enabledCursor := Cursor fromImage:aCursorOrImage
       
   704     ] ifFalse:[
       
   705         (aCursorOrImage isMemberOf:Cursor) ifTrue:[
       
   706             enabledCursor := aCursorOrImage
       
   707         ]
       
   708     ]
       
   709 
       
   710 ! !
       
   711 
       
   712 !DragAndDropManager methodsFor:'dragging - drop source'!
       
   713 
       
   714 startDragFrom:aView dropSource:aDropSource
       
   715     "start a drop at the current pointer position.
       
   716     "
       
   717     ^ self startDragFrom:aView dropSource:aDropSource offset:#topLeft "/ #center
       
   718 !
       
   719 
       
   720 startDragFrom:aView dropSource:aDropSource offset:anOffset
       
   721     "start a drop at the current pointer position.
       
   722     "
       
   723     dropContext dropSource:aDropSource.
       
   724 
       
   725     ^ self startDrag:(aDropSource dropObjects)
       
   726                 from:aView
       
   727               offset:anOffset
       
   728                atEnd:nil
       
   729              display:(aDropSource displayObjects)
       
   730 ! !
       
   731 
       
   732 !DragAndDropManager methodsFor:'dragging - easy startup'!
       
   733 
       
   734 startDrag:draggableObjects from:aView
       
   735     "start a drop at the current pointer position
       
   736     "
       
   737     ^ self startDrag:draggableObjects
       
   738                 from:aView
       
   739               offset:0@0
       
   740 !
       
   741 
       
   742 startDrag:draggableObjects from:aView display:something
       
   743     "start a drop at the current pointer position.
       
   744     "
       
   745     ^ self startDrag:draggableObjects
       
   746                 from:aView
       
   747               offset:nil
       
   748                atEnd:nil
       
   749              display:something
       
   750 !
       
   751 
       
   752 startDrag:draggableObjects from:aView offset:anOffset
       
   753     "start a drop at the current pointer position with an offset
       
   754     "
       
   755     ^ self startDrag:draggableObjects
       
   756                 from:aView
       
   757               offset:anOffset
       
   758                atEnd:nil
       
   759 !
       
   760 
       
   761 startDrag:draggableObjects from:aView offset:anOffset atEnd:aFourArgEndBlock
       
   762     "start a drop at the current pointer position.
       
   763      When finished, the endAction is called with four args:
       
   764      the targetView, the targetViews windowID (useful, if its an alien view),
       
   765      the dropPoint in root-coordinates and the dropPoint within the targetView
       
   766     "
       
   767     ^ self startDrag:draggableObjects
       
   768                 from:aView
       
   769               offset:anOffset
       
   770                atEnd:aFourArgEndBlock
       
   771              display:draggableObjects
       
   772 !
       
   773 
       
   774 startDrag:draggableObjects from:aView offset:anOffset atEnd:aFourArgBlock display:something
       
   775     "start a drop at the current pointer position.
       
   776      When finished, the endAction is called with four args:
       
   777      the targetView, the targetViews windowID (useful, if its an alien view),
       
   778      the dropPoint in root-coordinates and the dropPoint within the targetView.
       
   779     "
       
   780     |height width fontWdt dispObj offset ascent device dispObjs list space|
       
   781 
       
   782     self dropObjects:draggableObjects.
       
   783 
       
   784     self dropObjects size == 0 ifTrue:[
       
   785         ^ self
       
   786     ].
       
   787 
       
   788     device   := aView device.
       
   789     space    := 1.
       
   790     height   := space negated.
       
   791     width    := 0.
       
   792     fontWdt  := aView font width.
       
   793     ascent   := aView font ascent.
       
   794 
       
   795     (list := something) isNil ifTrue:[
       
   796         list := self dropObjects
       
   797     ] ifFalse:[
       
   798         (list isCollection not or:[list isString]) ifTrue:[
       
   799             list := Array with:something
       
   800         ]
       
   801     ].
       
   802     dispObjs := OrderedCollection new.
       
   803 
       
   804     list do:[:el|
       
   805         |obj asc|
       
   806 
       
   807         obj    := self displayObjectFor:el on:device.
       
   808         asc    := (obj respondsTo:#string) ifTrue:[ascent] ifFalse:[0].
       
   809         height := height + space.
       
   810 
       
   811         dispObjs add:(Array with:obj with:(0 @ (height + asc))).
       
   812         width  := width max:(obj widthOn:aView).
       
   813         height := height + (obj heightOn:aView).
       
   814     ].
       
   815 
       
   816     offset := self computeOffset:anOffset w:width h:height.
       
   817 
       
   818     dispObjs do:[:el| el at:2 put:((el at:2) - offset) ].
       
   819 
       
   820     self startOpaqueDrag:[:p :v| dispObjs do:[:el| (el at:1) displayOn:v at:p + (el at:2)] ]
       
   821                   offset:offset
       
   822                   extent:width @ height
       
   823                       in:aView
       
   824                       at:nil
       
   825                    atEnd:aFourArgBlock
       
   826 !
       
   827 
       
   828 startDrag:draggableObjects from:aView offset:anOffset display:something
       
   829     "start a drop at the current pointer position.
       
   830     "
       
   831     ^ self startDrag:draggableObjects
       
   832                 from:aView
       
   833               offset:anOffset
       
   834                atEnd:nil
       
   835              display:something
   469 ! !
   836 ! !
   470 
   837 
   471 !DragAndDropManager methodsFor:'dragging - generic'!
   838 !DragAndDropManager methodsFor:'dragging - generic'!
   472 
       
   473 doGenericDragX:x y:y
       
   474     "drag to x/y; see if the target view allows a drop
       
   475      and change the mouse pointer as appropriate"
       
   476 
       
   477     |view newCursor|
       
   478 
       
   479     previousPoint notNil ifTrue:[
       
   480         (opaque and:[dragSize notNil]) ifTrue:[
       
   481             self restoreGenericAt:previousPoint
       
   482         ] ifFalse:[
       
   483             self invertGenericAt:previousPoint
       
   484         ]
       
   485     ].
       
   486     previousPoint := x @ y.
       
   487     lastScreenPosition := nil.
       
   488 
       
   489     view := self destinationViewAt:previousPoint.
       
   490     view ~~ lastView ifTrue:[
       
   491         view isNil ifTrue:[
       
   492             "/ alien view - dont know if it likes a drop
       
   493             newCursor := Cursor questionMark
       
   494         ] ifFalse:[
       
   495             "/ ST/X view - ask it.
       
   496             (self askIfCanDrop:dropObjects in:view) ifTrue:[
       
   497                 newCursor := Cursor thumbsUp
       
   498             ] ifFalse:[
       
   499                 newCursor := Cursor thumbsDown
       
   500             ]
       
   501         ].
       
   502         dragView cursor:newCursor now:true.
       
   503         lastView := view
       
   504     ].
       
   505 
       
   506     (opaque and:[dragSize notNil]) ifTrue:[
       
   507         self drawGenericAt:previousPoint.
       
   508     ] ifFalse:[
       
   509         self invertGenericAt:previousPoint
       
   510     ].
       
   511 
       
   512     "Modified: 19.4.1997 / 11:33:54 / cg"
       
   513 !
       
   514 
       
   515 endGenericDragX:x y:y
       
   516     "finish a drag; restore from saveUnder (or reinvert),
       
   517      then call for the endAction"
       
   518 
       
   519     previousPoint notNil ifTrue:[
       
   520         (opaque and:[dragSize notNil]) ifTrue:[
       
   521             self restoreGenericAt:previousPoint
       
   522         ] ifFalse:[
       
   523             self invertGenericAt:previousPoint
       
   524         ]
       
   525     ].
       
   526     previousPoint := nil.
       
   527     self uncatchEvents.
       
   528     self endDragAt:x @ y
       
   529 
       
   530     "Created: 26.10.1996 / 15:17:20 / cg"
       
   531     "Modified: 19.4.1997 / 10:41:57 / cg"
       
   532 !
       
   533 
   839 
   534 startGenericDrag:aTwoArgDragBlock in:aView at:p atEnd:aFourArgEndBlock
   840 startGenericDrag:aTwoArgDragBlock in:aView at:p atEnd:aFourArgEndBlock
   535     "start a generic (caller-provided drag);
   841     "start a generic (caller-provided drag);
   536      Here, an inverting drag is initiated (i.e. the drawing is undone
   842      Here, an inverting drag is initiated (i.e. the drawing is undone
   537      by inverting again). See startOpaqueDrag for another variant.
   843      by inverting again). See startOpaqueDrag for another variant.
   538      the dragBlock, aTwoArgDragBlock will be called with two args
   844      the dragBlock, aTwoArgDragBlock will be called with two args
   539      aPoint and a drawingGC, to perform the drawing at some dragPoint.
   845      aPoint and a drawingGC, to perform the drawing at some dragPoint.
   540      The drag starts in aView at point p.
   846      The drag starts in aView at point p.
   541      When finished, the endAction is called with four args:
   847      When finished, the endAction is called with four args:
   542      the targetView, the targetViews windowID (useful, if its an alien view),
   848      the targetView, the targetViews windowID (useful, if its an alien view),
   543      the dropPoint in root-coordinates and the dropPoint within the targetView"
   849      the dropPoint in root-coordinates and the dropPoint within the targetView
   544 
   850     "
   545     self catchEventsFrom:aView.
   851     ^ self startOpaqueDrag:aTwoArgDragBlock
   546     motionAction := #doGenericDragX:y:.
   852                     offset:nil
   547     releaseAction := #endGenericDragX:y:.
   853                     extent:nil
   548     initialPoint := p.
   854                         in:aView
   549     previousPoint := nil.
   855                         at:nil
   550     dragBlock := aTwoArgDragBlock.
   856                      atEnd:aFourArgEndBlock
   551     dropAction := aFourArgEndBlock.
   857 !
   552 
   858 
   553     "Created: 26.10.1996 / 15:16:13 / cg"
   859 startOpaqueDrag:aDragBlock offset:offs extent:anExtent in:aView at:aDummyPoint atEnd:aFourArgEndBlock
   554     "Modified: 19.4.1997 / 10:44:32 / cg"
   860     "start an opaque or generic opaque (caller-provided drag);
   555 !
       
   556 
       
   557 startOpaqueDrag:aTwoArgDragBlock offset:offs extent:ext in:aView at:p atEnd:aFourArgEndBlock
       
   558     "start a generic opaque (caller-provided drag);
       
   559      opaque drag means, that the drawing cannot be undone by two inverting
   861      opaque drag means, that the drawing cannot be undone by two inverting
   560      draws, but instead, the area under the dragged object must be saved
   862      draws, but instead, the area under the dragged object must be saved
   561      and restored. The areas size to be saved/restored is passed in ext.
   863      and restored. The areas size to be saved/restored is passed in anExtent.
   562      the dragBlock, aTwoArgDragBlock will be called with two args
   864      the dragBlock, aDragBlock will be called with up to three args aPoint, a
   563      aPoint and a drawingGC, to perform the drawing at some dragPoint.
   865      drawingGC and the display objects, to perform the drawing at some dragPoint.
   564      The drag starts in aView at point p.
   866      The drag starts in aView at point p.
   565      When finished, the endAction is called with four args:
   867      When finished, the endAction is called with four args:
   566      the targetView, the targetViews windowID (useful, if its an alien view),
   868      the targetView, the targetViews windowID (useful, if its an alien view),
   567      the dropPoint in root-coordinates and the dropPoint within the targetView"
   869      the dropPoint in root-coordinates and the dropPoint within the targetView
   568 
   870     "
   569     self catchEventsFrom:aView.
   871     |handler numArgs dragBlock dobjs|
   570     motionAction := #doGenericDragX:y:.
   872 
   571     releaseAction := #endGenericDragX:y:.
   873     dragOffset := offs ? (Point x:0 y:0).
   572     initialPoint := p.
   874     numArgs    := aDragBlock numArgs.
   573     previousPoint := nil.
   875 
   574     dragBlock := aTwoArgDragBlock.
   876     numArgs == 3 ifTrue:[
   575     dropAction := aFourArgEndBlock.
   877         dobjs := self dropObjects.
   576     opaque := true.
   878         dragBlock := [:p :v| aDragBlock value:p value:v value:dobjs ]
   577     dragSize := ext.
   879     ] ifFalse:[
   578     dragOffset := offs.
   880         numArgs == 1 ifTrue:[
   579 
   881             dragBlock := [:p :v| aDragBlock value:p ]
   580     "Modified: 26.10.1996 / 15:09:26 / cg"
   882         ] ifFalse:[
   581     "Created: 26.10.1996 / 15:16:13 / cg"
   883             dragBlock := aDragBlock
   582 
   884         ]
   583 ! !
   885     ].
   584 
   886 
   585 !DragAndDropManager methodsFor:'dragging - generic - inverting'!
   887     anExtent isNil ifTrue:[
   586 
   888         handler := DragHandler startGenericDrag:dragBlock.
   587 invertGenericAt:ip
   889     ] ifFalse:[
   588     "draw for a generic inverting drag"
   890         handler := DragHandler startOpaqueDrag:dragBlock extent:anExtent offset:dragOffset.
   589 
   891     ].
   590     |t offs p rootView|
   892     self doStart:handler for:aView atEnd:aFourArgEndBlock
   591 
   893 
   592     rootView := dragView device rootView.
       
   593 
       
   594     (p := lastScreenPosition) isNil ifTrue:[
       
   595         p := ip.
       
   596 
       
   597         "
       
   598          get device coordinates
       
   599         "
       
   600         (t := dragView transformation) notNil ifTrue:[
       
   601             p := t applyTo:p.
       
   602         ].
       
   603 
       
   604         "
       
   605          translate to screen
       
   606         "
       
   607         offs := dragView device 
       
   608                     translatePoint:0@0 
       
   609                     from:(dragView id) to:(rootView id).
       
   610         p := p + offs.
       
   611 
       
   612         lastScreenPosition := p.
       
   613     ].
       
   614 
       
   615     rootView clippedByChildren:false.
       
   616     rootView xoring:[
       
   617         rootView lineWidth:0. 
       
   618         self callForDragActionAt:p in:rootView.
       
   619         rootView flush
       
   620     ].
       
   621 
       
   622     "Created: 26.10.1996 / 15:15:26 / cg"
       
   623     "Modified: 19.4.1997 / 11:35:33 / cg"
       
   624 ! !
       
   625 
       
   626 !DragAndDropManager methodsFor:'dragging - generic - opaque'!
       
   627 
       
   628 drawGenericAt:ip
       
   629     "draw for a generic opaque drag"
       
   630 
       
   631     |t offs p rootView szX szY|
       
   632 
       
   633     rootView := dragView device rootView.
       
   634 
       
   635     p := ip.
       
   636 
       
   637     "/
       
   638     "/ get device coordinates
       
   639     "/
       
   640     (t := dragView transformation) notNil ifTrue:[
       
   641         p := t applyTo:p.
       
   642     ].
       
   643 
       
   644     "/
       
   645     "/ translate to screen
       
   646     "/
       
   647     offs := dragView device 
       
   648                 translatePoint:0@0 
       
   649                 from:(dragView id) to:(rootView id).
       
   650     p := p + offs.
       
   651 
       
   652     rootView clippedByChildren:false.
       
   653 
       
   654     "/
       
   655     "/ copy from screen to saveUnder
       
   656     "/
       
   657     szX := dragSize x.
       
   658     szY := dragSize y.
       
   659     saveUnder isNil ifTrue:[
       
   660         saveUnder := Form 
       
   661                             width:szX 
       
   662                             height:szY 
       
   663                             depth:rootView device depth 
       
   664                             on:dragView device.
       
   665         saveUnder clippedByChildren:false.
       
   666     ].
       
   667 
       
   668     lastScreenPosition := p - dragOffset.
       
   669     saveUnder 
       
   670         copyFrom:rootView 
       
   671         x:lastScreenPosition x 
       
   672         y:lastScreenPosition y
       
   673         toX:0 
       
   674         y:0 
       
   675         width:szX 
       
   676         height:szY.
       
   677 
       
   678     "/
       
   679     "/ draw using the dragAction block
       
   680     "/
       
   681     rootView lineWidth:0. 
       
   682     self callForDragActionAt:p in:rootView.
       
   683     rootView flush
       
   684 
       
   685     "Modified: 19.4.1997 / 10:45:48 / cg"
       
   686 !
       
   687 
       
   688 restoreGenericAt:ip
       
   689     "restore from saveUnder for a generic opaque drag"
       
   690 
       
   691     |rootView|
       
   692 
       
   693     rootView := dragView device rootView.
       
   694 
       
   695     "/
       
   696     "/ copy from saveUnder back to screen
       
   697     "/
       
   698     rootView clippedByChildren:false.
       
   699     rootView 
       
   700         copyFrom:saveUnder 
       
   701         x:0 y:0 
       
   702         toX:lastScreenPosition x y:lastScreenPosition y
       
   703         width:dragSize x 
       
   704         height:dragSize y.
       
   705 
       
   706     "Modified: 19.4.1997 / 10:46:39 / cg"
       
   707 ! !
   894 ! !
   708 
   895 
   709 !DragAndDropManager methodsFor:'dragging - lines'!
   896 !DragAndDropManager methodsFor:'dragging - lines'!
   710 
   897 
   711 doLineDragX:x y:y
   898 startArrowDragIn:aView at:aStartPoint atEnd:aFourArgEndBlock
   712     "do a line drag - invert previous and draw at new position"
       
   713 
       
   714     previousPoint notNil ifTrue:[
       
   715         self invertLineFrom:initialPoint to:previousPoint
       
   716     ].
       
   717     previousPoint := x @ y.
       
   718     self invertLineFrom:initialPoint to:previousPoint
       
   719 
       
   720     "Modified: 19.4.1997 / 12:39:43 / cg"
       
   721 !
       
   722 
       
   723 endLineDragX:x y:y
       
   724     "end a line drag - invert previous, deinstall event catcher 
       
   725      and call for endDrag action"
       
   726 
       
   727     previousPoint notNil ifTrue:[
       
   728         self invertLineFrom:initialPoint to:previousPoint
       
   729     ].
       
   730 
       
   731     previousPoint := nil.
       
   732     dragView device sync.
       
   733 
       
   734     self uncatchEvents.
       
   735     self endDragAt:x @ y.
       
   736 
       
   737     "Created: 26.10.1996 / 15:17:20 / cg"
       
   738     "Modified: 19.4.1997 / 12:40:14 / cg"
       
   739 !
       
   740 
       
   741 invertLineFrom:ip1 to:ip2
       
   742     "invert for a line drag"
       
   743 
       
   744     |t offs p1 p2 rootView a|
       
   745 
       
   746     rootView := dragView device rootView.
       
   747 
       
   748     p1 := ip1.
       
   749     p2 := ip2.
       
   750 
       
   751     "
       
   752      get device coordinates
       
   753     "
       
   754     (t := dragView transformation) notNil ifTrue:[
       
   755         p1 := t applyTo:p1.
       
   756         p2 := t applyTo:p2.
       
   757     ].
       
   758 
       
   759     "
       
   760      translate to screen
       
   761     "
       
   762     offs := dragView device 
       
   763                 translatePoint:0@0 
       
   764                 from:(dragView id) to:(rootView id).
       
   765     p1 := p1 + offs.
       
   766     p2 := p2 + offs.
       
   767 
       
   768     rootView clippedByChildren:false.
       
   769     rootView xoring:[
       
   770         rootView lineWidth:0. 
       
   771         lineMode == #arrow ifTrue:[
       
   772             a := Arrow from:p1 to:p2.
       
   773             a arrowHeadLength:(rootView device horizontalPixelPerMillimeter * 4) rounded.
       
   774             a displayFilledOn:rootView.
       
   775         ] ifFalse:[
       
   776             rootView displayLineFrom:p1 to:p2.
       
   777         ].
       
   778         rootView flush
       
   779     ].
       
   780 
       
   781     "Created: 26.10.1996 / 15:15:26 / cg"
       
   782     "Modified: 19.4.1997 / 12:40:29 / cg"
       
   783 !
       
   784 
       
   785 startArrowDragIn:aView at:p atEnd:aBlock
       
   786     "start a line-drag of an arrow-line.
   899     "start a line-drag of an arrow-line.
   787      The drag starts in aView at point p.
   900      The drag starts in aView at point aStartPoint.
   788      When finished, the endAction is called with four args:
   901      When finished, the endAction is called with four args:
   789      the targetView, the targetViews windowID (useful, if its an alien view),
   902      the targetView, the targetViews windowID (useful, if its an alien view),
   790      the dropPoint in root-coordinates and the dropPoint within the targetView"
   903      the dropPoint in root-coordinates and the dropPoint within the targetView
   791 
   904     "
   792     self catchEventsFrom:aView.
   905     |p|
   793     motionAction := #doLineDragX:y:.
   906 
   794     releaseAction := #endLineDragX:y:.
   907     p := self translatePointToScreen:aStartPoint from:aView.
   795     initialPoint := p.
   908 
   796     previousPoint := nil.
   909     self doStart:(DragHandler startArrowDragAt:p)
   797     dragBlock := nil.
   910              for:aView
   798     lineMode := #arrow.
   911            atEnd:aFourArgEndBlock
   799     dropAction := aBlock.
   912 !
   800 
   913 
   801     "Modified: 26.10.1996 / 15:09:26 / cg"
   914 startLineDragIn:aView at:aStartPoint atEnd:aFourArgEndBlock
   802     "Created: 26.10.1996 / 15:16:13 / cg"
       
   803 
       
   804 !
       
   805 
       
   806 startLineDragIn:aView at:p atEnd:aFourArgEndBlock
       
   807     "start a line-drag of a normal line.
   915     "start a line-drag of a normal line.
   808      The drag starts in aView at point p.
   916      The drag starts in aView at point aStartPoint.
   809      When finished, the endAction is called with four args:
   917      When finished, the endAction is called with four args:
   810      the targetView, the targetViews windowID (useful, if its an alien view),
   918      the targetView, the targetViews windowID (useful, if its an alien view),
   811      the dropPoint in root-coordinates and the dropPoint within the targetView"
   919      the dropPoint in root-coordinates and the dropPoint within the targetView
   812 
   920     "
   813     self catchEventsFrom:aView.
   921     |p|
   814     motionAction := #doLineDragX:y:.
   922 
   815     releaseAction := #endLineDragX:y:.
   923     p := self translatePointToScreen:aStartPoint from:aView.
   816     initialPoint := p.
   924 
   817     previousPoint := nil.
   925     self doStart:(DragHandler startLineDragAt:p)
   818     dragBlock := nil.
   926              for:aView
   819     lineMode := nil.
   927            atEnd:aFourArgEndBlock
   820     dropAction := aFourArgEndBlock.
       
   821 
       
   822     "Modified: 26.10.1996 / 15:09:26 / cg"
       
   823     "Created: 26.10.1996 / 15:16:13 / cg"
       
   824 
       
   825 ! !
   928 ! !
   826 
   929 
   827 !DragAndDropManager methodsFor:'drawing'!
   930 !DragAndDropManager methodsFor:'drawing'!
       
   931 
       
   932 computeOffset:anOffset w:w h:h
       
   933     |p|
       
   934 
       
   935     anOffset isSymbol ifFalse:[
       
   936         ^ anOffset notNil ifTrue:[anOffset] ifFalse:[0@0]
       
   937     ].
       
   938     anOffset == #topLeft     ifTrue:[ ^ 0 @ 0].
       
   939     anOffset == #topRight    ifTrue:[ ^ w @ 0].
       
   940 
       
   941     anOffset == #bottomLeft  ifTrue:[ ^ 0 @ h].
       
   942     anOffset == #bottomRight ifTrue:[ ^ w @ h].
       
   943 
       
   944     p := (w @ h) // 2.
       
   945 
       
   946     anOffset == #center       ifTrue:[ ^ p ].
       
   947 
       
   948     anOffset == #topCenter    ifTrue:[ ^ p x @ 0 ].
       
   949     anOffset == #bottomCenter ifTrue:[ ^ p x @ h ].
       
   950 
       
   951     anOffset == #leftCenter   ifTrue:[ ^ 0 @ p y ].
       
   952     anOffset == #rightCenter  ifTrue:[ ^ w @ p y ].
       
   953 
       
   954     Transcript showCR:'unsupported offset: ', anOffset printString.
       
   955     ^ 0 @ 0
       
   956 !
       
   957 
       
   958 displayObjectFor:anObject on:aDevice
       
   959     "converts an object to a display object
       
   960     "
       
   961     |obj icon s1 s2|
       
   962 
       
   963     obj := (anObject respondsTo:#displayObject) ifTrue:[anObject displayObject]
       
   964                                                ifFalse:[anObject].
       
   965 
       
   966     obj isString ifTrue:[
       
   967         ^ obj
       
   968     ].
       
   969 
       
   970     obj messageNotUnderstoodSignal handle:[:ex|] do:[
       
   971         obj := obj on:aDevice
       
   972     ].
       
   973 
       
   974     obj isImage ifTrue:[
       
   975         ^ obj clearMaskedPixels
       
   976     ].
       
   977 
       
   978     obj class == LabelAndIcon ifTrue:[
       
   979         obj image notNil ifTrue:[obj image clearMaskedPixels].
       
   980         obj icon  notNil ifTrue:[obj icon clearMaskedPixels].
       
   981       ^ obj
       
   982     ].
       
   983 
       
   984     (obj class == MultiColListEntry) ifFalse:[
       
   985         ^ obj
       
   986     ].
       
   987     s1 := obj colAt:1.
       
   988     s2 := obj colAt:2.
       
   989 
       
   990     s1 isImage ifTrue:[
       
   991         s2 isImage  ifTrue:[ ^ self displayObjectFor:(LabelAndIcon form:s1  image:s2) on:aDevice ].
       
   992         s2 isString ifTrue:[ ^ self displayObjectFor:(LabelAndIcon icon:s1 string:s2) on:aDevice ].
       
   993         ^ (s1 on:aDevice) clearMaskedPixels
       
   994     ].
       
   995 
       
   996     s2 isImage ifTrue:[
       
   997         s1 isString ifTrue:[ ^ self displayObjectFor:(LabelAndIcon icon:s2 string:s1) on:aDevice ].
       
   998         ^ (s2 on:aDevice) clearMaskedPixels
       
   999     ].
       
  1000 
       
  1001     s1 isString ifTrue:[^ s1].
       
  1002     s2 isString ifTrue:[^ s2].
       
  1003   ^ obj
       
  1004 !
   828 
  1005 
   829 showDragging:items in:aView at:p
  1006 showDragging:items in:aView at:p
   830     "helper for dragging dragObjects: draw them all"
  1007     "helper for dragging dragObjects: draw them all"
   831 
  1008 
   832     |offs|
  1009     |offs|
   838     ]
  1015     ]
   839 
  1016 
   840     "Modified: 19.4.1997 / 12:41:24 / cg"
  1017     "Modified: 19.4.1997 / 12:41:24 / cg"
   841 ! !
  1018 ! !
   842 
  1019 
   843 !DragAndDropManager methodsFor:'dropping'!
  1020 !DragAndDropManager methodsFor:'event catching'!
   844 
  1021 
   845 drop:something in:targetView at:aPoint from:sourceView ifOk:okAction ifFail:failAction
  1022 buttonMotion:button x:x y:y view:aView
   846     "try to drop some object in a targetView;
  1023     "handle a button motion event
   847      if any view along the targetViews superView chain takes it, 
  1024     "
   848      the okAction is evaluated; if not, failAction is evaluated.
  1025     |oldPt oldTgt oldWg oldId newWg newId newTgt point rootId cursor device isDroppable|
   849      This may be sent from a drag initiators endDrag block."
  1026 
   850 
  1027     device := dragView device.
   851     |v pnt|
  1028     rootId := device rootView id.
   852 
  1029     point  := self translatePointToScreen:(x @ y) from:dragView.
   853     v := targetView.
  1030     oldWg  := dropContext targetWidget.
   854     pnt := aPoint.
  1031     oldId  := dropContext targetId.
   855 
  1032     oldPt  := dropContext rootPoint.
   856     [v notNil] whileTrue:[
  1033 
   857         (self askIfCanDrop:something in:v) ifTrue:[
  1034     dropContext rootPoint:point.
   858             v 
  1035 
   859                 drop:something 
  1036     "/
   860                 at:aPoint 
  1037     "/ search view the drop is in
   861                 from:sourceView 
  1038     "/
   862                 with:[:o | okAction. ^ true]
  1039     [   newId := rootId.
   863                 ifFail:[:o | failAction. ^ false].
  1040         (rootId := device viewIdFromPoint:point in:newId) notNil
       
  1041     ] whileTrue.
       
  1042 
       
  1043     newWg := device viewFromId:newId.
       
  1044     dropContext targetWidget:newWg id:newId.
       
  1045 
       
  1046     handler isInterestedInDropTarget ifFalse:[
       
  1047         "/
       
  1048         "/ line or arrow handler
       
  1049         "/
       
  1050         handler dragTo:point.
       
  1051         ^ self
       
  1052     ].
       
  1053 
       
  1054     oldWg ~~ newWg ifTrue:[
       
  1055         "/
       
  1056         "/ widget has changed: drop target might change
       
  1057         "/
       
  1058         oldTgt := dropContext dropTarget.
       
  1059         newTgt := self doFindDropTargetIn:newWg at:point.
       
  1060 
       
  1061         newTgt ~= oldTgt ifTrue:[
       
  1062             "/
       
  1063             "/ drop target changed: handler might restore the screen
       
  1064             "/
       
  1065             handler dropTargetWillChange.
       
  1066 
       
  1067             oldTgt notNil ifTrue:[
       
  1068                 "/
       
  1069                 "/ setup old context
       
  1070                 "/
       
  1071                 dropContext targetWidget:oldWg id:oldId.
       
  1072                 oldTgt leave:dropContext.
       
  1073                 dropContext targetWidget:newWg id:newId.
       
  1074             ].
       
  1075             dropContext dropTarget:newTgt.
       
  1076             newTgt notNil ifTrue:[ newTgt enter:dropContext ]
       
  1077         ] ifFalse:[
       
  1078             dropContext dropTarget:newTgt
       
  1079         ]
       
  1080     ] ifFalse:[
       
  1081         (oldPt notNil and:[(oldPt dist:point) < 2 ]) ifTrue:[
       
  1082             "/
       
  1083             "/ ignorre the button motion event; restore old rootPoint
       
  1084             "/
       
  1085             dropContext rootPoint:oldPt.
       
  1086             ^ self
   864         ].
  1087         ].
   865         v := v superView.
  1088         newTgt := dropContext dropTarget
   866         pnt := nil
  1089     ].
   867     ].
  1090     "/
   868     failAction value.
  1091     "/ update the cursor
   869     ^ false
  1092     "/
   870 
  1093     (isDroppable := dropContext canDrop) ifTrue:[
   871     "Modified: 19.4.1997 / 12:42:36 / cg"
  1094         cursor := enabledCursor
   872 ! !
  1095     ] ifFalse:[
   873 
  1096         cursor := dropContext isAlienView ifFalse:[disabledCursor]
   874 !DragAndDropManager methodsFor:'easy drag & drop'!
  1097                                            ifTrue:[alienCursor]
   875 
  1098     ].
   876 startDrag:anObjectOrCollection from:aView offset:anOffset
  1099     dragView cursor:cursor now:true.
   877     "start a drop at the current pointer position"
  1100     "/
   878 
  1101     "/ test if droppable state changed
   879     self startDrag:anObjectOrCollection from:aView offset:anOffset atEnd:nil
  1102     "/
   880 
  1103     canDrop == isDroppable ifFalse:[
   881 !
  1104         "/
   882 
  1105         "/ droppable state changed: handler might restore the screen
   883 startDrag:anObjectOrCollection from:aView offset:anOffset atEnd:aFourArgEndBlock
  1106         "/
   884     "start a drop at the current pointer position.
  1107         canDrop := isDroppable.
   885      When finished, the endAction is called with four args:
  1108         handler dropTargetWillChange
   886      the targetView, the targetViews windowID (useful, if its an alien view),
  1109     ].
   887      the dropPoint in root-coordinates and the dropPoint within the targetView"
  1110 
   888 
  1111     newTgt notNil ifTrue:[ newTgt over:dropContext ].
   889 
  1112     handler dragTo:point.
   890     |x y pos displayObjects device width height|
  1113 !
   891 
  1114 
   892     self dropObjects:anObjectOrCollection.
  1115 buttonMultiPress:button x:x y:y view:aView
   893 
  1116     "discard each buttonMultiPress event
   894     device := aView device.
  1117     "
   895     pos := device translatePoint:(device pointerPosition)
  1118 !
   896                             from:(device rootView id) 
  1119 
   897                               to:(aView id).
  1120 buttonPress:button x:x y:y view:aView
   898 
  1121     "discard each buttonPress event
   899     displayObjects := dropObjects collect:[:each | each displayObject on:device].
  1122     "
   900     height := displayObjects inject:0 into:[:sum :each | sum + (each heightOn:aView)].
       
   901     width  := displayObjects inject:0 into:[:max :each | max max:(each widthOn:aView)].
       
   902 
       
   903     x := anOffset x.
       
   904     y := anOffset y.
       
   905 
       
   906     (displayObjects at:1) class == LabelAndIcon ifTrue:[
       
   907         y := y + aView font ascent.
       
   908         width := width * 2.
       
   909     ].
       
   910 
       
   911     self startOpaqueDrag:[:aPoint :aView|self showDragging:displayObjects in:aView at:(aPoint - anOffset)]
       
   912                   offset:(x @ y)
       
   913                   extent:(width @ height)
       
   914                       in:aView
       
   915                       at:pos
       
   916                    atEnd:aFourArgEndBlock.
       
   917 
       
   918 !
       
   919 
       
   920 startDrag:anObjectOrCollection from:aView offset:anOffset atEnd:aFourArgEndBlock useIcon:anIcon
       
   921     "start a drop at the current pointer position.
       
   922      When finished, the endAction is called with four args:
       
   923      the targetView, the targetViews windowID (useful, if its an alien view),
       
   924      the dropPoint in root-coordinates and the dropPoint within the targetView"
       
   925 
       
   926 
       
   927     |pos displayObjects device|
       
   928 
       
   929     self dropObjects:anObjectOrCollection.
       
   930 
       
   931     device := aView device.
       
   932     pos    := device translatePoint:(device pointerPosition)
       
   933                                from:(device rootView id) 
       
   934                                  to:(aView id).
       
   935 
       
   936     displayObjects := Array with:(anIcon on:device).
       
   937 
       
   938     self startOpaqueDrag:[:aPoint :aView|self showDragging:displayObjects in:aView at:(aPoint - anOffset)]
       
   939                   offset:anOffset
       
   940                   extent:(anIcon extent)
       
   941                       in:aView
       
   942                       at:pos
       
   943                    atEnd:aFourArgEndBlock.
       
   944 
       
   945 !
       
   946 
       
   947 startDrag:anObjectOrCollection from:aView offset:anOffset useIcon:anIcon
       
   948     "start a drop at the current pointer position.
       
   949      When finished, the endAction is called with four args:
       
   950      the targetView, the targetViews windowID (useful, if its an alien view),
       
   951      the dropPoint in root-coordinates and the dropPoint within the targetView"
       
   952 
       
   953     self startDrag:anObjectOrCollection from:aView offset:anOffset atEnd:nil useIcon:anIcon
       
   954 ! !
       
   955 
       
   956 !DragAndDropManager methodsFor:'event catching'!
       
   957 
       
   958 buttonMotion:button x:x y:y view:aView
       
   959     self perform:motionAction with:x with:y
       
   960 
       
   961     "Created: 26.10.1996 / 15:09:00 / cg"
       
   962 
       
   963 
       
   964 !
  1123 !
   965 
  1124 
   966 buttonRelease:button x:x y:y view:aView
  1125 buttonRelease:button x:x y:y view:aView
   967     self perform:releaseAction with:x with:y.
  1126     "button released; do the drop
   968 
  1127     "
   969     "Modified: 19.4.1997 / 12:37:02 / cg"
  1128     ((button == 2) or:[button == #menu]) ifTrue:[
       
  1129         ^ self
       
  1130     ].
       
  1131     "/
       
  1132     "/ update the context
       
  1133     "/
       
  1134     self buttonMotion:button x:x y:y view:aView.
       
  1135 
       
  1136     "/
       
  1137     "/ restore source view
       
  1138     "/
       
  1139     restoreBlock value.
       
  1140 
       
  1141     "/
       
  1142     "/ at least do the drop operation
       
  1143     "/
       
  1144     dropAction isNil ifTrue:[
       
  1145         dropContext doDrop
       
  1146     ] ifFalse:[
       
  1147         "/
       
  1148         "/ initiator wants to do it himself, manually.
       
  1149         "/ Thus, no feedBack operation invoked.
       
  1150         "/
       
  1151         dropAction value:(dropContext targetWidget)
       
  1152                    value:(dropContext targetId)
       
  1153                    value:(dropContext rootPoint)
       
  1154                    value:(dropContext targetPoint).
       
  1155     ]
   970 !
  1156 !
   971 
  1157 
   972 handlesButtonMotion:button inView:aView
  1158 handlesButtonMotion:button inView:aView
   973     "query from event processor: am I interested in button-events ?
  1159     "query from event processor: am I interested in button-events ?
   974      yes I am (to activate the clicked-on field)."
  1160      yes I am (to activate the clicked-on field)."
   975 
  1161 
   976     ^ aView == dragView
  1162     ^ dragView == aView
   977 
  1163 !
   978     "Created: 26.10.1996 / 15:05:36 / cg"
  1164 
   979 
  1165 handlesButtonMultiPress:button inView:aView
       
  1166     "query from event processor: am I interested in button-events ?
       
  1167      yes I am (to activate the clicked-on field)."
       
  1168 
       
  1169     ^ dragView == aView
       
  1170 !
       
  1171 
       
  1172 handlesButtonPress:button inView:aView
       
  1173     "query from event processor: am I interested in button-events ?
       
  1174      yes I am (to activate the clicked-on field)."
       
  1175 
       
  1176     ^ dragView == aView
   980 !
  1177 !
   981 
  1178 
   982 handlesButtonRelease:button inView:aView
  1179 handlesButtonRelease:button inView:aView
   983     "query from event processor: am I interested in button-events ?
  1180     "query from event processor: am I interested in button-events ?
   984      yes I am (to activate the clicked-on field)."
  1181      yes I am (to activate the clicked-on field)."
   985 
  1182 
   986     ^ aView == dragView
  1183     ^ dragView == aView
   987 
  1184 ! !
   988     "Created: 26.10.1996 / 15:05:48 / cg"
  1185 
   989 
  1186 !DragAndDropManager methodsFor:'initialization'!
       
  1187 
       
  1188 initialize
       
  1189     super initialize.
       
  1190 
       
  1191     dragOffset     := 0 @ 0.
       
  1192     dropContext    := DropContext new.
       
  1193     alienCursor    := Cursor questionMark.
       
  1194     enabledCursor  := Cursor thumbsUp.
       
  1195     disabledCursor := Cursor thumbsDown.
       
  1196     canDrop        := false.
   990 ! !
  1197 ! !
   991 
  1198 
   992 !DragAndDropManager methodsFor:'private'!
  1199 !DragAndDropManager methodsFor:'private'!
   993 
  1200 
   994 askIfCanDrop:dropObjects in:aView
  1201 doDrop:aContext in:aWidget
   995     |canDrop|
  1202     "old drop mechanism
       
  1203     "
       
  1204     |point|
   996 
  1205 
   997     DragOriginatorQuerySignal answer:dragView do:[
  1206     DragOriginatorQuerySignal answer:dragView do:[
   998         DragOffsetQuerySignal answer:dragOffset do:[
  1207         DragOffsetQuerySignal answer:dragOffset do:[
   999             canDrop := aView canDrop:dropObjects
  1208             aContext targetWidget == aWidget ifTrue:[
  1000         ].
  1209                 point := aContext targetPoint
  1001     ].
  1210             ] ifFalse:[
  1002     ^ canDrop
  1211                 point := nil.
  1003 
  1212                 "/
  1004     "Modified: 11.8.1997 / 00:55:10 / cg"
  1213                 "/ FeedBack: set the widget which handles the drop
  1005 !
  1214                 "/
  1006 
  1215                 aContext targetWidget:aWidget id:(aWidget id).
  1007 callForDragActionAt:aPoint in:aView
  1216             ].
  1008     "evaluate the user supplied dragAction.
  1217             aWidget drop:(aContext dropObjects) at:point
  1009      Look how many args it expects and invoke with
       
  1010         position
       
  1011         dragView
       
  1012         dragObjects"
       
  1013 
       
  1014     |numArgs|
       
  1015 
       
  1016     (numArgs := dragBlock numArgs) == 1 ifTrue:[
       
  1017         dragBlock value:aPoint
       
  1018     ] ifFalse:[
       
  1019         numArgs == 2 ifTrue:[
       
  1020             dragBlock value:aPoint value:aView
       
  1021         ] ifFalse:[
       
  1022             dragBlock value:aPoint value:aView value:dropObjects.
       
  1023         ]
  1218         ]
  1024     ]
  1219     ].
  1025 
  1220 
  1026     "Created: 19.4.1997 / 10:05:55 / cg"
  1221 !
  1027 !
  1222 
  1028 
  1223 doFindDropTargetIn:aView at:aPoint
  1029 catchEventsFrom:aView
  1224     "get the drop target for a view and source at a point or nil
       
  1225     "
       
  1226     |target view dobj|
       
  1227 
       
  1228     aView isNil ifTrue:[ ^ nil ].
       
  1229     "/
       
  1230     "/ new mechanism to get a dropTarget
       
  1231     "/
       
  1232     aView messageNotUnderstoodSignal handle:[:ex|
       
  1233         target := nil.
       
  1234     ] do:[
       
  1235         target := aView dropTarget
       
  1236     ].
       
  1237     target notNil ifTrue:[ ^ target ].
       
  1238     "/
       
  1239     "/ old mechanism to get a dropTarget
       
  1240     "/
       
  1241     view := aView.
       
  1242     dobj := dropContext dropObjects.
       
  1243 
       
  1244     DragOriginatorQuerySignal answer:dragView do:[
       
  1245         DragOffsetQuerySignal answer:dragOffset do:[
       
  1246             [   (view canDrop:dobj) ifTrue:[
       
  1247                     ^ DropTarget receiver:self argument:view dropSelector:#doDrop:in:.
       
  1248                 ].
       
  1249                 (view := view superView) notNil
       
  1250 
       
  1251             ] whileTrue.
       
  1252         ]
       
  1253     ].
       
  1254     ^ nil
       
  1255 !
       
  1256 
       
  1257 doStart:aHandler for:aView atEnd:aFourArgEndBlock
       
  1258     "setup a handler and a restore block
       
  1259     "
       
  1260     |cursor delegate|
       
  1261 
       
  1262     dropContext sourceWidget:aView.
       
  1263 
       
  1264     dragOffset  isNil ifTrue:[ dragOffset  := 0 @ 0 ].
       
  1265     alienCursor isNil ifTrue:[ alienCursor := disabledCursor ].
       
  1266 
  1030     dragView   := aView.
  1267     dragView   := aView.
  1031     saveCursor := dragView cursor.
  1268     dropAction := aFourArgEndBlock.
  1032 
  1269     cursor     := aView cursor.
  1033     rememberedDelegate := aView delegate.
  1270     delegate   := aView delegate.
       
  1271     handler    := aHandler.
       
  1272 
       
  1273     restoreBlock := [
       
  1274         aHandler postDragging.
       
  1275         aView delegate:delegate.
       
  1276         aView cursor:cursor now:true.
       
  1277         aView device ungrabPointer
       
  1278     ].
       
  1279 
       
  1280     aHandler preDraggingIn:aView.
  1034     aView delegate:self.
  1281     aView delegate:self.
  1035     aView device grabPointerInView:aView.
  1282     aView device grabPointerInView:aView.
  1036 
  1283 
  1037     "Modified: 19.4.1997 / 12:36:04 / cg"
  1284 ! !
  1038 !
  1285 
  1039 
  1286 !DragAndDropManager methodsFor:'translation'!
  1040 destinationViewAt:ip
  1287 
  1041     |rootPoint t viewId offs destinationId lastViewId destinationView
  1288 translatePointToScreen:aPoint from:aView
  1042      rootView destinationPoint device|
  1289     "translate a point to screen
  1043 
  1290     "
  1044     device    := dragView device.
  1291     |device trans point offset|
  1045     rootView  := device rootView.
  1292 
  1046     rootPoint := ip.
  1293     device := aView device.
  1047 
  1294     "/
  1048     "
  1295     "/ get device coordinates
  1049      get device coordinates
  1296     "/
  1050     "
  1297     (trans := aView transformation) notNil ifTrue:[
  1051     (t := dragView transformation) notNil ifTrue:[
  1298         point := trans applyTo:aPoint
  1052         rootPoint := t applyTo:ip.
  1299     ] ifFalse:[
  1053     ].
  1300         point := aPoint
  1054     viewId := rootView id.
  1301     ].
  1055 
  1302     "/
  1056     "
  1303     "/ translate to screen
  1057      translate to screen
  1304     "/
  1058     "
  1305     offset := device translatePoint:0@0 from:(aView id) to:(device rootView id).
  1059     offs := device translatePoint:0@0 from:(dragView id) to:viewId.
  1306   ^ offset + point
  1060     rootPoint := rootPoint + offs.
  1307 
  1061 
       
  1062     "search view the drop is in"
       
  1063 
       
  1064     [viewId notNil] whileTrue:[
       
  1065         destinationId := device viewIdFromPoint:rootPoint in:viewId.
       
  1066         lastViewId := viewId.
       
  1067         viewId := destinationId
       
  1068     ].
       
  1069     ^ device viewFromId:lastViewId
       
  1070 !
       
  1071 
       
  1072 endDragAt:ip
       
  1073     |rootPoint t rootId viewId offs destinationId lastViewId destinationView
       
  1074      rootView destinationPoint device|
       
  1075 
       
  1076     dragView cursor:saveCursor now:true.
       
  1077     device := dragView device.
       
  1078     device ungrabPointer.
       
  1079     rootView := device rootView.
       
  1080     rootPoint := ip.
       
  1081 
       
  1082     "
       
  1083      get device coordinates
       
  1084     "
       
  1085     (t := dragView transformation) notNil ifTrue:[
       
  1086         rootPoint := t applyTo:ip.
       
  1087     ].
       
  1088     viewId := rootId := rootView id.
       
  1089 
       
  1090     "
       
  1091      translate to screen
       
  1092     "
       
  1093     offs := device translatePoint:0@0 from:(dragView id) to:rootId.
       
  1094     rootPoint := rootPoint + offs.
       
  1095 
       
  1096     "search view the drop is in"
       
  1097 
       
  1098     [viewId notNil] whileTrue:[
       
  1099         destinationId := device viewIdFromPoint:rootPoint in:viewId.
       
  1100         lastViewId := viewId.
       
  1101         viewId := destinationId
       
  1102     ].
       
  1103     destinationView := device viewFromId:lastViewId.
       
  1104     destinationId := lastViewId.
       
  1105 
       
  1106     "/
       
  1107     "/ translate to destination view
       
  1108     "/
       
  1109     destinationPoint := device translatePoint:rootPoint from:rootId to:destinationId.
       
  1110 
       
  1111     "/
       
  1112     "/ if the destinationView has a transformation,
       
  1113     "/ also translate to logical coordinates ..
       
  1114     "/
       
  1115     destinationView notNil ifTrue:[
       
  1116         (t := destinationView transformation) notNil ifTrue:[
       
  1117             destinationPoint := t applyInverseTo:destinationPoint
       
  1118         ]
       
  1119     ].
       
  1120 
       
  1121     "/
       
  1122     "/ if this dragOperation has an explicit dropAction,
       
  1123     "/ perform it.
       
  1124     "/
       
  1125     dropAction notNil ifTrue:[
       
  1126         "/ initiator wants to do it himself, manually.
       
  1127 
       
  1128         dropAction value:destinationView
       
  1129                    value:destinationId
       
  1130                    value:rootPoint
       
  1131                    value:destinationPoint.
       
  1132         ^ self
       
  1133     ].
       
  1134 
       
  1135     "/ default drop behavior:
       
  1136     "/ if its one of my own views, ask if dropping is ok.
       
  1137     "/ if not, ask the device to drop it.
       
  1138 
       
  1139     destinationView notNil ifTrue:[
       
  1140         "/
       
  1141         "/ one of my views
       
  1142         "/
       
  1143 
       
  1144         DragOriginatorQuerySignal answer:dragView do:[
       
  1145             DragOffsetQuerySignal answer:dragOffset do:[
       
  1146                 "/
       
  1147                 "/ see if the view itself can drop that stuff ...
       
  1148                 "/
       
  1149                 (destinationView canDrop:dropObjects) ifTrue:[
       
  1150                     destinationView drop:dropObjects at:destinationPoint.
       
  1151                     ^ self.
       
  1152                 ].
       
  1153 
       
  1154                 "/
       
  1155                 "/ try superViews along the chain ...
       
  1156                 "/
       
  1157                 destinationView := destinationView superView.
       
  1158                 [destinationView notNil] whileTrue:[
       
  1159                     (destinationView canDrop:dropObjects) ifTrue:[
       
  1160                         destinationView drop:dropObjects at:nil.
       
  1161                         ^ self.
       
  1162                     ].
       
  1163                     destinationView := destinationView superView.
       
  1164                 ].
       
  1165             ].
       
  1166         ].
       
  1167         ^ self
       
  1168     ].
       
  1169 
       
  1170     "/
       
  1171     "/ not one of my views
       
  1172     "/
       
  1173 
       
  1174     "/ external clipboard mechanism via display
       
  1175     device 
       
  1176         drop:dropObjects 
       
  1177         inWindowID:destinationId 
       
  1178         position:destinationPoint 
       
  1179         rootPosition:rootPoint
       
  1180 
       
  1181     "Modified: 11.8.1997 / 00:55:41 / cg"
       
  1182 !
       
  1183 
       
  1184 uncatchEvents
       
  1185     dragView delegate:rememberedDelegate.
       
  1186 
       
  1187     "Created: 26.10.1996 / 15:22:29 / cg"
       
  1188 
       
  1189     "
       
  1190      DragAndDropManager allInstancesDo:[:m |
       
  1191         m uncatchEvents
       
  1192      ]
       
  1193     "
       
  1194 ! !
       
  1195 
       
  1196 !DragAndDropManager::DemoView class methodsFor:'documentation'!
       
  1197 
       
  1198 documentation
       
  1199 "
       
  1200     demonstrates rubber-line dragging.
       
  1201 
       
  1202     See the buttonPress method, where a drag is initiated.
       
  1203     At endDrop, look at the transcript.
       
  1204 
       
  1205     [author:]
       
  1206         Claus Gittinger
       
  1207 
       
  1208     [start with:]
       
  1209         DemoView new open
       
  1210 "
       
  1211 ! !
       
  1212 
       
  1213 !DragAndDropManager::DemoView methodsFor:'events'!
       
  1214 
       
  1215 buttonPress:button x:x y:y
       
  1216     DragAndDropManager new
       
  1217         startLineDragIn:self at:(x@y) 
       
  1218         atEnd:[:view
       
  1219                :viewID
       
  1220                :rootPoint
       
  1221                :viewPoint | 
       
  1222 
       
  1223                Transcript show:'dropped at ';
       
  1224                           show:viewPoint;
       
  1225                           show:' (screen: ';
       
  1226                           show:rootPoint;
       
  1227                           show:') in '.
       
  1228                view notNil ifTrue:[
       
  1229                    Transcript showCR:view
       
  1230                ] ifFalse:[
       
  1231                    Transcript show:'alien view ';
       
  1232                               showCR:viewID address
       
  1233                ] 
       
  1234         ].
       
  1235 
       
  1236     "
       
  1237      self new open
       
  1238     "
       
  1239 
       
  1240     "Modified: 19.4.1997 / 11:40:46 / cg"
       
  1241 ! !
       
  1242 
       
  1243 !DragAndDropManager::DemoView2 class methodsFor:'documentation'!
       
  1244 
       
  1245 documentation
       
  1246 "
       
  1247     demonstrates string dragging.
       
  1248 
       
  1249     See the buttonPress method, where a drag is initiated.
       
  1250     At endDrop, look at the transcript.
       
  1251 
       
  1252 
       
  1253     [author:]
       
  1254         Claus Gittinger
       
  1255 
       
  1256     [start with:]
       
  1257         DemoView2 new open
       
  1258 "
       
  1259 
       
  1260 
       
  1261 ! !
       
  1262 
       
  1263 !DragAndDropManager::DemoView2 methodsFor:'events'!
       
  1264 
       
  1265 buttonPress:button x:x y:y
       
  1266     DragAndDropManager new
       
  1267         startGenericDrag:[:p :v | v displayString:'hello' at:p]
       
  1268         in:self 
       
  1269         at:(x@y) 
       
  1270         atEnd:[:view
       
  1271                :viewID
       
  1272                :rootPoint
       
  1273                :viewPoint | ]
       
  1274 
       
  1275 
       
  1276     "
       
  1277      self new open
       
  1278     "
       
  1279 
       
  1280 
       
  1281 ! !
       
  1282 
       
  1283 !DragAndDropManager::DemoView3 class methodsFor:'documentation'!
       
  1284 
       
  1285 documentation
       
  1286 "
       
  1287     demonstrates arrow-line dragging.
       
  1288 
       
  1289     See the buttonPress method, where a drag is initiated.
       
  1290     At endDrop, look at the transcript.
       
  1291 
       
  1292     [author:]
       
  1293         Claus Gittinger
       
  1294 
       
  1295     [start with:]
       
  1296         DemoView3 new open
       
  1297 "
       
  1298 
       
  1299 
       
  1300 ! !
       
  1301 
       
  1302 !DragAndDropManager::DemoView3 methodsFor:'events'!
       
  1303 
       
  1304 buttonPress:button x:x y:y
       
  1305     DragAndDropManager new
       
  1306         startArrowDragIn:self 
       
  1307         at:(x@y)
       
  1308         atEnd:[:view
       
  1309                :viewID
       
  1310                :rootPoint
       
  1311                :viewPoint | 
       
  1312 
       
  1313                Transcript show:'dropped at ';
       
  1314                           show:viewPoint;
       
  1315                           show:' (screen: ';
       
  1316                           show:rootPoint;
       
  1317                           show:') in '.
       
  1318                view notNil ifTrue:[
       
  1319                    Transcript showCR:view
       
  1320                ] ifFalse:[
       
  1321                    Transcript show:'alien view ';
       
  1322                               showCR:viewID address
       
  1323                ] 
       
  1324         ].
       
  1325 
       
  1326     "
       
  1327      self new open
       
  1328     "
       
  1329 
       
  1330     "Modified: 19.4.1997 / 12:45:29 / cg"
       
  1331 ! !
  1308 ! !
  1332 
  1309 
  1333 !DragAndDropManager class methodsFor:'documentation'!
  1310 !DragAndDropManager class methodsFor:'documentation'!
  1334 
  1311 
  1335 version
  1312 version
  1336     ^ '$Header: /cvs/stx/stx/libview2/DragAndDropManager.st,v 1.18 1998-03-09 16:06:35 ca Exp $'
  1313     ^ '$Header: /cvs/stx/stx/libview2/DragAndDropManager.st,v 1.19 1998-03-30 12:02:15 ca Exp $'
  1337 ! !
  1314 ! !
  1338 DragAndDropManager initialize!
  1315 DragAndDropManager initialize!