HierarchicalDropTargetController.st
changeset 3371 c80f59a3a422
child 3379 060bb2feff4b
equal deleted inserted replaced
3370:5199f62a817d 3371:c80f59a3a422
       
     1 "{ Package: 'stx:libwidg2' }"
       
     2 
       
     3 Object subclass:#HierarchicalDropTargetController
       
     4 	instanceVariableNames:'expandBlock highlightMode receiver dropOverLine dropSelector
       
     5 		canDropSelector'
       
     6 	classVariableNames:''
       
     7 	poolDictionaries:''
       
     8 	category:'Interface-DragAndDrop'
       
     9 !
       
    10 
       
    11 
       
    12 !HierarchicalDropTargetController class methodsFor:'instance creation'!
       
    13 
       
    14 receiver:aReceiver argument:anArgument dropSelector:aDropSelector canDropSelector:aCanDropSelector
       
    15     |target|
       
    16 
       
    17     target := self new.
       
    18     ^ target receiver:aReceiver argument:anArgument dropSelector:aDropSelector canDropSelector:aCanDropSelector
       
    19 !
       
    20 
       
    21 receiver:aReceiver dropSelector:aDropSelector canDropSelector:aCanDropSelector
       
    22     ^ self receiver:aReceiver argument:nil dropSelector:aDropSelector canDropSelector:aCanDropSelector
       
    23 ! !
       
    24 
       
    25 !HierarchicalDropTargetController class methodsFor:'constants'!
       
    26 
       
    27 delayMilliSecondsBeforeExpand
       
    28     ^ 1000
       
    29 ! !
       
    30 
       
    31 !HierarchicalDropTargetController methodsFor:'drop actions'!
       
    32 
       
    33 canDrop:aDropContext
       
    34     "return true, if the DropContext can be dropped into the list of items"
       
    35 
       
    36     dropOverLine isNil ifTrue:[ ^ false ].      "/ never setup by dropEnter:
       
    37     dropOverLine > 0 ifFalse:[ ^ false ].
       
    38 
       
    39     canDropSelector numArgs == 2 ifTrue:[
       
    40         ^ receiver perform:canDropSelector with:aDropContext with:dropOverLine .
       
    41     ].
       
    42     ^ receiver perform:canDropSelector with:aDropContext.
       
    43 !
       
    44 
       
    45 drop:aDropContext
       
    46     "drop the dropContext into the hierachical list of items
       
    47     "
       
    48     |lnNr|
       
    49 
       
    50     lnNr := dropOverLine.
       
    51     lnNr isNil ifTrue:[^ false ].      "/ never setup by dropEnter:
       
    52 
       
    53     self dropLeave:aDropContext.
       
    54 
       
    55     dropSelector isNil ifTrue:[  ^ false ].
       
    56 
       
    57     dropSelector numArgs == 2 ifTrue:[
       
    58         receiver perform:dropSelector with:aDropContext with:lnNr .
       
    59     ] ifFalse:[
       
    60         receiver perform:dropSelector with:aDropContext.
       
    61     ].
       
    62     ^ true
       
    63 !
       
    64 
       
    65 dropEnter:aDropContext
       
    66     "a drop operation enters my widget; set the highlightMode in the target widget"
       
    67 
       
    68     |widget|
       
    69 
       
    70     dropOverLine := 0.
       
    71 
       
    72     widget := aDropContext targetWidget.
       
    73     highlightMode := widget highlightMode.
       
    74 
       
    75     highlightMode notNil ifTrue:[
       
    76         aDropContext saveDraw:[
       
    77             widget highlightMode: #dropMode.
       
    78             widget windowGroup processExposeEvents.
       
    79         ].
       
    80     ].
       
    81 !
       
    82 
       
    83 dropLeave:aDropContext
       
    84     "the widget is leaved; restore drop indications drawn ...
       
    85     "
       
    86     self changeDropLineTo:nil in:aDropContext.
       
    87 !
       
    88 
       
    89 dropOver:aDropContext
       
    90     |target lineNr|
       
    91 
       
    92     dropOverLine isNil ifTrue:[^ self ].       "/ never setup by dropEnter:
       
    93 
       
    94     target := aDropContext targetWidget.
       
    95     lineNr := target yVisibleToLineNr:(aDropContext targetPoint y).
       
    96 
       
    97     lineNr isNil ifTrue:[ lineNr := 0. ].
       
    98 
       
    99     lineNr > target size ifTrue:[
       
   100         lineNr := 0.
       
   101     ].
       
   102     self changeDropLineTo:lineNr in:aDropContext.
       
   103 ! !
       
   104 
       
   105 !HierarchicalDropTargetController methodsFor:'instance creation'!
       
   106 
       
   107 receiver:aReceiver argument:anArgument dropSelector:aDropSelector canDropSelector:aCanDropSelector
       
   108     |target|
       
   109 
       
   110     receiver        := aReceiver.
       
   111     dropSelector    := aDropSelector.
       
   112     canDropSelector := aCanDropSelector.
       
   113 
       
   114     target := DropTarget
       
   115         receiver:self
       
   116         argument:anArgument
       
   117         dropSelector:#drop:
       
   118         canDropSelector:#canDrop:.
       
   119 
       
   120     target enterSelector:#dropEnter:.
       
   121     target leaveSelector:#dropLeave:.
       
   122     target overSelector:#dropOver:.
       
   123 
       
   124     ^ target
       
   125 ! !
       
   126 
       
   127 !HierarchicalDropTargetController methodsFor:'private'!
       
   128 
       
   129 changeDropLineTo:aLineOrNil in:aDropContext
       
   130     |x0 y0 y1 view item bgColor fgColor processEvents|
       
   131 
       
   132     aLineOrNil == dropOverLine ifTrue:[ ^ self ]. "/ nothing changed
       
   133 
       
   134     view := aDropContext targetWidget.
       
   135 
       
   136     expandBlock notNil ifTrue:[
       
   137         Processor removeTimedBlock:expandBlock.
       
   138     ].
       
   139     processEvents := (aLineOrNil isNil).
       
   140     aDropContext contentsWillChange.
       
   141 
       
   142     (aLineOrNil isNil and:[highlightMode notNil]) ifTrue:[
       
   143         "/ resore the selection mode
       
   144         view highlightMode: highlightMode.
       
   145         highlightMode := nil.
       
   146         processEvents := true.
       
   147     ].
       
   148     (dropOverLine notNil and:[dropOverLine ~~ 0]) ifTrue:[
       
   149         "/ invalidate old line
       
   150         view invalidateLineAt:dropOverLine.
       
   151         processEvents := true.
       
   152     ].
       
   153     processEvents ifTrue:[
       
   154         view windowGroup processExposeEvents.
       
   155     ].
       
   156 
       
   157     dropOverLine := aLineOrNil.
       
   158 
       
   159     (dropOverLine isNil or:[dropOverLine == 0]) ifTrue:[
       
   160         ^ self
       
   161     ].
       
   162     item := view at:dropOverLine ifAbsent:nil.
       
   163     item isNil ifTrue:[ ^ self ].
       
   164 
       
   165     y0 := view yVisibleOfLine:dropOverLine.
       
   166     y1 := view yVisibleOfLine:(dropOverLine + 1).
       
   167     x0 := view xVisibleOfTextAtLevel:item level.
       
   168 
       
   169     bgColor := view hilightBackgroundColor.
       
   170     fgColor := view hilightForegroundColor.
       
   171 
       
   172     view paint: bgColor.
       
   173     view fillRectangle:(Rectangle left:(x0 - 2) top:y0 width:(item widthOn:view) + 4 height:(y1 - y0)).
       
   174 
       
   175     view paint:fgColor on:bgColor.
       
   176     item displayOn:view x:x0 y:y0 h:(y1 - y0).
       
   177 
       
   178     (item isExpanded not and:[item canExpand]) ifTrue:[
       
   179         Processor 
       
   180             addTimedBlock: [self expandForDrop:aDropContext at:aLineOrNil]
       
   181             afterMilliseconds:(self class delayMilliSecondsBeforeExpand).
       
   182     ].
       
   183 !
       
   184 
       
   185 expandForDrop:aDropContext at:aLnNr
       
   186     |item view|
       
   187 
       
   188     expandBlock := nil.
       
   189     aLnNr == dropOverLine ifFalse:[ ^ self].
       
   190 
       
   191     view := aDropContext targetWidget.
       
   192     item := view at:aLnNr ifAbsent:nil.
       
   193     item isNil ifTrue:[^ self].
       
   194 
       
   195     aDropContext saveDraw:[
       
   196         item expand.
       
   197         view windowGroup processExposeEvents.
       
   198     ].
       
   199 ! !
       
   200 
       
   201 !HierarchicalDropTargetController class methodsFor:'documentation'!
       
   202 
       
   203 version
       
   204     ^ '$Header: /cvs/stx/stx/libwidg2/HierarchicalDropTargetController.st,v 1.1 2008-03-25 10:11:43 ab Exp $'
       
   205 ! !