ListView.st
changeset 51 e895ac4cc7c8
parent 38 4b9b70b2cc87
child 59 450ce95a72a4
--- a/ListView.st	Wed Aug 24 01:38:00 1994 +0200
+++ b/ListView.st	Wed Aug 24 01:38:59 1994 +0200
@@ -24,7 +24,8 @@
                               fontIsFixedWidth fontWidth
                               normalFont boldFont italicFont
                               autoScrollBlock autoScrollDeltaT
-                              searchPattern wordCheck'
+                              searchPattern wordCheck
+                              includesNonStrings'
        classVariableNames:''
        poolDictionaries:''
        category:'Views-Text'
@@ -34,7 +35,7 @@
 COPYRIGHT (c) 1989 by Claus Gittinger
               All Rights Reserved
 
-$Header: /cvs/stx/stx/libwidg/ListView.st,v 1.8 1994-08-07 13:22:46 claus Exp $
+$Header: /cvs/stx/stx/libwidg/ListView.st,v 1.9 1994-08-23 23:38:21 claus Exp $
 '!
 
 !ListView class methodsFor:'documentation'!
@@ -55,7 +56,7 @@
 
 version
 "
-$Header: /cvs/stx/stx/libwidg/ListView.st,v 1.8 1994-08-07 13:22:46 claus Exp $
+$Header: /cvs/stx/stx/libwidg/ListView.st,v 1.9 1994-08-23 23:38:21 claus Exp $
 "
 !
 
@@ -142,7 +143,8 @@
     textStartTop := topMargin + margin.
     innerWidth := width - textStartLeft - (margin * 2).
     self getFontParameters.
-    wordCheck := [:char | char isNationalAlphaNumeric]
+    wordCheck := [:char | char isNationalAlphaNumeric].
+    includesNonStrings := false
 !
 
 initStyle
@@ -239,7 +241,7 @@
     ^ leftMargin
 !
 
-setList:aCollection
+setList:aCollection expandTabs:expandTabs
     "set the contents (a collection of strings);
      dont change position (i.e. do not scroll).
      This can be used to update a self-changing list 
@@ -252,7 +254,11 @@
     list := aCollection.
 
     list notNil ifTrue:[
-        self expandTabs
+        expandTabs ifTrue:[
+            self expandTabs
+        ] ifFalse:[
+            includesNonStrings := (list findFirst:[:l | l notNil and:[l isString not]]) ~~ 0.
+        ]
     ].
     self contentsChanged.
     shown ifTrue:[
@@ -260,6 +266,15 @@
     ]
 !
 
+setList:aCollection
+    "set the contents (a collection of strings);
+     dont change position (i.e. do not scroll).
+     This can be used to update a self-changing list 
+     (for example: a file list being shown, without disturbing user too much)"
+
+    ^ self setList:aCollection expandTabs:true
+!
+
 list:aCollection
     "set the contents (a collection of strings) and scroll to top-left"
 
@@ -304,22 +319,30 @@
      This can be used to update a self-changing list 
      (for example: a file list being shown, without disturbing user too much)."
 
-    something isNil ifTrue:[
-        self setList:nil
-    ] ifFalse:[
-        self setList:(something asText)
-    ]
+    |l|
+
+    l := something.
+    l notNil ifTrue:[
+	l isString ifTrue:[
+	    l := l asText
+	]
+    ].
+    self setList:l
 !
 
 contents:something
     "set the contents (either a string or a Collection of strings)
      also scroll to top-left"
 
-    something isNil ifTrue:[
-        self list:nil
-    ] ifFalse:[
-        self list:(something asText)
-    ]
+    |l|
+
+    l := something.
+    l notNil ifTrue:[
+        l isString ifTrue:[
+            l := l asText
+        ]
+    ].
+    self list:l
 !
 
 contents
@@ -517,15 +540,33 @@
 
     list isNil ifTrue:[^ 0].
 
