ListView.st
changeset 38 4b9b70b2cc87
parent 24 966098a893f8
child 51 e895ac4cc7c8
equal deleted inserted replaced
37:8dd71a2e79cd 38:4b9b70b2cc87
    22                               tabPositions lineSpacing
    22                               tabPositions lineSpacing
    23                               fontHeight fontAscent
    23                               fontHeight fontAscent
    24                               fontIsFixedWidth fontWidth
    24                               fontIsFixedWidth fontWidth
    25                               normalFont boldFont italicFont
    25                               normalFont boldFont italicFont
    26                               autoScrollBlock autoScrollDeltaT
    26                               autoScrollBlock autoScrollDeltaT
    27                               searchPattern'
    27                               searchPattern wordCheck'
    28        classVariableNames:''
    28        classVariableNames:''
    29        poolDictionaries:''
    29        poolDictionaries:''
    30        category:'Views-Text'
    30        category:'Views-Text'
    31 !
    31 !
    32 
    32 
    33 ListView comment:'
    33 ListView comment:'
    34 
       
    35 COPYRIGHT (c) 1989 by Claus Gittinger
    34 COPYRIGHT (c) 1989 by Claus Gittinger
    36               All Rights Reserved
    35               All Rights Reserved
    37 
    36 
    38 $Header: /cvs/stx/stx/libwidg/ListView.st,v 1.7 1994-01-13 00:17:08 claus Exp $
    37 $Header: /cvs/stx/stx/libwidg/ListView.st,v 1.8 1994-08-07 13:22:46 claus Exp $
    39 
       
    40 written spring 89 by claus
       
    41 '!
    38 '!
    42 
    39 
    43 !ListView class methodsFor:'documentation'!
    40 !ListView class methodsFor:'documentation'!
       
    41 
       
    42 copyright
       
    43 "
       
    44  COPYRIGHT (c) 1989 by Claus Gittinger
       
    45               All Rights Reserved
       
    46 
       
    47  This software is furnished under a license and may be used
       
    48  only in accordance with the terms of that license and with the
       
    49  inclusion of the above copyright notice.   This software may not
       
    50  be provided or otherwise made available to, or used by, any
       
    51  other person.  No title to or ownership of the software is
       
    52  hereby transferred.
       
    53 "
       
    54 !
       
    55 
       
    56 version
       
    57 "
       
    58 $Header: /cvs/stx/stx/libwidg/ListView.st,v 1.8 1994-08-07 13:22:46 claus Exp $
       
    59 "
       
    60 !
    44 
    61 
    45 documentation
    62 documentation
    46 "
    63 "
    47 a simple View for lists - the elements must understand printString
    64     a View for (string-)lists.
    48 the list is changed - the elements are replaced by their printStrings
    65 
    49 (if this leads to problems - I will change it later)
    66     This class can only passively display collections of strings-
    50 
    67     selections, editing, cursors etc. must be done in subclasses.
    51 This class can only passively display -
    68     see SelectionInListView, TextView etc.
    52 selections, editing, cursors etc. must be done in subclasses.
    69 
    53 see SelectionInListView, TextView etc.
    70     This code currently handles only fixed-height fonts correctly -
    54 
    71     should be rewritten in some places ...
    55 This code currently handles only fixed-height fonts correctly -
    72 
    56 should be rewritten in some places ...
    73     It can only scroll by full lines vertically (i.e. setting firstLineShown to ~~ 1)
    57 
    74     which should be changed to have this behavior optionally for smooth scroll.
    58 Instance variables:
    75 
    59 
    76     This is being totally rewritten ... so dont depend on the internals.
    60 list            <aCollection>           the text strings
    77 
    61 attributes      <aCollection>           corresponding attributes
    78 
    62 firstLineShown  <Number>                the index of the 1st visible line (1 ..)
    79     Instance variables:
    63 leftOffset      <Number>                left offset for horizontal scroll
    80 
    64 nFullLinesShown <Number>                the number of unclipped lines in visible
    81     list            <aCollection>           the text strings
    65 nLinesShown     <Number>                the number of lines in visible
    82     attributes      <aCollection>           corresponding attributes (if any)
    66 fgColor         <Color>                 color to draw characters
    83     firstLineShown  <Number>                the index of the 1st visible line (1 ..)
    67 bgColor         <Color>                 the background
    84     leftOffset      <Number>                left offset for horizontal scroll
    68 partialLines    <Boolean>               allow last line to be partial displayed
    85 
    69 leftMargin      <Number>                margin at left in pixels
    86     nFullLinesShown <Number>                the number of unclipped lines in visible
    70 topMargin       <Number>                margin at top in pixels
    87     nLinesShown     <Number>                the number of lines in visible
    71 textStartLeft   <Number>                margin + leftMargin
    88     fgColor         <Color>                 color to draw characters
    72 textStartTop    <Number>                margin + topMargin
    89     bgColor         <Color>                 the background
    73 innerWidth      <Number>                width - margins
    90     partialLines    <Boolean>               allow last line to be partial displayed
    74 tabPositions    <aCollection>           tab stops (cols)
    91     leftMargin      <Number>                margin at left in pixels
    75 fontHeight      <Number>                font height in pixels
    92     topMargin       <Number>                margin at top in pixels
    76 fontAscent      <Number>                font ascent in pixels
    93     textStartLeft   <Number>                margin + leftMargin
    77 fontIsFixed     <Boolean>               true if its a fixed font
    94     textStartTop    <Number>                margin + topMargin
    78 fontWidth       <Number>                width of space
    95     innerWidth      <Number>                width - margins
    79 lineSpacing     <Number>                pixels between lines
    96     tabPositions    <aCollection>           tab stops (cols)
    80 normalFont      <Font>                  font for normal characters
    97     fontHeight      <Number>                font height in pixels
    81 boldFont        <Font>                  font for bold characters
    98     fontAscent      <Number>                font ascent in pixels
    82 italicFont      <Font>                  font for italic characters
    99     fontIsFixed     <Boolean>               true if its a fixed font
    83 searchPattern   <String>                last pattern for searching
   100     fontWidth       <Number>                width of space
       
   101     lineSpacing     <Number>                pixels between lines
       
   102     normalFont      <Font>                  font for normal characters
       
   103     boldFont        <Font>                  font for bold characters
       
   104     italicFont      <Font>                  font for italic characters
       
   105     searchPattern   <String>                last pattern for searching
       
   106     wordCheck       <Block>                 rule used for check in word select
    84 "
   107 "
    85 ! !
   108 ! !
    86 
   109 
    87 !ListView class methodsFor:'defaults'!
   110 !ListView class methodsFor:'defaults'!
    88 
   111 
   100 ! !
   123 ! !
   101 
   124 
   102 !ListView methodsFor:'initialization'!
   125 !ListView methodsFor:'initialization'!
   103 
   126 
   104 initialize
   127 initialize
       
   128     leftMargin := (self horizontalPixelPerMillimeter:0.5) rounded.
       
   129 
   105     super initialize.
   130     super initialize.
   106 
   131 
   107     bitGravity := #NorthWest.
   132     bitGravity := #NorthWest.
   108     list := nil.
   133     list := nil.
   109     firstLineShown := 1.
   134     firstLineShown := 1.
       
   135     nFullLinesShown := 1. "just any value ..."
       
   136     nLinesShown := 1.     "just any value"
   110     leftOffset := 0.
   137     leftOffset := 0.
   111     partialLines := true.
   138     partialLines := true.
   112     tabPositions := self class defaultTabPositions.
   139     tabPositions := self class defaultTabPositions.
   113     leftMargin := (self horizontalPixelPerMillimeter:0.5) rounded.
       
   114     topMargin := (self verticalPixelPerMillimeter:0.5) rounded.
   140     topMargin := (self verticalPixelPerMillimeter:0.5) rounded.
   115     textStartLeft := leftMargin + margin.
   141     textStartLeft := leftMargin + margin.
   116     textStartTop := topMargin + margin.
   142     textStartTop := topMargin + margin.
   117     innerWidth := width - textStartLeft - margin.
   143     innerWidth := width - textStartLeft - (margin * 2).
   118     self getFontParameters
   144     self getFontParameters.
       
   145     wordCheck := [:char | char isNationalAlphaNumeric]
   119 !
   146 !
   120 
   147 
   121 initStyle
   148 initStyle
   122     super initStyle.
   149     super initStyle.
   123     fgColor := Black.
   150 
   124     bgColor := White.
   151     fgColor := resources at:'FOREGROUND_COLOR' default:Black.
       
   152     bgColor := resources at:'BACKGROUND_COLOR' default:White.
   125     lineSpacing := 0.
   153     lineSpacing := 0.
   126 !
   154 
   127 
   155     "Transcript class classResources at:'FOREGROUND_COLOR' put:Color red.
   128 initEvents
   156      Transcript class classResources at:'BACKGROUND_COLOR' put:Color white"
   129     self enableKeyEvents
       
   130 !
   157 !
   131 
   158 
   132 create
   159 create
   133     super create.
   160     super create.
   134 
   161 
   158 !ListView methodsFor:'accessing'!
   185 !ListView methodsFor:'accessing'!
   159 
   186 
   160 backgroundColor:aColor
   187 backgroundColor:aColor
   161     "set the background color"
   188     "set the background color"
   162 
   189 
   163     bgColor := aColor.
   190     bgColor ~~ aColor ifTrue:[
   164     shown ifTrue:[
   191         bgColor := aColor.
   165         self redraw
   192         shown ifTrue:[
       
   193             self redraw
       
   194         ]
   166     ]
   195     ]
   167 !
   196 !
   168 
   197 
   169 foregroundColor:aColor
   198 foregroundColor:aColor
   170     "set the foreground color"
   199     "set the foreground color"
   171 
   200 
   172     fgColor := aColor.
   201     fgColor ~~ aColor ifTrue:[
   173     shown ifTrue:[
   202         fgColor := aColor.
   174         self redraw
   203         shown ifTrue:[
       
   204             self redraw
       
   205         ]
   175     ]
   206     ]
   176 !
   207 !
   177 
   208 
   178 foregroundColor:color1 backgroundColor:color2
   209 foregroundColor:color1 backgroundColor:color2
   179     "set both foreground and background colors"
   210     "set both foreground and background colors"
   180 
   211 
   181     fgColor := color1.
   212     ((fgColor ~~ color1) or:[bgColor ~~ color2]) ifTrue:[
   182     bgColor := color2.
   213         fgColor := color1.
   183     shown ifTrue:[
   214         bgColor := color2.
   184         self redraw
   215         shown ifTrue:[
       
   216             self redraw
       
   217         ]
   185     ]
   218     ]
   186 !
   219 !
   187 
   220 
   188 partialLines:aBoolean
   221 partialLines:aBoolean
   189     "allow/disallow display of a last partial line"
   222     "allow/disallow display of a last partial line"
   205 
   238 
   206     ^ leftMargin
   239     ^ leftMargin
   207 !
   240 !
   208 
   241 
   209 setList:aCollection
   242 setList:aCollection
   210     "set the contents (a collection of strings) keep position unchanged"
   243     "set the contents (a collection of strings);
       
   244      dont change position (i.e. do not scroll).
       
   245      This can be used to update a self-changing list 
       
   246      (for example: a file list being shown, without disturbing user too much)"
   211 
   247 
   212     (aCollection isNil and:[list isNil]) ifTrue:[
   248     (aCollection isNil and:[list isNil]) ifTrue:[
   213         "no change"
   249         "no change"
   214         ^ self
   250         ^ self
   215     ].
   251     ].
   223         self redrawFromVisibleLine:1 to:nLinesShown
   259         self redrawFromVisibleLine:1 to:nLinesShown
   224     ]
   260     ]
   225 !
   261 !
   226 
   262 
   227 list:aCollection
   263 list:aCollection
   228     "set the contents (a collection of strings) and scroll to top"
   264     "set the contents (a collection of strings) and scroll to top-left"
   229 
   265 
   230     |oldFirst|
   266     |oldFirst oldLeft|
   231 
   267 
   232     (aCollection isNil and:[list isNil]) ifTrue:[
   268     (aCollection isNil and:[list isNil]) ifTrue:[
   233         "no change"
   269         "no change"
   234         self scrollToTop.
   270         self scrollToTop.
       
   271         self scrollToLeft.
   235         ^ self
   272         ^ self
   236     ].
   273     ].
   237     list := aCollection.
   274     list := aCollection.
   238 
   275 
   239     list notNil ifTrue:[
   276     list notNil ifTrue:[
   240         self expandTabs
   277         self expandTabs
   241     ].
   278     ].
   242     self contentsChanged.
       
   243     "dont use scroll here to avoid the redraw"
       
   244     oldFirst := firstLineShown.
   279     oldFirst := firstLineShown.
       
   280     oldLeft := leftOffset.
   245     firstLineShown := 1.
   281     firstLineShown := 1.
   246     self originChanged:(oldFirst - 1) negated.
   282     leftOffset := 0.
   247     shown ifTrue:[
   283     realized ifTrue:[
   248         self redrawFromVisibleLine:1 to:nLinesShown
   284         self contentsChanged.
       
   285         "
       
   286          dont use scroll here to avoid the redraw
       
   287         "
       
   288         self originChanged:(oldFirst - 1) negated.
       
   289         shown ifTrue:[
       
   290             self redrawFromVisibleLine:1 to:nLinesShown
       
   291         ]
   249     ]
   292     ]
   250 !
   293 !
   251 
   294 
   252 list
   295 list
   253     "return the contents as a collection of strings"
   296     "return the contents as a collection of strings"
   255     ^ list
   298     ^ list
   256 !
   299 !
   257 
   300 
   258 setContents:something
   301 setContents:something
   259     "set the contents (either a string or a Collection of strings)
   302     "set the contents (either a string or a Collection of strings)
   260      dont change position"
   303      dont change position (i.e. do not scroll).
       
   304      This can be used to update a self-changing list 
       
   305      (for example: a file list being shown, without disturbing user too much)."
   261 
   306 
   262     something isNil ifTrue:[
   307     something isNil ifTrue:[
   263         self setList:nil
   308         self setList:nil
   264     ] ifFalse:[
   309     ] ifFalse:[
   265         self setList:(something asText)
   310         self setList:(something asText)
   266     ]
   311     ]
   267 !
   312 !
   268 
   313 
   269 contents:something
   314 contents:something
   270     "set the contents (either a string or a Collection of strings)
   315     "set the contents (either a string or a Collection of strings)
   271      also scroll to top"
   316      also scroll to top-left"
   272 
   317 
   273     something isNil ifTrue:[
   318     something isNil ifTrue:[
   274         self list:nil
   319         self list:nil
   275     ] ifFalse:[
   320     ] ifFalse:[
   276         self list:(something asText)
   321         self list:(something asText)
   304     "delete line - no redraw;
   349     "delete line - no redraw;
   305      return true, if something was really deleted"
   350      return true, if something was really deleted"
   306 
   351 
   307     (list isNil or:[lineNr > list size]) ifTrue:[^ false].
   352     (list isNil or:[lineNr > list size]) ifTrue:[^ false].
   308     list removeIndex:lineNr.
   353     list removeIndex:lineNr.
       
   354     (attributes notNil and:[lineNr <= attributes size]) ifTrue:[attributes removeIndex:lineNr].
       
   355 
   309     lineNr < firstLineShown ifTrue:[
   356     lineNr < firstLineShown ifTrue:[
   310         firstLineShown := firstLineShown - 1
   357         firstLineShown := firstLineShown - 1
   311     ].
   358     ].
   312     self contentsChanged.
   359     self contentsChanged.
   313     ^ true
   360     ^ true
   317     "delete line"
   364     "delete line"
   318 
   365 
   319     |visLine w
   366     |visLine w
   320      srcY "{ Class: SmallInteger }" |
   367      srcY "{ Class: SmallInteger }" |
   321 
   368 
   322     w := self widthForScrollBetween:lineNr
       
   323                                 and:(firstLineShown + nLinesShown).
       
   324     (self removeIndexWithoutRedraw:lineNr) ifFalse:[^ self].
   369     (self removeIndexWithoutRedraw:lineNr) ifFalse:[^ self].
       
   370     "
       
   371      is there a need to redraw ?
       
   372     "
   325     visLine := self listLineToVisibleLine:lineNr.
   373     visLine := self listLineToVisibleLine:lineNr.
   326     visLine notNil ifTrue:[
   374     visLine notNil ifTrue:[
       
   375         w := self widthForScrollBetween:lineNr and:(firstLineShown + nLinesShown).
   327         srcY := topMargin + (visLine * fontHeight).
   376         srcY := topMargin + (visLine * fontHeight).
   328         self catchExpose.
   377         self catchExpose.
   329         self copyFrom:self x:textStartLeft y:srcY
   378         self copyFrom:self x:textStartLeft y:srcY
   330                          toX:textStartLeft y:(srcY - fontHeight)
   379                          toX:textStartLeft y:(srcY - fontHeight)
   331                        width:w height:((nLinesShown - visLine) * fontHeight).
   380                        width:w height:((nLinesShown - visLine) * fontHeight).
   341     "set the font"
   390     "set the font"
   342 
   391 
   343     aFont isNil ifTrue:[
   392     aFont isNil ifTrue:[
   344         ^ self error:'nil font'
   393         ^ self error:'nil font'
   345     ].
   394     ].
   346     super font:aFont.
   395     font ~~ aFont ifTrue:[
   347     (font device == device) ifTrue:[
   396         super font:aFont.
   348         self getFontParameters.
   397         realized ifTrue:[
   349         self computeNumberOfLinesShown.
   398             (font device == device) ifTrue:[
   350         shown ifTrue:[
   399                 self getFontParameters.
   351             self redrawFromVisibleLine:1 to:nLinesShown
   400                 self computeNumberOfLinesShown.
   352         ]
   401                 shown ifTrue:[
   353     ].
   402                     self redrawFromVisibleLine:1 to:nLinesShown
   354     self contentsChanged
   403                 ]
       
   404             ].
       
   405             self contentsChanged
       
   406         ]
       
   407     ]
   355 !
   408 !
   356 
   409 
   357 level:aNumber
   410 level:aNumber
   358     "set the level - cought here to update text-position variables
   411     "set the level - cought here to update text-position variables
   359      (which avoid many computations later)"
   412      (which avoids many computations later)"
   360 
   413 
   361     super level:aNumber.
   414     super level:aNumber.
   362 
   415 
   363     textStartLeft := leftMargin + margin.
   416     textStartLeft := leftMargin + margin.
   364     textStartTop := topMargin + margin.
   417     textStartTop := topMargin + margin.
   380 
   433 
   381     ^ firstLineShown
   434     ^ firstLineShown
   382 !
   435 !
   383 
   436 
   384 lastLineShown
   437 lastLineShown
   385     "return the index of the last (possibly partial)
   438     "return the index of the last (possibly partial) visible line"
   386      visible line"
       
   387 
   439 
   388     ^ firstLineShown + nLinesShown
   440     ^ firstLineShown + nLinesShown
   389 !
   441 !
   390 
   442 
   391 numberOfLines
   443 numberOfLines
   395 !
   447 !
   396 
   448 
   397 lengthOfLongestLine
   449 lengthOfLongestLine
   398     "return the length (in characters) of the longest line"
   450     "return the length (in characters) of the longest line"
   399 
   451 
   400     |max      "{ Class: SmallInteger }"
   452     ^ self lengthOfLongestLineBetween:1 and:list size
   401      thisLen  "{ Class: SmallInteger }" |
       
   402 
       
   403     max := 0.
       
   404     list notNil ifTrue:[
       
   405         list do:[:lineString |
       
   406             lineString notNil ifTrue:[
       
   407                 thisLen := lineString size.
       
   408                 (thisLen > max) ifTrue:[
       
   409                     max := thisLen
       
   410                 ]
       
   411             ]
       
   412         ]
       
   413     ].
       
   414     ^ max
       
   415 !
   453 !
   416 
   454 
   417 lengthOfLongestLineBetween:firstLine and:lastLine
   455 lengthOfLongestLineBetween:firstLine and:lastLine
   418     "return the length (in characters) of the longest line in a line-range"
   456     "return the length (in characters) of the longest line in a line-range"
   419 
   457 
   420     |max      "{ Class: SmallInteger }"
   458     |max      "{ Class: SmallInteger }"
   421      thisLen  "{ Class: SmallInteger }"
   459      thisLen  "{ Class: SmallInteger }"
   422      listSize "{ Class: SmallInteger }"
   460      listSize "{ Class: SmallInteger }"
   423      first    "{ Class: SmallInteger }"
   461      first    "{ Class: SmallInteger }"
   424      last     "{ Class: SmallInteger }" |
   462      last     "{ Class: SmallInteger }" |
       
   463 
       
   464     list isNil ifTrue:[^ 0].
   425 
   465 
   426     listSize := list size.
   466     listSize := list size.
   427     max := 0.
   467     max := 0.
   428     first := firstLine.
   468     first := firstLine.
   429     last := lastLine.
   469     last := lastLine.
   448      - used for scrollbar interface"
   488      - used for scrollbar interface"
   449 
   489 
   450     | numLines |
   490     | numLines |
   451 
   491 
   452     numLines := self numberOfLines.
   492     numLines := self numberOfLines.
   453     ^ numLines * fontHeight + textStartTop.
   493     numLines == 0 ifTrue:[^ 0].
   454 
   494     "
   455     "it used to be that code - which is wrong"
   495      need device-font for query
   456     (nLinesShown == nFullLinesShown) ifTrue:[
   496     "
   457         ^ numLines * fontHeight
   497     font := font on:device.
   458     ].
   498     ^ numLines * fontHeight + textStartTop
   459     "add one - otherwise we cannot make last line
   499                             + (font descent) "makes it look better".
   460      fully visible since scrolling is done by full lines only"
   500 "/                            + (font descent * 2) "makes it look better".
   461 
   501 
   462     ^ (numLines + 1) * fontHeight
   502 "/    "it used to be that code - which is wrong"
       
   503 "/    (nLinesShown == nFullLinesShown) ifTrue:[
       
   504 "/        ^ numLines * fontHeight
       
   505 "/    ].
       
   506 "/    "add one - otherwise we cannot make last line
       
   507 "/     fully visible since scrolling is done by full lines only"
       
   508 "/
       
   509 "/    ^ (numLines + 1) * fontHeight
   463 !
   510 !
   464 
   511 
   465 widthOfContents
   512 widthOfContents
   466     "return the width of the contents in pixels"
   513     "return the width of the contents in pixels
       
   514      - used for scrollbar interface"
   467 
   515 
   468     |max|
   516     |max|
   469 
   517 
       
   518     list isNil ifTrue:[^ 0].
       
   519 
   470     fontIsFixedWidth ifTrue:[
   520     fontIsFixedWidth ifTrue:[
   471         ^ self lengthOfLongestLine * fontWidth
   521         max := self lengthOfLongestLine * fontWidth
   472     ].
   522     ] ifFalse:[
   473     max := 0.
   523         max := 0.
   474     list notNil ifTrue:[
   524         list notNil ifTrue:[
   475         max := max max:(font widthOf:list)
   525             max := max max:(font widthOf:list)
   476     ].
   526         ].
   477     ^ max
   527     ].
       
   528     ^ max + (leftMargin * 2)
   478 !
   529 !
   479 
   530 
   480 yOriginOfContents
   531 yOriginOfContents
   481     "return the vertical origin of the contents in pixels
   532     "return the vertical origin of the contents in pixels
   482      - used for scrollbar interface"
   533      - used for scrollbar interface"
   486 
   537 
   487 xOriginOfContents
   538 xOriginOfContents
   488     "return the horizontal origin of the contents in pixels
   539     "return the horizontal origin of the contents in pixels
   489      - used for scrollbar interface"
   540      - used for scrollbar interface"
   490 
   541 
   491     ^leftOffset 
   542     ^ leftOffset 
   492 !
   543 !
   493 
   544 
   494 leftIndentOfLine:lineNr
   545 leftIndentOfLine:lineNr
   495     "return the number of spaces at the left in line, lineNr.
   546     "return the number of spaces at the left in line, lineNr.
   496      returns 0 for empty lines."
   547      returns 0 for empty lines."
   619         ]
   670         ]
   620     ]
   671     ]
   621 !
   672 !
   622 
   673 
   623 widthOfWidestLineBetween:firstLine and:lastLine
   674 widthOfWidestLineBetween:firstLine and:lastLine
   624     "return the width in pixels of the widest line in a range"
   675     "return the width in pixels of the widest line in a range
       
   676      - used to optimize scrolling, by limiting the scrolled area"
   625 
   677 
   626     |max      "{ Class: SmallInteger }"
   678     |max      "{ Class: SmallInteger }"
   627      first    "{ Class: SmallInteger }"
   679      first    "{ Class: SmallInteger }"
   628      last     "{ Class: SmallInteger }"
   680      last     "{ Class: SmallInteger }"
   629      thisLen  "{ Class: SmallInteger }"
   681      thisLen  "{ Class: SmallInteger }"
   652     ].
   704     ].
   653     ^ max
   705     ^ max
   654 !
   706 !
   655 
   707 
   656 widthForScrollBetween:firstLine and:lastLine
   708 widthForScrollBetween:firstLine and:lastLine
   657     "return the width in pixels for a scroll between firstLine and lastLine"
   709     "return the width in pixels for a scroll between firstLine and lastLine.
       
   710      - used to optimize scrolling, by limiting the scrolled area.
       
   711      Subclasses with selections or other additional visible stuff should redefine
       
   712      this method."
   658 
   713 
   659     |w|
   714     |w|
   660 
   715 
   661     "for small width, its not worth searching for
   716     "for small width, its not worth searching for
   662      longest line ..."
   717      longest line ..."
   663 
   718 
   664     (width < 300) ifTrue:[^ innerWidth].
   719     (width < 300) ifTrue:[^ innerWidth].
   665 
   720 
   666     w := self widthOfWidestLineBetween:firstLine
   721     "for large lists, search is longer than scrolling full"
   667                                    and:lastLine.
   722 
       
   723     list size > 2000 ifTrue:[^ innerWidth].
       
   724 
       
   725     w := self widthOfWidestLineBetween:firstLine and:lastLine.
   668     (w > innerWidth) ifTrue:[^ innerWidth].
   726     (w > innerWidth) ifTrue:[^ innerWidth].
   669     ^ w
   727     ^ w
   670 !
   728 !
   671 
   729 
   672 listAt:lineNr
   730 listAt:lineNr
   697     |line|
   755     |line|
   698 
   756 
   699     line := self listAt:lineNr.
   757     line := self listAt:lineNr.
   700     line isNil ifTrue:[^ nil].
   758     line isNil ifTrue:[^ nil].
   701     (startCol > line size) ifTrue:[^ nil].
   759     (startCol > line size) ifTrue:[^ nil].
   702     ^ line copyFrom:startCol to:(line size)
   760     ^ line copyFrom:startCol
   703 !
   761 !
   704 
   762 
   705 listAt:lineNr to:endCol
   763 listAt:lineNr to:endCol
   706     "return left substring from start to endCol of a line"
   764     "return left substring from start to endCol of a line"
   707 
   765 
   709 
   767 
   710     line := self listAt:lineNr.
   768     line := self listAt:lineNr.
   711     line isNil ifTrue:[^ nil].
   769     line isNil ifTrue:[^ nil].
   712     stop := endCol.
   770     stop := endCol.
   713     (stop > line size) ifTrue:[stop := line size].
   771     (stop > line size) ifTrue:[stop := line size].
   714     ^ line copyFrom:1 to:stop
   772     ^ line copyTo:stop
   715 !
   773 !
   716 
   774 
   717 listLineToVisibleLine:listLineNr
   775 listLineToVisibleLine:listLineNr
   718     "given a list line (1..) return visible linenr or nil"
   776     "given a list line (1..) return visible linenr or nil"
   719 
   777 
   794 colOfX:x inVisibleLine:visLineNr
   852 colOfX:x inVisibleLine:visLineNr
   795     "given a visible lineNr and x-coordinate, return colNr"
   853     "given a visible lineNr and x-coordinate, return colNr"
   796 
   854 
   797     |lineString linePixelWidth xRel runCol posLeft posRight done|
   855     |lineString linePixelWidth xRel runCol posLeft posRight done|
   798 
   856 
   799     xRel := x - textStartLeft.
   857     xRel := x - textStartLeft + leftOffset.
   800     fontIsFixedWidth ifTrue:[
   858     fontIsFixedWidth ifTrue:[
   801         ^ (xRel // fontWidth) + 1
   859         ^ (xRel // fontWidth) + 1
   802     ].
   860     ].
   803     lineString := self visibleAt:visLineNr.
   861     lineString := self visibleAt:visLineNr.
   804     lineString notNil ifTrue:[
   862     lineString notNil ifTrue:[
   908 ! !
   966 ! !
   909 
   967 
   910 !ListView methodsFor:'tabulators'!
   968 !ListView methodsFor:'tabulators'!
   911 
   969 
   912 setTab4
   970 setTab4
       
   971     "set 4-character tab stops"
       
   972 
   913     tabPositions := self class tab4Positions.
   973     tabPositions := self class tab4Positions.
   914 !
   974 !
   915 
   975 
   916 setTab8
   976 setTab8
       
   977     "set 8-character tab stops"
       
   978 
   917     tabPositions := self class tab8Positions.
   979     tabPositions := self class tab8Positions.
   918 !
   980 !
   919 
   981 
   920 expandTabs
   982 expandTabs
   921     "go through whole text expanding tabs into spaces"
   983     "go through whole text expanding tabs into spaces"
   925     list notNil ifTrue:[
   987     list notNil ifTrue:[
   926         nLines := list size.
   988         nLines := list size.
   927         1 to:nLines do:[:index |
   989         1 to:nLines do:[:index |
   928             line := list at:index.
   990             line := list at:index.
   929             line notNil ifTrue:[
   991             line notNil ifTrue:[
   930                 (line class == String) ifFalse:[
   992                 line isString ifFalse:[
   931                     newLine := line printString
   993                     newLine := line printString
   932                 ] ifTrue:[
   994                 ] ifTrue:[
   933                     newLine := line
   995                     newLine := line
   934                 ].
   996                 ].
   935                 (newLine occurrencesOf:(Character tab)) == 0 ifFalse:[
   997                 (newLine occurrencesOf:(Character tab)) == 0 ifFalse:[
   985     ].
  1047     ].
   986     ^ tabPositions at:(tabIndex - 1)
  1048     ^ tabPositions at:(tabIndex - 1)
   987 !
  1049 !
   988 
  1050 
   989 withTabsExpanded:line
  1051 withTabsExpanded:line
   990     "good idea, to make this one a primitive"
  1052     "expand tabs into spaces, return a new line string,
   991 
  1053      or original line, if no tabs are included.
   992     |tmpString nString
  1054      good idea, to make this one a primitive"
       
  1055 
       
  1056     |tmpString nString nTabs
   993      currentMax "{ Class: SmallInteger }"
  1057      currentMax "{ Class: SmallInteger }"
   994      dstIndex   "{ Class: SmallInteger }"
  1058      dstIndex   "{ Class: SmallInteger }"
   995      nextTab    "{ Class: SmallInteger }" |
  1059      nextTab    "{ Class: SmallInteger }" |
       
  1060 
       
  1061     line isNil ifTrue:[^ line].
       
  1062     nTabs := line occurrencesOf:(Character tab).
       
  1063     nTabs == 0 ifTrue:[^ line].
   996 
  1064 
   997     currentMax := 200.
  1065     currentMax := 200.
   998     tmpString := String new:currentMax.
  1066     tmpString := String new:currentMax.
   999     dstIndex := 1.
  1067     dstIndex := 1.
  1000     line do:[:character |
  1068     line do:[:character |
  1019 
  1087 
  1020         "make stc-optimizer happy
  1088         "make stc-optimizer happy
  1021          - no need to return value of ifTrue:/ifFalse above"
  1089          - no need to return value of ifTrue:/ifFalse above"
  1022         0
  1090         0
  1023     ].
  1091     ].
  1024     ^ tmpString copyFrom:1 to:(dstIndex - 1)
  1092     ^ tmpString copyTo:(dstIndex - 1)
       
  1093 !
       
  1094 
       
  1095 withTabs:line
       
  1096     "Assuming an 8-character tab,
       
  1097      compress multiple spaces to tabs, return a new line string
       
  1098      or original line, if no tabs where created.
       
  1099      good idea, to make this one a primitive"
       
  1100 
       
  1101     |newLine|
       
  1102 
       
  1103     line isNil ifTrue:[^ line].
       
  1104     (line startsWith:'        ') ifFalse:[^ line].
       
  1105 
       
  1106     newLine := line copyFrom:9.
       
  1107     [newLine startsWith:'        '] whileTrue:[
       
  1108         newLine := Character tab asString , (newLine copyFrom:9)
       
  1109     ].
       
  1110     ^ newLine
  1025 ! !
  1111 ! !
  1026 
  1112 
  1027 !ListView methodsFor:'searching'!
  1113 !ListView methodsFor:'searching'!
  1028 
  1114 
  1029 setSearchPattern:aString
  1115 setSearchPattern:aString
  1032     searchPattern := aString withoutSeparators
  1118     searchPattern := aString withoutSeparators
  1033 !
  1119 !
  1034 
  1120 
  1035 searchForwardFor:pattern startingAtLine:startLine col:startCol ifFound:block1 else:block2
  1121 searchForwardFor:pattern startingAtLine:startLine col:startCol ifFound:block1 else:block2
  1036     "search for a pattern, if found evaluate block1 with row/col as arguments, if not
  1122     "search for a pattern, if found evaluate block1 with row/col as arguments, if not
  1037      found evaluate block2"
  1123      found evaluate block2.
       
  1124      Sorry, but pattern is no regular expression pattern (yet)"
  1038 
  1125 
  1039     |lineString col savedCursor patternSize|
  1126     |lineString col savedCursor patternSize|
  1040 
  1127 
  1041     patternSize := pattern size.
  1128     patternSize := pattern size.
  1042     patternSize ~~ 0 ifTrue:[
  1129     patternSize ~~ 0 ifTrue:[
  1062     ^ block2 value
  1149     ^ block2 value
  1063 !
  1150 !
  1064 
  1151 
  1065 searchBackwardFor:pattern startingAtLine:startLine col:startCol ifFound:block1 else:block2
  1152 searchBackwardFor:pattern startingAtLine:startLine col:startCol ifFound:block1 else:block2
  1066     "search for a pattern, if found evaluate block1 with row/col as arguments, if not
  1153     "search for a pattern, if found evaluate block1 with row/col as arguments, if not
  1067      found evaluate block2"
  1154      found evaluate block2.
       
  1155      Sorry, but pattern is no regular expression pattern (yet)"
  1068 
  1156 
  1069     |lineString col cc found firstChar savedCursor patternSize|
  1157     |lineString col cc found firstChar savedCursor patternSize|
  1070 
  1158 
  1071     patternSize := pattern size.
  1159     patternSize := pattern size.
  1072     patternSize ~~ 0 ifTrue:[
  1160     patternSize ~~ 0 ifTrue:[
  1113     ].
  1201     ].
  1114     "not found"
  1202     "not found"
  1115 
  1203 
  1116     self cursor:savedCursor.
  1204     self cursor:savedCursor.
  1117     ^ block2 value
  1205     ^ block2 value
       
  1206 !
       
  1207 
       
  1208 findBeginOfWordAtLine:selectLine col:selectCol
       
  1209     "return the col of first character of the word at given line/col.
       
  1210      If the character under the initial col is a space character, return
       
  1211      the first col of the blank-block."
       
  1212 
       
  1213     |beginCol thisCharacter|
       
  1214 
       
  1215     beginCol := selectCol.
       
  1216     thisCharacter := self characterAtLine:selectLine col:beginCol.
       
  1217 
       
  1218     "is this acharacter within a word ?"
       
  1219     (wordCheck value:thisCharacter) ifTrue:[
       
  1220         [wordCheck value:thisCharacter] whileTrue:[
       
  1221             beginCol := beginCol - 1.
       
  1222             beginCol < 1 ifTrue:[
       
  1223                 thisCharacter := Character space
       
  1224             ] ifFalse:[
       
  1225                 thisCharacter := self characterAtLine:selectLine col:beginCol
       
  1226             ]
       
  1227         ].
       
  1228         beginCol := beginCol + 1.
       
  1229     ] ifFalse:[
       
  1230         "nope - maybe its a space"
       
  1231         thisCharacter == Character space ifTrue:[
       
  1232             [beginCol > 1 and:[thisCharacter == Character space]] whileTrue:[
       
  1233                 beginCol := beginCol - 1.
       
  1234                 thisCharacter := self characterAtLine:selectLine col:beginCol
       
  1235             ].
       
  1236             thisCharacter ~~ Character space ifTrue:[
       
  1237                 beginCol := beginCol + 1.
       
  1238             ].
       
  1239         ] ifFalse:[
       
  1240             "select single character"
       
  1241         ]
       
  1242     ].
       
  1243     ^ beginCol
       
  1244 !
       
  1245 
       
  1246 findEndOfWordAtLine:selectLine col:selectCol
       
  1247     "return the col of last character of the word at given line/col.
       
  1248      If the character under the initial col is a space character, return
       
  1249      the last col of the blank-block.
       
  1250      Return 0 if we should wrap to next line (for spaces)"
       
  1251 
       
  1252     |endCol thisCharacter len|
       
  1253 
       
  1254     endCol := selectCol.
       
  1255     endCol == 0 ifTrue:[endCol := 1].
       
  1256     thisCharacter := self characterAtLine:selectLine col:endCol.
       
  1257 
       
  1258     "is this acharacter within a word ?"
       
  1259     (wordCheck value:thisCharacter) ifTrue:[
       
  1260         thisCharacter := self characterAtLine:selectLine col:endCol.
       
  1261         [wordCheck value:thisCharacter] whileTrue:[
       
  1262             endCol := endCol + 1.
       
  1263             thisCharacter := self characterAtLine:selectLine col:endCol
       
  1264         ].
       
  1265         endCol := endCol - 1.
       
  1266     ] ifFalse:[
       
  1267         "nope - maybe its a space"
       
  1268         thisCharacter == Character space ifTrue:[
       
  1269             len := (self listAt:selectLine) size.
       
  1270             endCol > len ifTrue:[
       
  1271                 "select rest to end"
       
  1272                 endCol := 0
       
  1273             ] ifFalse:[
       
  1274                 thisCharacter := self characterAtLine:selectLine col:endCol.
       
  1275                 [endCol <= len and:[thisCharacter == Character space]] whileTrue:[
       
  1276                     endCol := endCol + 1.
       
  1277                     thisCharacter := self characterAtLine:selectLine col:endCol
       
  1278                 ].
       
  1279                 endCol := endCol - 1.
       
  1280             ]
       
  1281         ] ifFalse:[
       
  1282             "select single character"
       
  1283         ]
       
  1284     ].
       
  1285     ^ endCol.
  1118 ! !
  1286 ! !
  1119 
  1287 
  1120 !ListView methodsFor:'scrolling'!
  1288 !ListView methodsFor:'scrolling'!
  1121 
  1289 
  1122 gotoLine:aLineNumber
  1290 gotoLine:aLineNumber
  1127 !
  1295 !
  1128 
  1296 
  1129 pageDown
  1297 pageDown
  1130     "change origin to display next page"
  1298     "change origin to display next page"
  1131 
  1299 
       
  1300     |nLines|
       
  1301 
       
  1302     nLines := nFullLinesShown.
       
  1303     (firstLineShown + nLines + nFullLinesShown > list size) ifTrue:[
       
  1304         nLines := list size - firstLineShown - nFullLinesShown + 1
       
  1305     ].
       
  1306     nLines <= 0 ifTrue:[^ self].
       
  1307 
  1132     self originWillChange.
  1308     self originWillChange.
  1133     firstLineShown := firstLineShown + nFullLinesShown.
  1309     firstLineShown := firstLineShown + nLines.
  1134     self originChanged:nFullLinesShown.
  1310     self originChanged:nLines.
  1135     self redrawFromVisibleLine:1 to:nLinesShown
  1311     self redrawFromVisibleLine:1 to:nLinesShown
  1136 !
  1312 !
  1137 
  1313 
  1138 pageUp
  1314 pageUp
  1139     "change origin to display previous page"
  1315     "change origin to display previous page"
  1160 
  1336 
  1161 halfPageUp
  1337 halfPageUp
  1162     "scroll up half a page"
  1338     "scroll up half a page"
  1163 
  1339 
  1164     self scrollUp:(nFullLinesShown // 2)
  1340     self scrollUp:(nFullLinesShown // 2)
       
  1341 !
       
  1342 
       
  1343 makeLineVisible:aListLineNr
       
  1344     "if aListLineNr is not visible, scroll to make it visible.
       
  1345      Numbering starts with 1 for the very first line of the text."
       
  1346 
       
  1347     |bott|
       
  1348 
       
  1349     (aListLineNr isNil "or:[shown not]") ifTrue:[^ self].
       
  1350 
       
  1351     (aListLineNr >= firstLineShown) ifTrue:[
       
  1352         (aListLineNr < (firstLineShown + nFullLinesShown)) ifTrue:[
       
  1353             ^ self
       
  1354         ]
       
  1355     ].
       
  1356     (aListLineNr < nFullLinesShown) ifTrue:[
       
  1357         ^ self scrollToLine:1
       
  1358     ].
       
  1359     (nFullLinesShown < 3) ifTrue:[
       
  1360         ^ self scrollToLine:aListLineNr
       
  1361     ].
       
  1362     bott := self numberOfLines - (nFullLinesShown - 1).
       
  1363     (aListLineNr > bott) ifTrue:[
       
  1364         ^ self scrollToLine:bott
       
  1365     ].
       
  1366     self scrollToLine:(aListLineNr - (nFullLinesShown // 2) + 1)
       
  1367 !
       
  1368 
       
  1369 makeColVisible:aCol inLine:aLineNr
       
  1370     "if column aCol is not visible, scroll horizontal to make it visible"
       
  1371 
       
  1372     |xWant xVis visLnr oldLeft|
       
  1373 
       
  1374     (aCol isNil or:[shown not]) ifTrue:[^ self].
       
  1375 
       
  1376     visLnr := self absoluteLineToVisibleLine:aLineNr.
       
  1377     visLnr isNil ifTrue:[^ self].
       
  1378 
       
  1379     xWant := self xOfCol:aCol inLine:visLnr.
       
  1380     "
       
  1381      dont scroll, if already visible
       
  1382      (but scroll, if not in inner 20%..80% of visible area)
       
  1383     "
       
  1384     xVis := xWant - leftOffset.
       
  1385 
       
  1386     ((xVis >= (width // 5)) and:[xVis <= (width * 4 // 5)]) ifTrue:[
       
  1387         ^ self
       
  1388     ].
       
  1389 
       
  1390     oldLeft := leftOffset.
       
  1391     self scrollHorizontalTo:(xWant - (width // 2)).
       
  1392     self originChanged:((oldLeft - leftOffset) @ 0)
  1165 !
  1393 !
  1166 
  1394 
  1167 scrollDown:nLines
  1395 scrollDown:nLines
  1168     "change origin to scroll down some lines"
  1396     "change origin to scroll down some lines"
  1169 
  1397 
  1253     "change origin to start of text"
  1481     "change origin to start of text"
  1254 
  1482 
  1255     self scrollToLine:1
  1483     self scrollToLine:1
  1256 !
  1484 !
  1257 
  1485 
       
  1486 scrollToBottom
       
  1487     "change origin to show end of text"
       
  1488 
       
  1489     "scrolling to the end is not really correct (i.e. should scroll to list size - nFullLinesShown), 
       
  1490      but scrollDown: will adjust it ..."
       
  1491 
       
  1492     self scrollToLine:(list size)
       
  1493 !
       
  1494 
  1258 scrollToLine:aLineNr
  1495 scrollToLine:aLineNr
  1259     "change origin to make aLineNr be the top line"
  1496     "change origin to make aLineNr be the top line"
  1260 
  1497 
  1261     aLineNr < firstLineShown ifTrue:[
  1498     aLineNr < firstLineShown ifTrue:[
  1262         self scrollUp:(firstLineShown - aLineNr)
  1499         self scrollUp:(firstLineShown - aLineNr)
  1265             self scrollDown:(aLineNr - firstLineShown)
  1502             self scrollDown:(aLineNr - firstLineShown)
  1266         ]
  1503         ]
  1267     ]
  1504     ]
  1268 !
  1505 !
  1269 
  1506 
       
  1507 scrollToLeft
       
  1508     "change origin to start (left) of text"
       
  1509 
       
  1510     leftOffset ~~ 0 ifTrue:[
       
  1511         self scrollToCol:1
       
  1512     ]
       
  1513 !
       
  1514 
       
  1515 scrollToCol:aColNr
       
  1516     "change origin to make aColNr be the left col"
       
  1517 
       
  1518     |pxlOffset|
       
  1519 
       
  1520     aColNr == 1 ifTrue:[
       
  1521         leftOffset ~~ 0 ifTrue:[
       
  1522             self scrollLeft:leftOffset.
       
  1523         ].
       
  1524         ^ self
       
  1525     ].
       
  1526 
       
  1527     pxlOffset := font width * (aColNr - 1).
       
  1528 
       
  1529     pxlOffset < leftOffset ifTrue:[
       
  1530         self scrollLeft:(leftOffset - pxlOffset)
       
  1531     ] ifFalse:[
       
  1532         pxlOffset > leftOffset ifTrue:[
       
  1533             self scrollRight:(pxlOffset - leftOffset)
       
  1534         ]
       
  1535     ]
       
  1536 !
       
  1537 
  1270 scrollVerticalToPercent:percent
  1538 scrollVerticalToPercent:percent
  1271     "scroll to a position given in percent of total"
  1539     "scroll to a position given in percent of total"
  1272 
  1540 
  1273     |lineNr|
  1541     |lineNr|
  1274 
  1542 
  1275     lineNr := (((self numberOfLines * percent) asFloat / 100.0) + 0.5) asInteger + 1.
  1543     lineNr := (((self numberOfLines * percent) asFloat / 100.0) + 0.5) asInteger + 1.
  1276     self scrollToLine:lineNr
  1544     self scrollToLine:lineNr
  1277 !
       
  1278 
       
  1279 makeLineVisible:aListLineNr
       
  1280     "if aListLineNr is not visible, scroll to make it visible"
       
  1281 
       
  1282     |bott|
       
  1283 
       
  1284     (aListLineNr isNil or:[shown not]) ifTrue:[^ self].
       
  1285 
       
  1286     (aListLineNr >= firstLineShown) ifTrue:[
       
  1287         (aListLineNr < (firstLineShown + nFullLinesShown)) ifTrue:[
       
  1288             ^ self
       
  1289         ]
       
  1290     ].
       
  1291     (aListLineNr < nFullLinesShown) ifTrue:[
       
  1292         ^ self scrollToLine:1
       
  1293     ].
       
  1294     (nFullLinesShown < 3) ifTrue:[
       
  1295         ^ self scrollToLine:aListLineNr
       
  1296     ].
       
  1297     bott := self numberOfLines - (nFullLinesShown - 1).
       
  1298     (aListLineNr > bott) ifTrue:[
       
  1299         ^ self scrollToLine:bott
       
  1300     ].
       
  1301     self scrollToLine:(aListLineNr - (nFullLinesShown // 2) + 1)
       
  1302 !
  1545 !
  1303 
  1546 
  1304 scrollSelectUp
  1547 scrollSelectUp
  1305     "just a template - I do not know anything about selections"
  1548     "just a template - I do not know anything about selections"
  1306 
  1549 
  1324 
  1567 
  1325     (deltaT = autoScrollDeltaT) ifFalse:[
  1568     (deltaT = autoScrollDeltaT) ifFalse:[
  1326         autoScrollDeltaT := deltaT.
  1569         autoScrollDeltaT := deltaT.
  1327         autoScrollBlock isNil ifTrue:[
  1570         autoScrollBlock isNil ifTrue:[
  1328             autoScrollBlock := [self scrollSelectDown].
  1571             autoScrollBlock := [self scrollSelectDown].
  1329             Processor addTimedBlock:autoScrollBlock after:deltaT
  1572             Processor addTimedBlock:autoScrollBlock afterSeconds:deltaT
  1330         ]
  1573         ]
  1331     ]
  1574     ]
  1332 !
  1575 !
  1333 
  1576 
  1334 startScrollUp:yDistance
  1577 startScrollUp:yDistance
  1342 
  1585 
  1343     (deltaT = autoScrollDeltaT) ifFalse:[
  1586     (deltaT = autoScrollDeltaT) ifFalse:[
  1344         autoScrollDeltaT := deltaT.
  1587         autoScrollDeltaT := deltaT.
  1345         autoScrollBlock isNil ifTrue:[
  1588         autoScrollBlock isNil ifTrue:[
  1346             autoScrollBlock := [self scrollSelectUp].
  1589             autoScrollBlock := [self scrollSelectUp].
  1347             Processor addTimedBlock:autoScrollBlock after:deltaT
  1590             Processor addTimedBlock:autoScrollBlock afterSeconds:deltaT
  1348         ]
  1591         ]
  1349     ]
  1592     ]
  1350 !
  1593 !
  1351 
  1594 
  1352 stopAutoScroll
  1595 stopAutoScroll
  1356         self compressMotionEvents:true.
  1599         self compressMotionEvents:true.
  1357         Processor removeTimedBlock:autoScrollBlock.
  1600         Processor removeTimedBlock:autoScrollBlock.
  1358         autoScrollBlock := nil.
  1601         autoScrollBlock := nil.
  1359         autoScrollDeltaT := nil
  1602         autoScrollDeltaT := nil
  1360     ].
  1603     ].
       
  1604 !
       
  1605 
       
  1606 scrollRight
       
  1607     "scroll right by one character
       
  1608       - question is how much is a good for variable fonts"
       
  1609 
       
  1610     self scrollRight:font width
       
  1611 !
       
  1612 
       
  1613 scrollRight:nPixel
       
  1614     "change origin to scroll right some cols"
       
  1615 
       
  1616     |wMax cnt|
       
  1617 
       
  1618 
       
  1619     cnt := nPixel.
       
  1620 
       
  1621 "
       
  1622  commenting out the block below allows scrolling to the right of
       
  1623  the widest line
       
  1624 "
       
  1625 " "
       
  1626     "
       
  1627      the 10 below allows scrolling somewhat behind the end of the line
       
  1628     "
       
  1629     wMax := self widthOfContents + 10.
       
  1630     (leftOffset + nPixel + width > wMax) ifTrue:[
       
  1631         cnt := wMax - leftOffset - width
       
  1632     ].
       
  1633     cnt <= 0 ifTrue:[^ self].
       
  1634 " "
       
  1635     self originWillChange.
       
  1636     leftOffset:= leftOffset + cnt.
       
  1637     self redrawFromVisibleLine:1 to:nLinesShown.
       
  1638     self originChanged:(cnt @ 0)
       
  1639 !
       
  1640 
       
  1641 scrollLeft
       
  1642     "scroll left by one character
       
  1643       - question is how much is a good for variable fonts"
       
  1644 
       
  1645     self scrollLeft:font width
       
  1646 !
       
  1647 
       
  1648 scrollLeft:nPixel
       
  1649     "change origin to scroll left some cols"
       
  1650 
       
  1651     |newLeftOffset|
       
  1652 
       
  1653     nPixel <= 0 ifTrue:[^ self].
       
  1654 
       
  1655     newLeftOffset := leftOffset - nPixel.
       
  1656     newLeftOffset <= 0 ifTrue:[
       
  1657         leftOffset == 0 ifTrue:[^ self].
       
  1658         newLeftOffset := 0
       
  1659     ].
       
  1660 
       
  1661     self originWillChange.
       
  1662     leftOffset := newLeftOffset.
       
  1663     self redrawFromVisibleLine:1 to:nLinesShown.
       
  1664     self originChanged:(0 @ nPixel)
       
  1665 !
       
  1666 
       
  1667 scrollHorizontalTo:aPixelOffset
       
  1668     "change origin to make aPixelOffset be the left col"
       
  1669 
       
  1670     |orgX|
       
  1671 
       
  1672     orgX := leftOffset.
       
  1673 
       
  1674     (aPixelOffset < orgX) ifTrue:[
       
  1675         self scrollLeft:(orgX - aPixelOffset)
       
  1676     ] ifFalse:[
       
  1677         (aPixelOffset > orgX) ifTrue:[
       
  1678             self scrollRight:(aPixelOffset - orgX)
       
  1679         ]
       
  1680     ]
  1361 ! !
  1681 ! !
  1362 
  1682 
  1363 !ListView methodsFor:'drawing'!
  1683 !ListView methodsFor:'drawing'!
  1364 
  1684 
  1365 drawVisibleLine:visLineNr col:col with:fg and:bg
  1685 drawVisibleLine:visLineNr col:col with:fg and:bg
  1458     y := self yOfLine:startVisLineNr.
  1778     y := self yOfLine:startVisLineNr.
  1459     self paint:bg.
  1779     self paint:bg.
  1460     self fillRectangleX:margin y:y
  1780     self fillRectangleX:margin y:y
  1461                   width:(width - (margin * 2))
  1781                   width:(width - (margin * 2))
  1462                  height:(endVisLineNr - startVisLineNr + 1) * fontHeight.
  1782                  height:(endVisLineNr - startVisLineNr + 1) * fontHeight.
       
  1783     list isNil ifTrue:[^ self].
  1463 
  1784 
  1464     y := y + fontAscent.
  1785     y := y + fontAscent.
  1465     listSize := list size.
  1786     listSize := list size.
  1466 
  1787 
  1467     startLine := startVisLineNr + firstLineShown - 1.
  1788     startLine := startVisLineNr + firstLineShown - 1.
  1701             "start/end col has to be computed for each line"
  2022             "start/end col has to be computed for each line"
  1702 
  2023 
  1703             startLine to:stopLine do:[:i |
  2024             startLine to:stopLine do:[:i |
  1704                 startCol := self colOfX:x inVisibleLine:i.
  2025                 startCol := self colOfX:x inVisibleLine:i.
  1705                 endCol := self colOfX:(x + w) inVisibleLine:i.
  2026                 endCol := self colOfX:(x + w) inVisibleLine:i.
  1706                 self redrawVisibleLine:i from:startCol to:endCol
  2027                 startCol > 0 ifTrue:[
       
  2028                     endCol > 0 ifTrue:[
       
  2029                         self redrawVisibleLine:i from:startCol to:endCol
       
  2030                     ]
       
  2031                 ]
  1707             ]
  2032             ]
  1708         ] ifTrue:[
  2033         ] ifTrue:[
  1709             "start/end col is the same for all lines"
  2034             "start/end col is the same for all lines"
  1710 
  2035 
  1711             startCol := self colOfX:x inVisibleLine:startLine.
  2036             startCol := self colOfX:x inVisibleLine:startLine.
  1712             endCol := self colOfX:(x + w) inVisibleLine:startLine.
  2037             endCol := self colOfX:(x + w) inVisibleLine:startLine.
  1713             startLine to:stopLine do:[:i |
  2038             startCol > 0 ifTrue:[
  1714                   self redrawVisibleLine:i from:startCol to:endCol
  2039                 endCol > 0 ifTrue:[
       
  2040                     startLine to:stopLine do:[:i |
       
  2041                         self redrawVisibleLine:i from:startCol to:endCol
       
  2042                     ]
       
  2043                 ]
  1715             ]
  2044             ]
  1716         ]
  2045         ]
  1717     ]
  2046     ]
  1718 !
  2047 !
  1719 
  2048