SelectionInTreeView.st
changeset 494 76d8c4e0b612
parent 490 1129f3cf5cea
child 497 9b5503aa6f57
--- a/SelectionInTreeView.st	Mon Aug 11 13:02:55 1997 +0200
+++ b/SelectionInTreeView.st	Fri Aug 15 11:24:57 1997 +0200
@@ -12,10 +12,10 @@
 
 
 SelectionInListView subclass:#SelectionInTreeView
-	instanceVariableNames:'doubleClickSelectionBlock figuresWidth showLines listOfNodes
-		imageOpened imageClosed imageItem imageInset textInset
-		openIndicator closeIndicator showDirectoryIndicator
-		indicatorWidthDiv2 indicatorHeightDiv2'
+	instanceVariableNames:'doubleClickSelectionBlock imageWidth showLines listOfNodes
+		imageInset textInset openIndicator closeIndicator showRoot
+		extentOpenIndicator extentCloseIndicator showDirectoryIndicator
+		indicatorExtentDiv2 imageOpened imageClosed imageItem'
 	classVariableNames:'ImageOpened ImageClosed ImageItem OpenIndicator CloseIndicator'
 	poolDictionaries:''
 	category:'Views-Text'
@@ -53,6 +53,7 @@
         TreeItem
         SelectionInTreeView
         SelectionInListView
+        FileSelectionTree
 
     [author:]
         Claus Atzkern
@@ -127,10 +128,10 @@
 
 !SelectionInTreeView class methodsFor:'constants'!
 
-shownIndicatorInset
-    "returns the additional inset used when setting directory indication to enabled
+minImageInset
+    "returns minimum inset from directory indication to image
     "
-  ^ 4
+  ^ 6
 
 
 ! !
@@ -258,11 +259,8 @@
     "show or hide lines
     "
     aState ~~ showDirectoryIndicator ifTrue:[
-        (showDirectoryIndicator := aState) ifTrue:[
-            imageInset := imageInset + self class shownIndicatorInset.
-        ] ifFalse:[
-            imageInset := imageInset - self class shownIndicatorInset.
-        ].
+        showDirectoryIndicator := aState.
+        self refetchDeviceResources.
         self invalidate
     ].
 !
@@ -280,6 +278,21 @@
         showLines := aState.
         self invalidate
     ].
+!
+
+showRoot
+    "list with or without root
+    "
+  ^ showRoot
+!
+
+showRoot:aState
+    "list with or without root
+    "
+    showRoot ~~ aState ifTrue:[
+        showRoot := aState.
+        model notNil ifTrue:[model showRoot:showRoot].
+    ].
 ! !
 
 !SelectionInTreeView methodsFor:'accessing-images'!
@@ -296,8 +309,7 @@
     "set the value of the instance variable 'imageClosed' (automatically generated)"
 
     imageClosed := something.
-
-    "Created: 3.7.1997 / 12:34:31 / cg"
+    self refetchDeviceResources.
 !
 
 imageItem
@@ -312,8 +324,7 @@
     "set the value of the instance variable 'imageItem' (automatically generated)"
 
     imageItem := something.
-
-    "Created: 3.7.1997 / 12:34:34 / cg"
+    self refetchDeviceResources.
 !
 
 imageOpened
@@ -328,8 +339,7 @@
     "set the value of the instance variable 'imageOpened' (automatically generated)"
 
     imageOpened := something.
-
-    "Created: 3.7.1997 / 12:34:28 / cg"
+    self refetchDeviceResources.
 ! !
 
 !SelectionInTreeView methodsFor:'drawing'!
@@ -368,97 +378,81 @@
 
 drawFromVisibleLine:startVisLineNr to:endVisLineNr with:fg and:bg
 
-    |nodeIndex listSize end fontHgDiv2 yBot yTop yCtr xFig2 figInset
-     x x1 xFig xStr node level lvl idx image isCollapsable hasChildren radius extent xCross|
+    |size end index yBot yTop yCtr level figWidthDiv2
+     x xFig xStr node lv idx image xCross|
 
-    nodeIndex := self visibleLineToAbsoluteLine:startVisLineNr.
-    listSize  := listOfNodes size.
-    yTop      := self yOfVisibleLine:startVisLineNr.
-    end       := endVisLineNr - startVisLineNr + 1.
+    index := self visibleLineToAbsoluteLine:startVisLineNr.
+    size  := listOfNodes size.
+    yTop  := self yOfVisibleLine:startVisLineNr.
+    end   := endVisLineNr - startVisLineNr + 1.
 
 "/  clear rectangle line and set background color
     self paint:bg.
     self fillRectangleX:0 y:yTop width:width height:(end * fontHeight).
 