-    fontIsFixedWidth ifTrue:[
-        max := self lengthOfLongestLine * fontWidth
+    includesNonStrings ifTrue:[
+        max := list 
+                   inject:0 
+                   into:[:maxSoFar :entry |
+                             (
+                                 entry isNil ifTrue:[
+                                     0
+                                 ] ifFalse:[
+                                    entry isString ifTrue:[
+                                        font widthOf:entry
+                                    ] ifFalse:[
+                                        entry widthIn:self
+                                    ]
+                                 ]
+                             ) max:maxSoFar.
+                        ]
     ] ifFalse:[
-        max := 0.
-        list notNil ifTrue:[
-            max := max max:(font widthOf:list)
+        fontIsFixedWidth ifTrue:[
+            max := self lengthOfLongestLine * fontWidth
+        ] ifFalse:[
+            max := 0.
+            list notNil ifTrue:[
+                max := max max:(font widthOf:list)
+            ].
         ].
-    ].
-    ^ max + (leftMargin * 2)
+        ^ max + (leftMargin * 2)
+    ]
 !
 
 yOriginOfContents
@@ -681,6 +722,10 @@
      thisLen  "{ Class: SmallInteger }"
      listSize "{ Class: SmallInteger }" |
 
+    includesNonStrings ifTrue:[
+        ^ width
+    ].
+
     fontIsFixedWidth ifTrue:[
         ^ (self lengthOfLongestLineBetween:firstLine and:lastLine) * fontWidth
     ].
@@ -1398,7 +1443,8 @@
     |w     "{ Class:SmallInteger }"
      h     "{ Class:SmallInteger }"
      m2    "{ Class:SmallInteger }"
-     count "{ Class:SmallInteger }"|
+     count "{ Class:SmallInteger }"
+     prevFirst|
 
     count := nLines.
     (firstLineShown + nLines + nFullLinesShown > list size) ifTrue:[
@@ -1407,28 +1453,29 @@
     count <= 0 ifTrue:[^ self].
 
     self originWillChange.
-    (count >= nLinesShown) ifTrue:[
-        firstLineShown := firstLineShown + count.
-        self redrawFromVisibleLine:1 to:nLinesShown.
-        self originChanged:(count negated)
-    ] ifFalse:[
-        m2 := margin * 2.
-        w := self widthForScrollBetween:firstLineShown
-                                    and:(firstLineShown + nLinesShown).
-        w := w + leftMargin.
+    prevFirst := firstLineShown.
+    firstLineShown := firstLineShown + count.
+    shown ifTrue:[
+        (count >= nLinesShown) ifTrue:[
+            self redrawFromVisibleLine:1 to:nLinesShown.
+        ] ifFalse:[
+            m2 := margin * 2.
+            w := self widthForScrollBetween:prevFirst 
+                                        and:(prevFirst + nLinesShown).
+            w := w + leftMargin.
 
-        firstLineShown := firstLineShown + count.
-        h := (fontHeight * count) + textStartTop.
-        self catchExpose.
-        self copyFrom:self x:margin y:h
-                         toX:margin y:textStartTop
-                       width:w height:(height - m2 - h).
+            h := (fontHeight * count) + textStartTop.
+            self catchExpose.
+            self copyFrom:self x:margin y:h
+                             toX:margin y:textStartTop
+                           width:w height:(height - m2 - h).
 
-        self redrawFromVisibleLine:(nFullLinesShown - count + 1)
-                                to:nLinesShown.
-        self waitForExpose.
-        self originChanged:(count negated).
-    ]
+            self redrawFromVisibleLine:(nFullLinesShown - count + 1)
+                                    to:nLinesShown.
+            self waitForExpose.
+        ].
+    ].
+    self originChanged:count.
 !
 
 scrollDown
@@ -1442,7 +1489,8 @@
 
     |w      "{ Class:SmallInteger }"
      h      "{ Class:SmallInteger }"
-     count  "{ Class:SmallInteger }"|
+     count  "{ Class:SmallInteger }"
+     prevFirst|
 
     count := nLines.
     count >= firstLineShown ifTrue:[
@@ -1451,24 +1499,25 @@
     (count == 0) ifTrue:[^ self].
 
     self originWillChange.
-    (count >= nLinesShown) ifTrue:[
-        firstLineShown := firstLineShown - count.
-        self redrawFromVisibleLine:1 to:nLinesShown.
-        self originChanged:(count negated)
-    ] ifFalse:[
-        w := self widthForScrollBetween:firstLineShown
-                                    and:(firstLineShown + nLinesShown).
-        w := w + leftMargin.
-        firstLineShown := firstLineShown - count.
-        h := (fontHeight * count) + topMargin.
-        self catchExpose.
-        self copyFrom:self x:margin y:topMargin
-                         toX:margin y:h
-                       width:w height:(height - h - margin).
-        self redrawFromVisibleLine:1 to:count.
-        self waitForExpose.
-        self originChanged:(count negated).
-    ]
+    prevFirst := firstLineShown.
+    firstLineShown := firstLineShown - count.
+    shown ifTrue:[
+        (count >= nLinesShown) ifTrue:[
+            self redrawFromVisibleLine:1 to:nLinesShown.
+        ] ifFalse:[
+            w := self widthForScrollBetween:prevFirst
+                                        and:(prevFirst + nLinesShown).
+            w := w + leftMargin.
+            h := (fontHeight * count) + topMargin.
+            self catchExpose.
+            self copyFrom:self x:margin y:topMargin
+                             toX:margin y:h
+                           width:w height:(height - h - margin).
+            self redrawFromVisibleLine:1 to:count.
+            self waitForExpose.
+        ].
+    ].
+    self originChanged:(count negated).
 !
 
 scrollUp
@@ -1693,16 +1742,20 @@
 
     self paint:bg.
 
-    (lineString isNil or:[col > lineString size]) ifTrue:[
-        self fillRectangleX:x y:y width:(font widthOf:' ')
-                                 height:fontHeight.
-        self paint:fg
+    (lineString notNil and:[lineString isString not]) ifTrue:[
+        self drawVisibleLine:visLineNr with:fg and:bg
     ] ifFalse:[
-        characterString := (lineString at:col) asString.
-        self fillRectangleX:x y:y width:(font widthOf:characterString)
-                                 height:fontHeight.
-        self paint:fg.
-        self displayString:characterString x:x y:(y + fontAscent)
+        col > lineString size ifTrue:[
+            self fillRectangleX:x y:y width:(font width) height:fontHeight.
+            self paint:fg
+        ] ifFalse:[
+            characterString := (lineString at:col) asString.
+            self fillRectangleX:x y:y 
+                          width:(font widthOf:characterString)
+                         height:fontHeight.
+            self paint:fg.
+            self displayString:characterString x:x y:(y + fontAscent)
+        ]
     ]
 !
 
@@ -1713,27 +1766,31 @@
 
     (endCol >= startCol) ifTrue:[
         lineString := self visibleAt:visLineNr.
-        x := (self xOfCol:startCol inLine:visLineNr) - leftOffset.
-        y := (self yOfLine:visLineNr).
-        
-        len := lineString size.
-        (startCol > len) ifTrue:[
-            len := endCol - startCol + 1.
-            self paint:bg.
-            self fillRectangleX:x y:y 
-                          width:(fontWidth * len) 
-                         height:fontHeight
+
+        (lineString notNil and:[lineString isString not]) ifTrue:[
+            self drawVisibleLine:visLineNr with:fg and:bg.
         ] ifFalse:[
-            (endCol > len) ifTrue:[
-                characterString := String new:endCol.
-                characterString replaceFrom:1 to:len with:lineString startingAt:1.
-                lineString := characterString
-            ].
-            self paint:bg.
-            self fillRectangleX:x y:y width:(font widthOf:lineString from:startCol to:endCol)
-                                      height:fontHeight.
-            self paint:fg.
-            self displayString:lineString from:startCol to:endCol x:x y:(y + fontAscent)
+            x := (self xOfCol:startCol inLine:visLineNr) - leftOffset.
+            y := (self yOfLine:visLineNr).
+            len := lineString size.
+            (startCol > len) ifTrue:[
+                len := endCol - startCol + 1.
+                self paint:bg.
+                self fillRectangleX:x y:y 
+                              width:(fontWidth * len) 
+                             height:fontHeight
+            ] ifFalse:[
+                (endCol > len) ifTrue:[
+                    characterString := String new:endCol.
+                    characterString replaceFrom:1 to:len with:lineString startingAt:1.
+                    lineString := characterString
+                ].
+                self paint:bg.
+                self fillRectangleX:x y:y width:(font widthOf:lineString from:startCol to:endCol)
+                                          height:fontHeight.
+                self paint:fg.
+                self displayString:lineString from:startCol to:endCol x:x y:(y + fontAscent)
+            ]
         ]
     ]
 !
@@ -1754,14 +1811,18 @@
     self fillRectangleX:x y:y
                   width:(width + leftOffset - x)
                  height:fontHeight.
-    
+
     lineString := self visibleAt:visLineNr.
     lineString notNil ifTrue:[
-        index2 := lineString size.
-        (index2 < index1) ifTrue:[^ self].
-        (index1 <= index2) ifTrue:[
-            self paint:fg.
-            self displayString:lineString from:index1 to:index2 x:x y:(y + fontAscent)
+        lineString isString ifFalse:[
+            self drawVisibleLine:visLineNr with:fg and:bg.
+        ] ifTrue:[
+            index2 := lineString size.
+            (index2 < index1) ifTrue:[^ self].
+            (index1 <= index2) ifTrue:[
+                self paint:fg.
+                self displayString:lineString from:index1 to:index2 x:x y:(y + fontAscent)
+            ]
         ]
     ]
 !
@@ -2018,27 +2079,33 @@
         "if area is big enough redraw whole lines"
         self redrawFromVisibleLine:startLine to:stopLine
     ] ifFalse:[
-        fontIsFixedWidth ifFalse:[
-            "start/end col has to be computed for each line"
-
+        includesNonStrings ifTrue:[
             startLine to:stopLine do:[:i |
-                startCol := self colOfX:x inVisibleLine:i.
-                endCol := self colOfX:(x + w) inVisibleLine:i.
-                startCol > 0 ifTrue:[
-                    endCol > 0 ifTrue:[
-                        self redrawVisibleLine:i from:startCol to:endCol
+                self redrawVisibleLine:i
+            ]
+        ] ifFalse:[
+            fontIsFixedWidth ifFalse:[
+                "start/end col has to be computed for each line"
+
+                startLine to:stopLine do:[:i |
+                    startCol := self colOfX:x inVisibleLine:i.
+                    endCol := self colOfX:(x + w) inVisibleLine:i.
+                    startCol > 0 ifTrue:[
+                        endCol > 0 ifTrue:[
+                            self redrawVisibleLine:i from:startCol to:endCol
+                        ]
                     ]
                 ]
-            ]
-        ] ifTrue:[
-            "start/end col is the same for all lines"
+            ] ifTrue:[
+                "start/end col is the same for all lines"
 
-            startCol := self colOfX:x inVisibleLine:startLine.
-            endCol := self colOfX:(x + w) inVisibleLine:startLine.
-            startCol > 0 ifTrue:[
-                endCol > 0 ifTrue:[
-                    startLine to:stopLine do:[:i |
-                        self redrawVisibleLine:i from:startCol to:endCol
+                startCol := self colOfX:x inVisibleLine:startLine.
+                endCol := self colOfX:(x + w) inVisibleLine:startLine.
+                startCol > 0 ifTrue:[
+                    endCol > 0 ifTrue:[
+                        startLine to:stopLine do:[:i |
+                            self redrawVisibleLine:i from:startCol to:endCol
+                        ]
                     ]
                 ]
             ]