-    nodeIndex isNil ifTrue:[^ self].
-    fontHgDiv2 := fontHeight // 2.
-    xFig2  := figuresWidth // 2..
-    radius := xFig2 // 2 - 1.
-    extent := radius + radius + 1.
-    figInset := figuresWidth + imageInset.
+    index isNil ifTrue:[^ self].
+    figWidthDiv2 := imageWidth // 2..
+    yCtr := yTop - (fontHeight // 2).
 
     self paint:fg on:bg.
-
-    (end := nodeIndex + end) > listSize ifTrue:[
-        end := listSize + 1
-    ].
-
-    [nodeIndex < end] whileTrue:[
-        node  := listOfNodes at:nodeIndex.
-        yBot  := yTop + fontHeight.
-        yCtr  := yTop + fontHgDiv2.
-        image := self figureFor:node.
+    (end := index + end) > size ifTrue:[end := size + 1].
 
-        (hasChildren := node hasChildren) ifTrue:[ 
-            isCollapsable := node isCollapsable.
-        ] ifFalse:[
-            isCollapsable := false
-        ].
+    [index < end] whileTrue:[
+        node := listOfNodes at:index.
+        yBot := yTop + fontHeight.
+        yCtr := yCtr + fontHeight.
 
-        (lvl := node level) == level ifFalse:[
-            level  := lvl.
-            xFig   := self xOfFigureNode:node.
-            xStr   := self xOfStringNode:node.
-            xCross := xFig + xFig2 - figInset.
+        (lv := node level) == level ifFalse:[
+            level  := lv.
+            xFig   := self xOfFigureLevel:lv.
+            xStr   := self xOfStringLevel:lv.
+            xCross := (self xOfFigureLevel:(lv-1)) + figWidthDiv2.
         ].
 
         showLines ifTrue:[
-            (isCollapsable and:[node numberOfChildren ~~ 0]) ifTrue:[
-                x := xFig + xFig2.
-                self displayLineFromX:x y:yCtr toX:x y:yBot
+            (node isCollapsable and:[node numberOfChildren ~~ 0]) ifTrue:[
+                x := xFig + figWidthDiv2.
+                self displayLineFromX:x y:yCtr  toX:x y:yBot
             ].
-        "/  draw horizontal and vertical line
-            nodeIndex == 1 ifFalse:[                                    "/ not for root
-                self displayLineFromX:xCross y:yTop toX:xCross y:yCtr.  "/ vertical
+            (level ~~ 1 and:[node parent children last == node]) ifTrue:[
+                self displayLineFromX:xCross y:yTop toX:xCross y:yCtr . "/ vertical
             ].
-            self displayLineFromX:xCross y:yCtr toX:xFig   y:yCtr.       "/ horizontal
+            self displayLineFromX:xCross y:yCtr toX:xFig y:yCtr .       "/ horizontal
 
         "/  draw vertical lines
-            idx  := nodeIndex.
-
-            idx ~~ listSize ifTrue:[
-                x := figInset - xFig2.
+            idx := index.
 
-                [(lvl > 0 and:[(idx := idx + 1) <= listSize])] whileTrue:[
-                    node := listOfNodes at:idx.
-
-                    node level > lvl ifFalse:[
-                        x1 := (self xOfFigureNode:node) - x.
-                        self displayLineFromX:x1 y:yTop toX:x1 y:yBot.
-                        lvl := node level - 1
-                    ]
+            [(lv > 0 and:[(idx := idx + 1) <= size])] whileTrue:[
+                (x := (listOfNodes at:idx) level) <= lv ifTrue:[
+                    lv := x - 1.
+                    x  := (self xOfFigureLevel:lv) + figWidthDiv2.
+                    self displayLineFromX:x y:yTop toX:x y:yBot.
                 ]
             ]
         ].
 
         "/ draw image
+        image := self figureFor:node.
         self displayForm:image x:xFig y:(yCtr - (image height // 2)).
 
         "/ draw text label
-        self drawLabelIndex:nodeIndex atX:xStr y:yCtr.
-
-        (hasChildren and:[showDirectoryIndicator]) ifTrue:[
-            isCollapsable ifTrue:[image := openIndicator]
-                         ifFalse:[image := closeIndicator].
+        self drawLabelIndex:index atX:xStr y:yCtr .
 
-            self displayForm:image
-                           x:(xCross - indicatorWidthDiv2)
-                           y:(yCtr   - indicatorHeightDiv2)
+        "/ draw directory indicator
+        (showDirectoryIndicator and:[node hasChildren]) ifTrue:[
+            node isCollapsable ifTrue:[
+                image := openIndicator.
+                x := extentOpenIndicator.
+            ] ifFalse:[
+                image := closeIndicator.
+                x := extentCloseIndicator.
+            ].
+            self displayForm:image x:(xCross - x x)
+                                   y:(yCtr   - x y)
         ].
-
         "/ setup next line
-        nodeIndex := nodeIndex + 1.
-        yTop      := yBot.
+        index := index + 1.
+        yTop  := yBot.
     ].
 
 
@@ -485,25 +479,14 @@
     ]    
 ! !
 
-!SelectionInTreeView methodsFor:'event handling'!
-
-buttonMultiPress:button x:x y:y
-    |node xFig|
+!SelectionInTreeView methodsFor:'enumerating'!
 
-"
-    ((button == 1) or:[button == #select]) ifTrue:[
-        (node := self selectedNode) notNil ifTrue:[
-            node hasChildren ifTrue:[
-                xFig := self xOfFigureNode:node.
-
-                (x < xFig and:[x > (xFig - figuresWidth)]) ifTrue:[
-                    ^ self
-                ]
-            ]
-        ]
-    ].
-"
-    super buttonMultiPress:button x:x y:y
+detectNode:aOneArgBlock
+    "evaluate the argument, aBlock for each node in the list until
+     the block returns true; in this case return the node which caused
+     the true evaluation. If none node is detected, nil is returned.
+    "
+  ^ listOfNodes detect:aOneArgBlock ifNone:nil
 ! !
 
 !SelectionInTreeView methodsFor:'initialization'!
@@ -521,13 +504,19 @@
      images again and again later; returns maximum extent of the images used.
      Could be redefined by subclass
     "
-    |y x t inset|
+    |y x t|
+
+    imageOpened isNil ifTrue:[
+        imageOpened := (self class imageOpened) onDevice:device.
+    ].
 
-    imageOpened    := (self class imageOpened)    onDevice:device.
-    imageClosed    := (self class imageClosed)    onDevice:device.
-    imageItem      := (self class imageItem)      onDevice:device.
-    openIndicator  := (self class openIndicator)  onDevice:device.
-    closeIndicator := (self class closeIndicator) onDevice:device.
+    imageClosed isNil ifTrue:[
+        imageClosed := (self class imageClosed) onDevice:device.
+    ].
+
+    imageItem isNil ifTrue:[
+        imageItem := (self class imageItem) onDevice:device.
+    ].
 
     y := imageClosed heightOn:self.
     x := imageClosed widthOn:self.
@@ -538,23 +527,6 @@
     (t := imageItem   heightOn:self) > y ifTrue:[y := t].
     (t := imageItem   widthOn:self)  > x ifTrue:[x := t].
 
-    (t := imageItem   heightOn:self) > y ifTrue:[y := t].
-    (t := imageItem   widthOn:self)  > x ifTrue:[x := t].
-
-    indicatorWidthDiv2  := openIndicator heightOn:self.
-    indicatorHeightDiv2 := openIndicator widthOn:self.
-    inset := self class shownIndicatorInset.
-
-    (t := inset + indicatorWidthDiv2)  > y ifTrue:[y := t].
-    (t := inset + indicatorHeightDiv2) > x ifTrue:[x := t].
-
-    indicatorWidthDiv2  := indicatorWidthDiv2  // 2.
-    indicatorHeightDiv2 := indicatorHeightDiv2 // 2.
-
-    (t := 4 + (closeIndicator heightOn:self)) > y ifTrue:[y := t].
-    (t := 4 + (closeIndicator widthOn:self )) > x ifTrue:[x := t].
-
-
   ^ x @ y
 
 !
@@ -562,7 +534,7 @@
 getFontParameters
     super getFontParameters.
 
-    figuresWidth notNil ifTrue:[
+    imageWidth notNil ifTrue:[
         self refetchDeviceResources
     ]
 !
@@ -572,25 +544,51 @@
     "
     super initialize.
     showLines := true.
+    showRoot  := true.
     showDirectoryIndicator := false.
-    textInset    := 2.
-    imageInset   := 0.
-    figuresWidth := 18.                 "/ default: will change during startup
+    textInset  := 2.
+    imageInset := 0.    "/ set during indication enabled
+    imageWidth := 8.    "/ default: will change during startup
 !
 
 refetchDeviceResources
     "reinitialize heavily used device resources - to avoid rendering
      images again and again later
     "
-    |y extent|
+    |extent x1 x2 y|
 
     extent := self fetchImageResources.
+    imageInset := 0.
 
-    extent y > fontHeight ifTrue:[
-        fontHeight := extent y.
+    showDirectoryIndicator ifTrue:[
+        openIndicator isNil ifTrue:[
+            openIndicator := (self class openIndicator) onDevice:device
+        ].
+
+        closeIndicator isNil ifTrue:[
+            closeIndicator := (self class closeIndicator) onDevice:device.
+        ].
+
+        x1 := (openIndicator widthOn:self) // 2.
+        y  := openIndicator heightOn:self.
+        y > extent y ifTrue:[extent y:y].
+        extentOpenIndicator := Point x:x1 y:(y // 2).
+
+        x2 := (closeIndicator widthOn:self) // 2.
+        y  := closeIndicator heightOn:self.
+        y > extent y ifTrue:[extent y:y].
+        extentCloseIndicator := Point x:x2 y:(y // 2).
+
+        x2 > x1 ifTrue:[x1 := x2].
+
+        (x1 := x1 + self class minImageInset) > (imageWidth // 2) ifTrue:[
+            imageInset := x1 - (imageWidth // 2).
+        ].
     ].
-
-    figuresWidth := extent x.
+    extent y >= fontHeight ifTrue:[
+        fontHeight := 1 + extent y.
+    ].
+    imageWidth := extent x.
 
 ! !
 
@@ -622,6 +620,11 @@
     ].
     listOfNodes := #().
   ^ #()
+!
+
+model:aModel
+    aModel showRoot:showRoot.
+    super model:aModel
 ! !
 
 !SelectionInTreeView methodsFor:'private'!
@@ -742,24 +745,36 @@
     ^ listOfNodes findFirst:[:n| n == aNode ]
 !
 
+xOfFigureLevel:aLevel
+    "origin x where to draw the icon
+    "
+    |l|
+
+    showRoot ifTrue:[l := aLevel]
+            ifFalse:[l := aLevel - 1].
+
+    showDirectoryIndicator ifFalse:[l := l - 1].
+  ^ (l * (imageInset + imageWidth)) + imageInset - leftOffset + leftMargin
+
+!
+
 xOfFigureNode:aNode
     "origin x where to draw the icon
     "
-    |level|
-
-    level := aNode level.
+    ^ self xOfFigureLevel:(aNode level)
+!
 
-    showDirectoryIndicator ifFalse:[
-        level := level - 1
-    ].
-  ^ (level * (imageInset + figuresWidth)) - leftOffset
+xOfStringLevel:aLevel
+    "origin x where to draw the text( label )
+    "
+    ^ (self xOfFigureLevel:aLevel) + imageWidth + textInset
 
 !
 
 xOfStringNode:aNode
     "origin x where to draw the text( label )
     "
-    ^ (self xOfFigureNode:aNode) + figuresWidth + textInset
+    ^ self xOfStringLevel:(aNode level)
 
 ! !
 
@@ -799,6 +814,42 @@
 
 !
 
+selectFromListOfNames:aListOfNames
+    "set selection from a list of names
+    "
+    |node comp rdwNd|
+
+    aListOfNames size < 1 ifTrue:[
+        ^ self selection:nil
+    ].
+
+    node := model root.
+
+    aListOfNames do:[:el||next|
+        next := node detectChild:[:e|e name = el].
+
+        next notNil ifTrue:[
+            node hidden ifTrue:[
+                rdwNd isNil ifTrue:[
+                    rdwNd := node.
+                    self selectNode:node.
+                ].
+                node expand
+            ].
+            node := next
+        ]
+    ].
+
+    rdwNd notNil ifTrue:[
+        model updateList.
+        list := self listFromModel.
+        self redrawFromLine:(self indexOfNode:rdwNd).
+        self contentsChanged.
+    ].
+    self selectNode:node.
+
+!
+
 selectNode:aNode
     "change selection to a node
     "
@@ -829,5 +880,5 @@
 !SelectionInTreeView class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libwidg2/SelectionInTreeView.st,v 1.13 1997-08-11 11:01:26 ca Exp $'
+    ^ '$Header: /cvs/stx/stx/libwidg2/SelectionInTreeView.st,v 1.14 1997-08-15 09:24:57 ca Exp $'
 ! !