ListModelView.st
changeset 3728 8858b3571313
parent 3723 e3c5f00861e1
child 3891 0cce5a3615ee
equal deleted inserted replaced
3727:03a3787770ed 3728:8858b3571313
    13 
    13 
    14 View subclass:#ListModelView
    14 View subclass:#ListModelView
    15 	instanceVariableNames:'list listHolder textStartLeft textStartTop viewOrigin enabled
    15 	instanceVariableNames:'list listHolder textStartLeft textStartTop viewOrigin enabled
    16 		fgColor bgColor lineSpacing widthOfContents computeWidthInRange
    16 		fgColor bgColor lineSpacing widthOfContents computeWidthInRange
    17 		startOfLinesY autoScroll autoScrollBlock scrollWhenUpdating
    17 		startOfLinesY autoScroll autoScrollBlock scrollWhenUpdating
    18 		hasConstantHeight constantHeight previousExtent renderer
    18 		hasConstantHeight constantHeight previousExtent listRenderer
    19 		cachedPreferredExtent'
    19 		cachedPreferredExtent'
    20 	classVariableNames:'DefaultForegroundColor DefaultBackgroundColor DefaultShadowColor
    20 	classVariableNames:'DefaultForegroundColor DefaultBackgroundColor DefaultShadowColor
    21 		DefaultLightColor StopRedrawSignal'
    21 		DefaultLightColor StopRedrawSignal'
    22 	poolDictionaries:''
    22 	poolDictionaries:''
    23 	category:'Views-Lists'
    23 	category:'Views-Lists'
    73     This class can only passively display collections of elements.
    73     This class can only passively display collections of elements.
    74     The class doesn't keep its own list, it works directly on
    74     The class doesn't keep its own list, it works directly on
    75     the list ( List or HierarchicalList ).
    75     the list ( List or HierarchicalList ).
    76 
    76 
    77     ATTENTION (warning by cg):
    77     ATTENTION (warning by cg):
    78         in contrast to its inappropriate name, this class COMPLETELY ignores the model
    78 	in contrast to its inappropriate name, this class COMPLETELY ignores the model
    79         instance variable - all is through the list/listHolder.
    79 	instance variable - all is through the list/listHolder.
    80 
    80 
    81     Each list item is obligated to provide 3 services:
    81     Each list item is obligated to provide 3 services:
    82         - heightOn:aGC
    82 	- heightOn:aGC
    83         - widthOn:aGC
    83 	- widthOn:aGC
    84         - displayOn:aGC x:x y:y
    84 	- displayOn:aGC x:x y:y
    85 
    85 
    86     [Instance variables:]
    86     [Instance variables:]
    87         list                   <List-Model>     List or HierarchicalList ...
    87 	list                   <List-Model>     List or HierarchicalList ...
    88         listHolder             <Model>          Model, which keeps a List
    88 	listHolder             <Model>          Model, which keeps a List
    89         textStartLeft          <Number>         left inset of text
    89 	textStartLeft          <Number>         left inset of text
    90         viewOrigin             <Point>          the current origin
    90 	viewOrigin             <Point>          the current origin
    91         enabled                <Boolean>        widget is enabled/disabeled
    91 	enabled                <Boolean>        widget is enabled/disabeled
    92         fgColor                <Color>          color to draw characters
    92 	fgColor                <Color>          color to draw characters
    93         bgColor                <Color>          the background
    93 	bgColor                <Color>          the background
    94         lineSpacing            <Number>         pixels between lines
    94 	lineSpacing            <Number>         pixels between lines
    95         widthOfContents        <Number>         cached width of widest line
    95 	widthOfContents        <Number>         cached width of widest line
    96         computeWidthInRange    <Point>          used for recompute width of contents
    96 	computeWidthInRange    <Point>          used for recompute width of contents
    97         startOfLinesY          <Collection>     keeps all the absolute Y-start positions
    97 	startOfLinesY          <Collection>     keeps all the absolute Y-start positions
    98                                                 for each line in the list. The first
    98 						for each line in the list. The first
    99                                                 entry into the list is the top Y inset.
    99 						entry into the list is the top Y inset.
   100         supportsDisplayInRange <Boolean>        set to true if the list elements
   100 	supportsDisplayInRange <Boolean>        set to true if the list elements
   101                                                 supports the service:
   101 						supports the service:
   102                                                     #displayOn:x:y:h:
   102 						    #displayOn:x:y:h:
   103 
   103 
   104         hasConstantHeight      <Boolean>        true, than each line has the same height
   104 	hasConstantHeight      <Boolean>        true, than each line has the same height
   105 
   105 
   106         constantHeight         <SmallInteger>   hasConstantHeight is turned on, this
   106 	constantHeight         <SmallInteger>   hasConstantHeight is turned on, this
   107                                                 is the used line height
   107 						is the used line height
   108 
   108 
   109     [author:]
   109     [author:]
   110         Claus Atzkern
   110 	Claus Atzkern
   111 
   111 
   112     [see also:]
   112     [see also:]
   113 
   113 
   114         SelectionInListModelView
   114 	SelectionInListModelView
   115         HierarchicalListView
   115 	HierarchicalListView
   116         List
   116 	List
   117         HierarchicalList
   117 	HierarchicalList
   118 "
   118 "
   119 !
   119 !
   120 
   120 
   121 examples
   121 examples
   122 "
   122 "
   207 list:aList
   207 list:aList
   208     "set the list of items
   208     "set the list of items
   209     "
   209     "
   210     |negatedOrg|
   210     |negatedOrg|
   211 
   211 
   212     renderer listWillChange.
   212     listRenderer listWillChange.
   213 
   213 
   214     list ~~ aList ifTrue:[
   214     list ~~ aList ifTrue:[
   215         list removeDependent:self.
   215 	list removeDependent:self.
   216         list := aList.
   216 	list := aList.
   217         list isNil ifTrue:[list := self newDefaultList ].
   217 	list isNil ifTrue:[list := self newDefaultList ].
   218         list addDependent:self
   218 	list addDependent:self
   219     ].
   219     ].
   220 "/    preferredExtent := nil.
   220 "/    preferredExtent := nil.
   221     cachedPreferredExtent := nil.
   221     cachedPreferredExtent := nil.
   222     widthOfContents := nil.
   222     widthOfContents := nil.
   223 
   223 
   224     realized ifTrue:[
   224     realized ifTrue:[
   225         self recomputeHeightOfContents.
   225 	self recomputeHeightOfContents.
   226         scrollWhenUpdating == #beginOfText ifTrue:[
   226 	scrollWhenUpdating == #beginOfText ifTrue:[
   227             viewOrigin = (0@0) ifFalse:[
   227 	    viewOrigin = (0@0) ifFalse:[
   228                 self originWillChange.
   228 		self originWillChange.
   229                 negatedOrg := viewOrigin negated.
   229 		negatedOrg := viewOrigin negated.
   230                 viewOrigin := (0@0).
   230 		viewOrigin := (0@0).
   231                 self originChanged:negatedOrg.
   231 		self originChanged:negatedOrg.
   232             ].
   232 	    ].
   233         ] ifFalse:[
   233 	] ifFalse:[
   234             scrollWhenUpdating == #endOfText ifTrue:[
   234 	    scrollWhenUpdating == #endOfText ifTrue:[
   235                 self scrollTo:(0 @ self heightOfContents - self innerHeight) redraw:false
   235 		self scrollTo:(0 @ self heightOfContents - self innerHeight) redraw:false
   236             ]
   236 	    ]
   237         ].
   237 	].
   238         self invalidate.
   238 	self invalidate.
   239     ].
   239     ].
   240     self contentsChanged
   240     self contentsChanged
   241 !
   241 !
   242 
   242 
       
   243 listRenderer
       
   244     "returns the used listrenderer
       
   245     "
       
   246     ^ listRenderer
       
   247 !
       
   248 
   243 renderer
   249 renderer
   244     "returns the used renderer
   250     self obsoleteMethodWarning:'naming conflict renderer vs. listRenderer'.
   245     "
   251     ^ self listRenderer
   246     ^ renderer
   252 !
   247 !
   253 
   248 
   254 listRenderer:aRendererOrRendererClass
   249 renderer:aRenderer
   255     "change the used listRenderer
   250     "change the used renderer
   256     "
   251     "
   257     aRendererOrRendererClass isNil ifTrue:[^ self].
   252     aRenderer isNil ifTrue:[^ self].
   258 
   253 
   259     listRenderer == aRendererOrRendererClass ifTrue:[^ self].
   254     renderer == aRenderer ifTrue:[^ self].
   260     listRenderer notNil ifTrue:[listRenderer release].
   255     renderer notNil ifTrue:[renderer release].
   261 
   256 
   262     aRendererOrRendererClass isBehavior ifTrue:[
   257     renderer := aRenderer.
   263 	listRenderer := aRendererOrRendererClass basicNew initialize.
   258     renderer isBehavior ifTrue:[
   264     ] ifFalse:[
   259         renderer := renderer basicNew initialize.
   265 	listRenderer := aRendererOrRendererClass.
   260     ].
   266     ].
   261     renderer forView:self.
   267     listRenderer forView:self.
       
   268 !
       
   269 
       
   270 renderer:aTableRenderer
       
   271     self obsoleteMethodWarning:'naming conflict renderer vs. listRenderer'.
       
   272     self listRenderer:aTableRenderer
   262 !
   273 !
   263 
   274 
   264 setupTableRenderer
   275 setupTableRenderer
   265     "under test - creates a renderer with columns based on a DataSetColumnSpec
   276     "creates a renderer with columns based on a DataSetColumnSpec
   266      answer the new renderer"
   277      answer the new renderer"
   267 
   278 
   268     self renderer:TableRenderer.
   279     self listRenderer:TableRenderer.
   269     ^ renderer
   280     ^ listRenderer
   270 ! !
   281 ! !
   271 
   282 
   272 !ListModelView methodsFor:'accessing-behavior'!
   283 !ListModelView methodsFor:'accessing-behavior'!
   273 
   284 
   274 autoScroll
   285 autoScroll
   311     "user configured; true if each line has the same lineHeight.
   322     "user configured; true if each line has the same lineHeight.
   312      Optimizes scrolling and redraw.
   323      Optimizes scrolling and redraw.
   313     "
   324     "
   314 
   325 
   315     aBool == hasConstantHeight ifTrue:[
   326     aBool == hasConstantHeight ifTrue:[
   316         ^ self
   327 	^ self
   317     ].
   328     ].
   318     constantHeight    := nil.
   329     constantHeight    := nil.
   319     hasConstantHeight := aBool.
   330     hasConstantHeight := aBool.
   320 
   331 
   321     self lostSynchronisation.
   332     self lostSynchronisation.
   322 !
   333 !
   323 
   334 
   324 scrollWhenUpdating:aSymbolOrNil
   335 scrollWhenUpdating:aSymbolOrNil
   325     "define how to scroll, when I get a new text 
   336     "define how to scroll, when I get a new text
   326      (via the model or the #contents/#list)
   337      (via the model or the #contents/#list)
   327      Allowed arguments are:
   338      Allowed arguments are:
   328 	#keep / nil     -> no change
   339 	#keep / nil     -> no change
   329 	#endOfText      -> scroll to the end
   340 	#endOfText      -> scroll to the end
   330 	#beginOfText    -> scroll to the top
   341 	#beginOfText    -> scroll to the top
   345     "
   356     "
   346     ^ list at:anIndex
   357     ^ list at:anIndex
   347 !
   358 !
   348 
   359 
   349 at:anIndex ifAbsent:exceptionBlock
   360 at:anIndex ifAbsent:exceptionBlock
   350     "return the list element at an index if valid. 
   361     "return the list element at an index if valid.
   351      If the index is invalid, return the result of evaluating 
   362      If the index is invalid, return the result of evaluating
   352      the exceptionblock.
   363      the exceptionblock.
   353     "
   364     "
   354     ^ list at:anIndex ifAbsent:exceptionBlock
   365     ^ list at:anIndex ifAbsent:exceptionBlock
   355 !
   366 !
   356 
   367 
   387     "set a new font
   398     "set a new font
   388     "
   399     "
   389     |oldWidth oldHeight|
   400     |oldWidth oldHeight|
   390 
   401 
   391     (aFont isNil or:[aFont = font]) ifFalse:[
   402     (aFont isNil or:[aFont = font]) ifFalse:[
   392         oldWidth  := font width.
   403 	oldWidth  := font width.
   393         oldHeight := font height.
   404 	oldHeight := font height.
   394 
   405 
   395         super font:aFont.
   406 	super font:aFont.
   396 
   407 
   397         (font widthOn:device) ~~ oldWidth ifTrue:[       "/ force a recomputation
   408 	(font widthOn:device) ~~ oldWidth ifTrue:[       "/ force a recomputation
   398 "/            preferredExtent := nil.
   409 "/            preferredExtent := nil.
   399             cachedPreferredExtent := nil.
   410 	    cachedPreferredExtent := nil.
   400             widthOfContents := nil.
   411 	    widthOfContents := nil.
   401         ].
   412 	].
   402         realized ifTrue:[
   413 	realized ifTrue:[
   403             oldHeight ~~ (font heightOn:device) ifTrue:[
   414 	    oldHeight ~~ (font heightOn:device) ifTrue:[
   404                 self recomputeHeightOfContents.
   415 		self recomputeHeightOfContents.
   405                 self contentsChanged.
   416 		self contentsChanged.
   406             ].
   417 	    ].
   407             self invalidate
   418 	    self invalidate
   408         ].
   419 	].
   409     ].
   420     ].
   410 !
   421 !
   411 
   422 
   412 foregroundColor
   423 foregroundColor
   413     "get the foreground color
   424     "get the foreground color
   439 lineSpacing:aNumber
   450 lineSpacing:aNumber
   440     "set the lineSpacing - thats an additional number of pixels,
   451     "set the lineSpacing - thats an additional number of pixels,
   441      by which lines are vertically separated.
   452      by which lines are vertically separated.
   442     "
   453     "
   443     lineSpacing ~= aNumber ifTrue:[
   454     lineSpacing ~= aNumber ifTrue:[
   444         lineSpacing := aNumber.
   455 	lineSpacing := aNumber.
   445 
   456 
   446         realized ifTrue:[
   457 	realized ifTrue:[
   447             self recomputeHeightOfContents.
   458 	    self recomputeHeightOfContents.
   448             self invalidate
   459 	    self invalidate
   449         ].
   460 	].
   450         self contentsChanged.
   461 	self contentsChanged.
   451     ]
   462     ]
   452 !
   463 !
   453 
   464 
   454 viewBackground:aColor
   465 viewBackground:aColor
   455     "set the background color
   466     "set the background color
   456     "
   467     "
   457     (aColor notNil and:[bgColor ~~ aColor]) ifTrue:[
   468     (aColor notNil and:[bgColor ~~ aColor]) ifTrue:[
   458         bgColor := aColor.
   469 	bgColor := aColor.
   459         super viewBackground:bgColor.
   470 	super viewBackground:bgColor.
   460 
   471 
   461         self realized ifTrue:[
   472 	self realized ifTrue:[
   462             bgColor := bgColor onDevice:device.
   473 	    bgColor := bgColor onDevice:device.
   463             self invalidate
   474 	    self invalidate
   464         ].
   475 	].
   465     ].
   476     ].
   466 ! !
   477 ! !
   467 
   478 
   468 !ListModelView methodsFor:'accessing-mvc'!
   479 !ListModelView methodsFor:'accessing-mvc'!
   469 
   480 
   492     |cache
   503     |cache
   493      oldHeight "{ Class:SmallInteger }"
   504      oldHeight "{ Class:SmallInteger }"
   494      deltaHeight "{ Class:SmallInteger }" |
   505      deltaHeight "{ Class:SmallInteger }" |
   495 
   506 
   496     (arg == #icon or:[arg == #hierarchy]) ifTrue:[
   507     (arg == #icon or:[arg == #hierarchy]) ifTrue:[
   497         ^ self
   508 	^ self
   498     ].
   509     ].
   499     hasConstantHeight ifTrue:[
   510     hasConstantHeight ifTrue:[
   500         self invalidateLineAt:aLnNr.
   511 	self invalidateLineAt:aLnNr.
   501         ^ self
   512 	^ self
   502     ].
   513     ].
   503 
   514 
   504     oldHeight := (self yVisibleOfLine:(aLnNr + 1)) - (self yVisibleOfLine:aLnNr).
   515     oldHeight := (self yVisibleOfLine:(aLnNr + 1)) - (self yVisibleOfLine:aLnNr).
   505     deltaHeight := (self heightOfLineAt:aLnNr) - oldHeight.
   516     deltaHeight := (self heightOfLineAt:aLnNr) - oldHeight.
   506 
   517 
   507     deltaHeight == 0 ifTrue:[
   518     deltaHeight == 0 ifTrue:[
   508         self invalidateLineAt:aLnNr.
   519 	self invalidateLineAt:aLnNr.
   509         ^ self
   520 	^ self
   510     ].
   521     ].
   511     cache := self startOfLinesY.
   522     cache := self startOfLinesY.
   512 
   523 
   513     aLnNr + 1 to:cache size do:[:i|
   524     aLnNr + 1 to:cache size do:[:i|
   514         cache at:i put:((cache at:i) + deltaHeight)
   525 	cache at:i put:((cache at:i) + deltaHeight)
   515     ].              
   526     ].
   516     self contentsChanged.
   527     self contentsChanged.
   517     self invalidate.
   528     self invalidate.
   518 !
   529 !
   519 
   530 
   520 listChangedInsert:start nItems:nLines
   531 listChangedInsert:start nItems:nLines
   538     shown ifFalse:[^ self].
   549     shown ifFalse:[^ self].
   539 
   550 
   540     newSz := startOfLinesY size + nLines.
   551     newSz := startOfLinesY size + nLines.
   541 
   552 
   542     (newSz - 1) ~~ self size ifTrue:[
   553     (newSz - 1) ~~ self size ifTrue:[
   543         "/
   554 	"/
   544         "/ no longer synchronized
   555 	"/ no longer synchronized
   545         "/
   556 	"/
   546         self lostSynchronisation.
   557 	self lostSynchronisation.
   547         ^ self
   558 	^ self
   548     ].
   559     ].
   549     newLines := startOfLinesY. "/ copy.
   560     newLines := startOfLinesY. "/ copy.
   550     newLines addAll:(Array new:nLines) beforeIndex:start + 1.
   561     newLines addAll:(Array new:nLines) beforeIndex:start + 1.
   551     absY0 := newLines at:start.
   562     absY0 := newLines at:start.
   552     absY1 := absY0.
   563     absY1 := absY0.
   553     run   := start.
   564     run   := start.
   554 
   565 
   555     nLines timesRepeat:[
   566     nLines timesRepeat:[
   556         absY1 := absY1 + (self heightOfLineAt:run).
   567 	absY1 := absY1 + (self heightOfLineAt:run).
   557         run   := run + 1.
   568 	run   := run + 1.
   558         newLines at:run put:absY1.
   569 	newLines at:run put:absY1.
   559     ].
   570     ].
   560     dltY := absY1 - absY0.
   571     dltY := absY1 - absY0.
   561 
   572 
   562     run + 1 to:newSz do:[:i||v|
   573     run + 1 to:newSz do:[:i||v|
   563         newLines at:i put:((newLines at:i) + dltY)
   574 	newLines at:i put:((newLines at:i) + dltY)
   564     ].
   575     ].
   565     startOfLinesY := newLines.
   576     startOfLinesY := newLines.
   566 
   577 
   567     orgY  := viewOrigin y.
   578     orgY  := viewOrigin y.
   568     absY1 := absY0 + dltY.
   579     absY1 := absY0 + dltY.
   569     visY0 := absY0 - orgY.
   580     visY0 := absY0 - orgY.
   570     visY1 := absY1 - orgY.
   581     visY1 := absY1 - orgY.
   571     maxHg := height - margin.
   582     maxHg := height - margin.
   572 
   583 
   573     absY0 < orgY ifTrue:[
   584     absY0 < orgY ifTrue:[
   574         self originWillChange.
   585 	self originWillChange.
   575         viewOrigin y:(dltY + orgY).
   586 	viewOrigin y:(dltY + orgY).
   576         self originChanged:(0 @ dltY).
   587 	self originChanged:(0 @ dltY).
   577     ].
   588     ].
   578 
   589 
   579     (visY0 >= maxHg or:[visY1 <= margin]) ifTrue:[
   590     (visY0 >= maxHg or:[visY1 <= margin]) ifTrue:[
   580         self contentsChanged.
   591 	self contentsChanged.
   581         ^ self
   592 	^ self
   582     ].
   593     ].
   583     visY0 := visY0 max:margin.
   594     visY0 := visY0 max:margin.
   584     visY1 := visY1 min:maxHg.
   595     visY1 := visY1 min:maxHg.
   585 
   596 
   586     self hasDamage ifTrue:[
   597     self hasDamage ifTrue:[
   587         self invalidate:(Rectangle left:0
   598 	self invalidate:(Rectangle left:0
   588                                     top:visY0 
   599 				    top:visY0
   589                                   width:width 
   600 				  width:width
   590                                  height:height - visY0).
   601 				 height:height - visY0).
   591 
   602 
   592         self contentsChanged.
   603 	self contentsChanged.
   593         ^ self
   604 	^ self
   594     ].
   605     ].
   595 
   606 
   596     (start == self size or:[(cpyHg := maxHg - visY1) < 20]) ifTrue:[
   607     (start == self size or:[(cpyHg := maxHg - visY1) < 20]) ifTrue:[
   597         visY1 := maxHg
   608 	visY1 := maxHg
   598     ] ifFalse:[
   609     ] ifFalse:[
   599         self catchExpose.
   610 	self catchExpose.
   600 
   611 
   601         self copyFrom:self x:0 y:visY0
   612 	self copyFrom:self x:0 y:visY0
   602                          toX:0 y:visY1
   613 			 toX:0 y:visY1
   603                        width:width height:cpyHg async:true.
   614 		       width:width height:cpyHg async:true.
   604 
   615 
   605         self waitForExpose
   616 	self waitForExpose
   606     ].
   617     ].
   607 
   618 
   608     self invalidateX:margin
   619     self invalidateX:margin
   609                    y:visY0
   620 		   y:visY0
   610                width:width - margin - margin
   621 	       width:width - margin - margin
   611               height:(visY1 - visY0).
   622 	      height:(visY1 - visY0).
   612 
   623 
   613     self contentsChanged.
   624     self contentsChanged.
   614 !
   625 !
   615 
   626 
   616 listChangedRemove:aStart toIndex:aStop
   627 listChangedRemove:aStart toIndex:aStop
   633     |
   644     |
   634     stop  := aStop.
   645     stop  := aStop.
   635     start := aStart.
   646     start := aStart.
   636 
   647 
   637     (size := stop - start + 1) == 0 ifTrue:[
   648     (size := stop - start + 1) == 0 ifTrue:[
   638         ^ self
   649 	^ self
   639     ].
   650     ].
   640 
   651 
   641     self listSizeChanged:start nLines:(size negated).
   652     self listSizeChanged:start nLines:(size negated).
   642     shown ifFalse:[^ self].
   653     shown ifFalse:[^ self].
   643 
   654 
   644     newSz := startOfLinesY size - size.
   655     newSz := startOfLinesY size - size.
   645 
   656 
   646     (newSz - 1) ~~ self size ifTrue:[
   657     (newSz - 1) ~~ self size ifTrue:[
   647         "/
   658 	"/
   648         "/ no longer synchrounous
   659 	"/ no longer synchrounous
   649         "/
   660 	"/
   650         ^ self lostSynchronisation
   661 	^ self lostSynchronisation
   651     ].
   662     ].
   652 
   663 
   653     absY0 := self yAbsoluteOfLine:start.
   664     absY0 := self yAbsoluteOfLine:start.
   654     absY1 := self yAbsoluteOfLine:stop + 1.
   665     absY1 := self yAbsoluteOfLine:stop + 1.
   655     dltY  := absY1 - absY0.
   666     dltY  := absY1 - absY0.
   656 
   667 
   657     newLines := startOfLinesY. "/ copy.
   668     newLines := startOfLinesY. "/ copy.
   658     newLines removeFromIndex:(start + 1) toIndex:(stop + 1).
   669     newLines removeFromIndex:(start + 1) toIndex:(stop + 1).
   659 
   670 
   660     (start + 1) to:newSz do:[:i|
   671     (start + 1) to:newSz do:[:i|
   661         absY0 := newLines at:i.
   672 	absY0 := newLines at:i.
   662         newLines at:i put:(absY0 - dltY).
   673 	newLines at:i put:(absY0 - dltY).
   663     ].
   674     ].
   664     startOfLinesY := newLines.
   675     startOfLinesY := newLines.
   665 
   676 
   666     orgY  := viewOrigin y.
   677     orgY  := viewOrigin y.
   667     orgX  := viewOrigin x.
   678     orgX  := viewOrigin x.
   671     visY0 := absY0 - orgY.
   682     visY0 := absY0 - orgY.
   672     visY1 := absY1 - orgY.
   683     visY1 := absY1 - orgY.
   673     maxHg := height - margin.
   684     maxHg := height - margin.
   674 
   685 
   675     (self size == 0 or:[(orgY ~~ 0 and:[self maxViewOriginY == 0])]) ifTrue:[
   686     (self size == 0 or:[(orgY ~~ 0 and:[self maxViewOriginY == 0])]) ifTrue:[
   676         (orgX ~~ 0 or:[orgY ~~ 0]) ifTrue:[
   687 	(orgX ~~ 0 or:[orgY ~~ 0]) ifTrue:[
   677             self originWillChange.
   688 	    self originWillChange.
   678             viewOrigin := 0@0.
   689 	    viewOrigin := 0@0.
   679             self originChanged:((orgX @ orgY) negated).
   690 	    self originChanged:((orgX @ orgY) negated).
   680         ].
   691 	].
   681         self invalidate.
   692 	self invalidate.
   682         ^ self contentsChanged    
   693 	^ self contentsChanged
   683     ].
   694     ].
   684 
   695 
   685     visY0 < margin ifTrue:[
   696     visY0 < margin ifTrue:[
   686         noRedraw := visY1 <= margin.
   697 	noRedraw := visY1 <= margin.
   687         noRedraw ifTrue:[dltY := dltY negated] ifFalse:[dltY := visY0].
   698 	noRedraw ifTrue:[dltY := dltY negated] ifFalse:[dltY := visY0].
   688 
   699 
   689         self originWillChange.
   700 	self originWillChange.
   690         viewOrigin y:(dltY + orgY).
   701 	viewOrigin y:(dltY + orgY).
   691         self originChanged:(0 @ dltY).        
   702 	self originChanged:(0 @ dltY).
   692     ] ifFalse:[
   703     ] ifFalse:[
   693         noRedraw := visY0 >= maxHg
   704 	noRedraw := visY0 >= maxHg
   694     ].
   705     ].
   695     visY0 := visY0 max:margin.
   706     visY0 := visY0 max:margin.
   696 
   707 
   697     self hasDamage ifTrue:[
   708     self hasDamage ifTrue:[
   698         self invalidate:(Rectangle left:0
   709 	self invalidate:(Rectangle left:0
   699                                     top:visY0 
   710 				    top:visY0
   700                                   width:width 
   711 				  width:width
   701                                  height:height - visY0).
   712 				 height:height - visY0).
   702 
   713 
   703         noRedraw := true
   714 	noRedraw := true
   704     ].
   715     ].
   705 
   716 
   706     noRedraw ifFalse:[
   717     noRedraw ifFalse:[
   707         cpyHg := maxHg - visY1.
   718 	cpyHg := maxHg - visY1.
   708 
   719 
   709         cpyHg > 20 ifTrue:[
   720 	cpyHg > 20 ifTrue:[
   710             self catchExpose.
   721 	    self catchExpose.
   711             self copyFrom:self x:0 y:visY1 toX:0 y:visY0
   722 	    self copyFrom:self x:0 y:visY1 toX:0 y:visY0
   712                     width:width height:cpyHg async:true.
   723 		    width:width height:cpyHg async:true.
   713             self waitForExpose.
   724 	    self waitForExpose.
   714             visY0 := visY0 + cpyHg.
   725 	    visY0 := visY0 + cpyHg.
   715         ].
   726 	].
   716 
   727 
   717         self invalidateX:margin
   728 	self invalidateX:margin
   718                        y:visY0
   729 		       y:visY0
   719                    width:width - margin - margin
   730 		   width:width - margin - margin
   720                   height:(maxHg - visY0).
   731 		  height:(maxHg - visY0).
   721     ].
   732     ].
   722     self contentsChanged.
   733     self contentsChanged.
   723 !
   734 !
   724 
   735 
   725 update:what with:aPara from:chgObj
   736 update:what with:aPara from:chgObj
   726     "catch and handle any notification raised from the list model
   737     "catch and handle any notification raised from the list model
   727      or list holder"
   738      or list holder"
   728 
   739 
   729     chgObj == self listHolder ifTrue:[
   740     chgObj == self listHolder ifTrue:[
   730         self list:chgObj value.
   741 	self list:chgObj value.
   731         ^ self.
   742 	^ self.
   732     ].
   743     ].
   733 
   744 
   734     chgObj == self list ifTrue:[
   745     chgObj == self list ifTrue:[
   735         renderer withinUpdateFromListDo:[
   746 	listRenderer withinUpdateFromListDo:[
   736             self updateFromList:what with:aPara.
   747 	    self updateFromList:what with:aPara.
   737         ].
   748 	].
   738         ^ self.
   749 	^ self.
   739     ].
   750     ].
   740 
   751 
   741     super update:what with:aPara from:chgObj
   752     super update:what with:aPara from:chgObj
   742 !
   753 !
   743 
   754 
   745     "called if the list changed"
   756     "called if the list changed"
   746 
   757 
   747     |arg1 arg2|
   758     |arg1 arg2|
   748 
   759 
   749     aParameter isCollection ifFalse:[
   760     aParameter isCollection ifFalse:[
   750         what == #at:     ifTrue:[self lineChangedAt:aParameter        with:nil.   ^ self].
   761 	what == #at:     ifTrue:[self lineChangedAt:aParameter        with:nil.   ^ self].
   751         what == #insert: ifTrue:[self listChangedInsert:aParameter  nItems:1.     ^ self].
   762 	what == #insert: ifTrue:[self listChangedInsert:aParameter  nItems:1.     ^ self].
   752         what == #remove: ifTrue:[self listChangedRemove:aParameter toIndex:aParameter. ^ self].
   763 	what == #remove: ifTrue:[self listChangedRemove:aParameter toIndex:aParameter. ^ self].
   753 
   764 
   754         self list:(self list).  "/ reload list
   765 	self list:(self list).  "/ reload list
   755         ^ self.
   766 	^ self.
   756     ].
   767     ].
   757 
   768 
   758     arg1 := aParameter at:1.
   769     arg1 := aParameter at:1.
   759     arg2 := aParameter at:2.
   770     arg2 := aParameter at:2.
   760 
   771 
   761     (arg1 == 1 and:[arg2 == self size]) ifTrue:[
   772     (arg1 == 1 and:[arg2 == self size]) ifTrue:[
   762         self list:(self list).  "/ reload list
   773 	self list:(self list).  "/ reload list
   763         ^ self
   774 	^ self
   764     ].
   775     ].
   765 
   776 
   766     what == #at:               ifTrue:[self lineChangedAt:arg1        with:arg2. ^ self].
   777     what == #at:               ifTrue:[self lineChangedAt:arg1        with:arg2. ^ self].
   767     what == #insertCollection: ifTrue:[self listChangedInsert:arg1  nItems:arg2. ^ self].
   778     what == #insertCollection: ifTrue:[self listChangedInsert:arg1  nItems:arg2. ^ self].
   768     what == #removeFrom:       ifTrue:[self listChangedRemove:arg1 toIndex:arg2. ^ self].
   779     what == #removeFrom:       ifTrue:[self listChangedRemove:arg1 toIndex:arg2. ^ self].
   769 
   780 
   770     what == #replace: ifTrue:[
   781     what == #replace: ifTrue:[
   771         arg1 to:arg2 do:[:i|self lineChangedAt:i with:nil].
   782 	arg1 to:arg2 do:[:i|self lineChangedAt:i with:nil].
   772         ^ self
   783 	^ self
   773     ].
   784     ].
   774     self halt:'oops - general change'.
   785     self halt:'oops - general change'.
   775     self list:(self list).  "/ reload list
   786     self list:(self list).  "/ reload list
   776 ! !
   787 ! !
   777 
   788 
   790 
   801 
   791     x0 := textStartLeft - viewOrigin x.
   802     x0 := textStartLeft - viewOrigin x.
   792     y1 := y.
   803     y1 := y.
   793 
   804 
   794     start to:stop do:[:i|
   805     start to:stop do:[:i|
   795         item := self at:i ifAbsent:self.        "/ list changed during draw
   806 	item := self at:i ifAbsent:self.        "/ list changed during draw
   796         item == self ifTrue:[^ self].
   807 	item == self ifTrue:[^ self].
   797 
   808 
   798         y0 := y1.
   809 	y0 := y1.
   799         y1 := self yVisibleOfLine:(i + 1).
   810 	y1 := self yVisibleOfLine:(i + 1).
   800 
   811 
   801         item notNil ifTrue:[
   812 	item notNil ifTrue:[
   802             renderer display:item atX:x0 y:y0 lineHeight:(y1 - y0).
   813 	    listRenderer display:item atX:x0 y:y0 lineHeight:(y1 - y0).
   803         ]
   814 	]
   804     ]
   815     ]
   805 !
   816 !
   806 
   817 
   807 drawFrom:start to:stop x:xLft y:yTop w:aWidth
   818 drawFrom:start to:stop x:xLft y:yTop w:aWidth
   808     "draw lines from start to stop. Test whether a new clip
   819     "draw lines from start to stop. Test whether a new clip
   809      must be setup.
   820      must be setup.
   810     "
   821     "
   811     |maxX w|
   822     |maxX w|
   812 
   823 
   813     maxX := renderer maxItemWidthOrNil.
   824     maxX := listRenderer maxItemWidthOrNil.
   814     w := aWidth.
   825     w := aWidth.
   815 
   826 
   816     maxX notNil ifTrue:[ |clip|
   827     maxX notNil ifTrue:[ |clip|
   817         maxX := maxX - viewOrigin x.
   828 	maxX := maxX - viewOrigin x.
   818         maxX > xLft ifFalse:[^ self.].
   829 	maxX > xLft ifFalse:[^ self.].
   819 
   830 
   820         w := maxX - xLft min:aWidth.
   831 	w := maxX - xLft min:aWidth.
   821 
   832 
   822         (clip := self clipRect copy) notNil ifTrue:[
   833 	(clip := self clipRect copy) notNil ifTrue:[
   823             clip width:w
   834 	    clip width:w
   824         ] ifFalse:[
   835 	] ifFalse:[
   825             clip := Rectangle left:xLft top:yTop width:w height:(height - yTop - margin).
   836 	    clip := Rectangle left:xLft top:yTop width:w height:(height - yTop - margin).
   826         ].
   837 	].
   827         self clippingRectangle:clip.
   838 	self clippingRectangle:clip.
   828     ].
   839     ].
   829     self drawElementsFrom:start to:stop x:xLft y:yTop w:w.
   840     self drawElementsFrom:start to:stop x:xLft y:yTop w:w.
   830 !
   841 !
   831 
   842 
   832 invalidateLineAt:aLineNr
   843 invalidateLineAt:aLineNr
   846      x0 "{ Class:SmallInteger }"
   857      x0 "{ Class:SmallInteger }"
   847      xR "{ Class:SmallInteger }"
   858      xR "{ Class:SmallInteger }"
   848     |
   859     |
   849 
   860 
   850     (shown and:[aLineNr notNil and:[aLineNr > 0]]) ifFalse:[
   861     (shown and:[aLineNr notNil and:[aLineNr > 0]]) ifFalse:[
   851         ^ self
   862 	^ self
   852     ].
   863     ].
   853 
   864 
   854     xR := width - margin.
   865     xR := width - margin.
   855     x0 := x max:margin.
   866     x0 := x max:margin.
   856     x0 < xR ifFalse:[ ^ self].
   867     x0 < xR ifFalse:[ ^ self].
   857 
   868 
   858     yB := height - margin.
   869     yB := height - margin.
   859     y0 := (self yVisibleOfLine:aLineNr) max:margin.
   870     y0 := (self yVisibleOfLine:aLineNr) max:margin.
   860 
   871 
   861     y0 < yB ifTrue:[
   872     y0 < yB ifTrue:[
   862         y1 := (self yVisibleOfLine:(aLineNr + 1)) min:yB.
   873 	y1 := (self yVisibleOfLine:(aLineNr + 1)) min:yB.
   863 
   874 
   864         y1 > y0 ifTrue:[
   875 	y1 > y0 ifTrue:[
   865             self invalidateX:x0 y:y0 width:(xR - x0) height:(y1 - y0) repairNow:false.
   876 	    self invalidateX:x0 y:y0 width:(xR - x0) height:(y1 - y0) repairNow:false.
   866         ]
   877 	]
   867     ].
   878     ].
   868 !
   879 !
   869 
   880 
   870 redraw
   881 redraw
   871     "redraw complete view
   882     "redraw complete view
   874 
   885 
   875 
   886 
   876 !
   887 !
   877 
   888 
   878 redrawX:x y:y width:w height:h
   889 redrawX:x y:y width:w height:h
   879     "redraw part of myself immediately, given logical coordinates 
   890     "redraw part of myself immediately, given logical coordinates
   880     "
   891     "
   881     |start stop yAbs yStart|
   892     |start stop yAbs yStart|
   882 
   893 
   883     shown ifFalse:[^ self].
   894     shown ifFalse:[^ self].
   884 
   895 
   885     (self startOfLinesY size) == (self size + 1) ifFalse:[
   896     (self startOfLinesY size) == (self size + 1) ifFalse:[
   886         "oops, recompute the height of the contents (the first time after creation).
   897 	"oops, recompute the height of the contents (the first time after creation).
   887         "
   898 	"
   888         self recomputeHeightOfContents.
   899 	self recomputeHeightOfContents.
   889 
   900 
   890         self startOfLinesY size > 1 ifTrue:[
   901 	self startOfLinesY size > 1 ifTrue:[
   891             "oops, the contents height changed
   902 	    "oops, the contents height changed
   892             "
   903 	    "
   893             self invalidate.
   904 	    self invalidate.
   894             self contentsChanged.
   905 	    self contentsChanged.
   895             ^ self
   906 	    ^ self
   896         ].
   907 	].
   897     ].
   908     ].
   898 "/    widthOfContents isNil ifTrue:[
   909 "/    widthOfContents isNil ifTrue:[
   899 "/        self preferredExtent
   910 "/        self preferredExtent
   900 "/    ].
   911 "/    ].
   901     yStart := y.
   912     yStart := y.
   902     start  := self yVisibleToLineNr:y.
   913     start  := self yVisibleToLineNr:y.
   903 
   914 
   904     start notNil ifTrue:[
   915     start notNil ifTrue:[
   905         yAbs := y + h.
   916 	yAbs := y + h.
   906         stop := self yVisibleToLineNr:yAbs.
   917 	stop := self yVisibleToLineNr:yAbs.
   907 
   918 
   908         stop isNil ifTrue:[
   919 	stop isNil ifTrue:[
   909             stop := self size.
   920 	    stop := self size.
   910         ] ifFalse:[ |y0|
   921 	] ifFalse:[ |y0|
   911             y0 := self startOfLinesY at:stop ifAbsent:nil.
   922 	    y0 := self startOfLinesY at:stop ifAbsent:nil.
   912             y0 isNil ifTrue:[^ self].   "/ oops, lines differ (will be changed)
   923 	    y0 isNil ifTrue:[^ self].   "/ oops, lines differ (will be changed)
   913 
   924 
   914             yAbs == y0 ifTrue:[
   925 	    yAbs == y0 ifTrue:[
   915                 stop := (stop - 1) max:start
   926 		stop := (stop - 1) max:start
   916             ].
   927 	    ].
   917         ].
   928 	].
   918 
   929 
   919         start > stop ifTrue:[
   930 	start > stop ifTrue:[
   920             start := stop := nil.
   931 	    start := stop := nil.
   921         ] ifFalse:[
   932 	] ifFalse:[
   922             (renderer validateDrawableItemsFrom:start to:stop) ifFalse:[
   933 	    (listRenderer validateDrawableItemsFrom:start to:stop) ifFalse:[
   923                 self invalidate.
   934 		self invalidate.
   924                 ^ self.
   935 		^ self.
   925             ].
   936 	    ].
   926             yStart := self yVisibleOfLine:start.
   937 	    yStart := self yVisibleOfLine:start.
   927         ].
   938 	].
   928     ].
   939     ].
   929     self paint:bgColor.
   940     self paint:bgColor.
   930     self fillRectangleX:x y:y width:w height:h.
   941     self fillRectangleX:x y:y width:w height:h.
   931 
   942 
   932     StopRedrawSignal handle:[:ex|
   943     StopRedrawSignal handle:[:ex|
   933         "/ an item changed its dimension during drawing, draw is aborted
   944 	"/ an item changed its dimension during drawing, draw is aborted
   934         self invalidate
   945 	self invalidate
   935     ] do:[
   946     ] do:[
   936 
   947 
   937 
   948 
   938         start notNil ifTrue:[
   949 	start notNil ifTrue:[
   939             self drawFrom:start to:stop x:x y:yStart w:w.
   950 	    self drawFrom:start to:stop x:x y:yStart w:w.
   940         ].
   951 	].
   941         renderer postRedrawX:x y:yStart w:w from:start to:stop.
   952 	listRenderer postRedrawX:x y:yStart w:w from:start to:stop.
   942     ].
   953     ].
   943 ! !
   954 ! !
   944 
   955 
   945 !ListModelView methodsFor:'enumerating'!
   956 !ListModelView methodsFor:'enumerating'!
   946 
   957 
   953 
   964 
   954     lineNr := self yVisibleToLineNr:1.
   965     lineNr := self yVisibleToLineNr:1.
   955     lineNr isNil ifTrue:[ ^ self ].
   966     lineNr isNil ifTrue:[ ^ self ].
   956 
   967 
   957     [   item := list at:lineNr ifAbsent:[ ^ self ].
   968     [   item := list at:lineNr ifAbsent:[ ^ self ].
   958         aTwoArgBlock value:lineNr value:item.
   969 	aTwoArgBlock value:lineNr value:item.
   959         lineNr := lineNr + 1.
   970 	lineNr := lineNr + 1.
   960         (self yVisibleOfLine:lineNr) < height
   971 	(self yVisibleOfLine:lineNr) < height
   961     ] whileTrue.
   972     ] whileTrue.
   962 ! !
   973 ! !
   963 
   974 
   964 !ListModelView methodsFor:'event handling'!
   975 !ListModelView methodsFor:'event handling'!
   965 
   976 
   966 keyPress:aKey x:x y:y
   977 keyPress:aKey x:x y:y
   967     "a key was pressed - handle page-keys here"
   978     "a key was pressed - handle page-keys here"
   968 
   979 
   969     <resource: #keyboard( #PreviousPage #NextPage  #HalfPageUp #HalfPageDown
   980     <resource: #keyboard( #PreviousPage #NextPage  #HalfPageUp #HalfPageDown
   970                           #BeginOfText  #EndOfText #ScrollUp   #ScrollDown
   981 			  #BeginOfText  #EndOfText #ScrollUp   #ScrollDown
   971                         )>
   982 			)>
   972 
   983 
   973     |n|
   984     |n|
   974 
   985 
   975     self size ~~ 0 ifTrue:[
   986     self size ~~ 0 ifTrue:[
   976         (aKey == #PreviousPage) ifTrue:[^ self pageUp].
   987 	(aKey == #PreviousPage) ifTrue:[^ self pageUp].
   977         (aKey == #NextPage)     ifTrue:[^ self pageDown].
   988 	(aKey == #NextPage)     ifTrue:[^ self pageDown].
   978         (aKey == #HalfPageUp)   ifTrue:[^ self halfPageUp].
   989 	(aKey == #HalfPageUp)   ifTrue:[^ self halfPageUp].
   979         (aKey == #HalfPageDown) ifTrue:[^ self halfPageDown].
   990 	(aKey == #HalfPageDown) ifTrue:[^ self halfPageDown].
   980         (aKey == #BeginOfText)  ifTrue:[^ self scrollToTop].
   991 	(aKey == #BeginOfText)  ifTrue:[^ self scrollToTop].
   981         (aKey == #EndOfText)    ifTrue:[^ self scrollToBottom].
   992 	(aKey == #EndOfText)    ifTrue:[^ self scrollToBottom].
   982 
   993 
   983         (aKey == #ScrollUp or:[aKey == #ScrollDown]) ifTrue:[
   994 	(aKey == #ScrollUp or:[aKey == #ScrollDown]) ifTrue:[
   984             n := 1 + (self sensor compressKeyPressEventsWithKey:aKey).
   995 	    n := 1 + (self sensor compressKeyPressEventsWithKey:aKey).
   985             n := n * self verticalScrollStep.
   996 	    n := n * self verticalScrollStep.
   986 
   997 
   987             aKey == #ScrollUp ifTrue:[self scrollUp:n]
   998 	    aKey == #ScrollUp ifTrue:[self scrollUp:n]
   988                              ifFalse:[self scrollDown:n].
   999 			     ifFalse:[self scrollDown:n].
   989             ^ self
  1000 	    ^ self
   990         ].
  1001 	].
   991     ].
  1002     ].
   992     super keyPress:aKey x:x y:y
  1003     super keyPress:aKey x:x y:y
   993 !
  1004 !
   994 
  1005 
   995 sizeChanged:how
  1006 sizeChanged:how
  1026 
  1037 
  1027     anImage isNil ifTrue:[^ anImage].
  1038     anImage isNil ifTrue:[^ anImage].
  1028 
  1039 
  1029     deviceImage := anImage onDevice:device.
  1040     deviceImage := anImage onDevice:device.
  1030     deviceImage isImage ifTrue:[
  1041     deviceImage isImage ifTrue:[
  1031         deviceImage clearMaskedPixels.
  1042 	deviceImage clearMaskedPixels.
  1032     ].
  1043     ].
  1033     ^ deviceImage
  1044     ^ deviceImage
  1034 "/    |image|
  1045 "/    |image|
  1035 "/
  1046 "/
  1036 "/    (image := anImage) notNil ifTrue:[
  1047 "/    (image := anImage) notNil ifTrue:[
  1075     "setup viewStyle specifics
  1086     "setup viewStyle specifics
  1076     "
  1087     "
  1077     super initStyle.
  1088     super initStyle.
  1078 
  1089 
  1079     DefaultBackgroundColor notNil ifTrue:[
  1090     DefaultBackgroundColor notNil ifTrue:[
  1080         viewBackground := DefaultBackgroundColor
  1091 	viewBackground := DefaultBackgroundColor
  1081     ].
  1092     ].
  1082     lineSpacing   := 0.
  1093     lineSpacing   := 0.
  1083     textStartLeft := 2.
  1094     textStartLeft := 2.
  1084     textStartTop  := 2.
  1095     textStartTop  := 2.
  1085     fgColor       := DefaultForegroundColor.
  1096     fgColor       := DefaultForegroundColor.
  1087     startOfLinesY := OrderedCollection new.
  1098     startOfLinesY := OrderedCollection new.
  1088 
  1099 
  1089     startOfLinesY add:(textStartTop + margin). "/ top inset of first line
  1100     startOfLinesY add:(textStartTop + margin). "/ top inset of first line
  1090 
  1101 
  1091     DefaultShadowColor notNil ifTrue:[
  1102     DefaultShadowColor notNil ifTrue:[
  1092         shadowColor := DefaultShadowColor
  1103 	shadowColor := DefaultShadowColor
  1093     ].
  1104     ].
  1094 
  1105 
  1095     DefaultLightColor notNil ifTrue:[
  1106     DefaultLightColor notNil ifTrue:[
  1096         lightColor := DefaultLightColor
  1107 	lightColor := DefaultLightColor
  1097     ].
  1108     ].
  1098 !
  1109 !
  1099 
  1110 
  1100 initialize
  1111 initialize
  1101     "setup default attributes
  1112     "setup default attributes
  1107     enabled            := true.
  1118     enabled            := true.
  1108     autoScroll         := true.
  1119     autoScroll         := true.
  1109     scrollWhenUpdating := #beginOfText.
  1120     scrollWhenUpdating := #beginOfText.
  1110     hasConstantHeight  := false.
  1121     hasConstantHeight  := false.
  1111 
  1122 
  1112     renderer isNil ifTrue:[
  1123     listRenderer isNil ifTrue:[
  1113         renderer := self class defaultRenderer forView:self.
  1124 	listRenderer := self class defaultRenderer forView:self.
  1114     ].
  1125     ].
  1115     self list:(self newDefaultList).
  1126     self list:(self newDefaultList).
  1116 !
  1127 !
  1117 
  1128 
  1118 mapped
  1129 mapped
  1120     "
  1131     "
  1121     "/ shown ifFalse:[
  1132     "/ shown ifFalse:[
  1122 "/        self recomputeHeightOfContents.
  1133 "/        self recomputeHeightOfContents.
  1123 "/        self contentsChanged.     "/ is computeEditorLayout what you want ?
  1134 "/        self contentsChanged.     "/ is computeEditorLayout what you want ?
  1124     "/ ].
  1135     "/ ].
  1125     renderer mapped.
  1136     listRenderer mapped.
  1126     super mapped
  1137     super mapped
  1127 
  1138 
  1128 !
  1139 !
  1129 
  1140 
  1130 recreate
  1141 recreate
  1144 !
  1155 !
  1145 
  1156 
  1146 release
  1157 release
  1147     "remove dependencies
  1158     "remove dependencies
  1148     "
  1159     "
  1149     renderer release.
  1160     listRenderer release.
  1150 
  1161 
  1151     self listHolder removeDependent:self.
  1162     self listHolder removeDependent:self.
  1152     self list       removeDependent:self.
  1163     self list       removeDependent:self.
  1153 
  1164 
  1154     super release
  1165     super release
  1161 
  1172 
  1162     ^ self sensor hasDamageFor:self
  1173     ^ self sensor hasDamageFor:self
  1163 !
  1174 !
  1164 
  1175 
  1165 startOfLinesY
  1176 startOfLinesY
  1166     "returns a collection of absolute Y-positions per line. 
  1177     "returns a collection of absolute Y-positions per line.
  1167      The first entry is the top Y inset.
  1178      The first entry is the top Y inset.
  1168      The size of the list is one more than the lists size,
  1179      The size of the list is one more than the lists size,
  1169      providing the Y-position of the line below the contents as its last entry."
  1180      providing the Y-position of the line below the contents as its last entry."
  1170 
  1181 
  1171     ^ startOfLinesY
  1182     ^ startOfLinesY
  1189     |y y2 y1 cash|
  1200     |y y2 y1 cash|
  1190 
  1201 
  1191     cash := self startOfLinesY.
  1202     cash := self startOfLinesY.
  1192 
  1203 
  1193     (y := cash at:aLineNr ifAbsent:nil) notNil ifTrue:[
  1204     (y := cash at:aLineNr ifAbsent:nil) notNil ifTrue:[
  1194         ^ y
  1205 	^ y
  1195     ].
  1206     ].
  1196 
  1207 
  1197     "/ recompute a y position
  1208     "/ recompute a y position
  1198     y1 := cash at:1 ifAbsent:textStartTop.
  1209     y1 := cash at:1 ifAbsent:textStartTop.
  1199     y2 := cash at:2 ifAbsent:(textStartTop + 16).
  1210     y2 := cash at:2 ifAbsent:(textStartTop + 16).
  1222 
  1233 
  1223     yAbs := yVisible + viewOrigin y.
  1234     yAbs := yVisible + viewOrigin y.
  1224     cache := self startOfLinesY.
  1235     cache := self startOfLinesY.
  1225 
  1236 
  1226     (size := cache size) < 2 ifTrue:[
  1237     (size := cache size) < 2 ifTrue:[
  1227         "/ empty list
  1238 	"/ empty list
  1228         (yAbs between:textStartTop and:textStartTop+16) ifTrue:[^ 1].
  1239 	(yAbs between:textStartTop and:textStartTop+16) ifTrue:[^ 1].
  1229         ^ nil
  1240 	^ nil
  1230     ].   
  1241     ].
  1231 
  1242 
  1232     yCache := cache at:size ifAbsent:nil.
  1243     yCache := cache at:size ifAbsent:nil.
  1233     yCache isNil ifTrue:[ ^ nil ].    "/ out of list
  1244     yCache isNil ifTrue:[ ^ nil ].    "/ out of list
  1234 
  1245 
  1235     yRun := yCache.
  1246     yRun := yCache.
  1236 
  1247 
  1237     yAbs >= yRun ifTrue:[
  1248     yAbs >= yRun ifTrue:[
  1238         yAbs == yRun ifTrue:[ ^ size - 1].
  1249 	yAbs == yRun ifTrue:[ ^ size - 1].
  1239         ^ nil   "/ out of list
  1250 	^ nil   "/ out of list
  1240     ].
  1251     ].
  1241 
  1252 
  1242     constantHeight notNil ifTrue:[
  1253     constantHeight notNil ifTrue:[
  1243         yAbs := yAbs - (cache at:1).
  1254 	yAbs := yAbs - (cache at:1).
  1244         yAbs < constantHeight ifTrue:[ ^ 1 ].
  1255 	yAbs < constantHeight ifTrue:[ ^ 1 ].
  1245         ^ yAbs // constantHeight + 1
  1256 	^ yAbs // constantHeight + 1
  1246     ].
  1257     ].
  1247 
  1258 
  1248     ictr := yAbs // (cache at:2).
  1259     ictr := yAbs // (cache at:2).
  1249     ictr < 1 ifTrue:[ ictr := 1 ]
  1260     ictr < 1 ifTrue:[ ictr := 1 ]
  1250             ifFalse:[ ictr := ictr min:size ].
  1261 	    ifFalse:[ ictr := ictr min:size ].
  1251 
  1262 
  1252     yRun := cache at:ictr.
  1263     yRun := cache at:ictr.
  1253 
  1264 
  1254     yRun > yAbs ifTrue:[
  1265     yRun > yAbs ifTrue:[
  1255         [(ictr := ictr - 1) > 0 ] whileTrue:[
  1266 	[(ictr := ictr - 1) > 0 ] whileTrue:[
  1256             yRun := cache at:ictr.
  1267 	    yRun := cache at:ictr.
  1257             yRun <= yAbs ifTrue:[ ^ ictr ].
  1268 	    yRun <= yAbs ifTrue:[ ^ ictr ].
  1258         ].
  1269 	].
  1259         ^ 1
  1270 	^ 1
  1260     ].
  1271     ].
  1261 
  1272 
  1262     [ yRun ~~ yAbs ] whileTrue:[
  1273     [ yRun ~~ yAbs ] whileTrue:[
  1263         ictr := ictr + 1.
  1274 	ictr := ictr + 1.
  1264         yRun := cache at:ictr.
  1275 	yRun := cache at:ictr.
  1265         yRun > yAbs ifTrue:[ ^ ictr - 1 ].
  1276 	yRun > yAbs ifTrue:[ ^ ictr - 1 ].
  1266     ].
  1277     ].
  1267     ^ ictr
  1278     ^ ictr
  1268 !
  1279 !
  1269 
  1280 
  1270 yVisibleToRowNr:yVisible
  1281 yVisibleToRowNr:yVisible
  1292 !
  1303 !
  1293 
  1304 
  1294 lineHeightFor:anItem
  1305 lineHeightFor:anItem
  1295     "returns the computed line height for an item
  1306     "returns the computed line height for an item
  1296     "
  1307     "
  1297     ^ lineSpacing + (renderer heightFor:anItem)
  1308     ^ lineSpacing + (listRenderer heightFor:anItem)
  1298 !
  1309 !
  1299 
  1310 
  1300 listSizeChanged:anIndex nLines:noLines
  1311 listSizeChanged:anIndex nLines:noLines
  1301     "list size changed; information is stored to recompute the
  1312     "list size changed; information is stored to recompute the
  1302      width if required( preferredExtent, horizontal scroller ... ).
  1313      width if required( preferredExtent, horizontal scroller ... ).
  1309     |
  1320     |
  1310 "/    preferredExtent := nil.
  1321 "/    preferredExtent := nil.
  1311 
  1322 
  1312     cachedPreferredExtent := nil.
  1323     cachedPreferredExtent := nil.
  1313     widthOfContents isNil ifTrue:[      "/ recompute whole list
  1324     widthOfContents isNil ifTrue:[      "/ recompute whole list
  1314         ^ self
  1325 	^ self
  1315     ].
  1326     ].
  1316 
  1327 
  1317     (noLines < 0 or:[(size := self size) <= noLines]) ifTrue:[
  1328     (noLines < 0 or:[(size := self size) <= noLines]) ifTrue:[
  1318         widthOfContents := nil.         "/ force recompute whole list
  1329 	widthOfContents := nil.         "/ force recompute whole list
  1319         ^ self
  1330 	^ self
  1320     ].
  1331     ].
  1321 
  1332 
  1322     stop  := anIndex + noLines - 1.     "/ recompute a range
  1333     stop  := anIndex + noLines - 1.     "/ recompute a range
  1323     start := anIndex.
  1334     start := anIndex.
  1324 
  1335 
  1325     computeWidthInRange notNil ifTrue:[
  1336     computeWidthInRange notNil ifTrue:[
  1326         start := computeWidthInRange y.
  1337 	start := computeWidthInRange y.
  1327         stop  <  start ifTrue:[stop := start min:size].
  1338 	stop  <  start ifTrue:[stop := start min:size].
  1328         start := (computeWidthInRange x) min:anIndex.
  1339 	start := (computeWidthInRange x) min:anIndex.
  1329     ].
  1340     ].
  1330     computeWidthInRange := start@stop
  1341     computeWidthInRange := start@stop
  1331 !
  1342 !
  1332 
  1343 
  1333 lostSynchronisation
  1344 lostSynchronisation
  1334     "called when the changes derived from the model are faster than the handling
  1345     "called when the changes derived from the model are faster than the handling
  1335     "
  1346     "
  1336     shown ifTrue:[
  1347     shown ifTrue:[
  1337         self recomputeHeightOfContents.
  1348 	self recomputeHeightOfContents.
  1338         self invalidate.
  1349 	self invalidate.
  1339         self contentsChanged
  1350 	self contentsChanged
  1340     ].
  1351     ].
  1341 !
  1352 !
  1342 
  1353 
  1343 newDefaultList
  1354 newDefaultList
  1344     "creates and returns a new default list class, on default a List
  1355     "creates and returns a new default list class, on default a List
  1349 widthOfWidestLineBetween:firstLine and:lastLine
  1360 widthOfWidestLineBetween:firstLine and:lastLine
  1350     "return the width in pixels of the widest line in a range
  1361     "return the width in pixels of the widest line in a range
  1351     "
  1362     "
  1352     |item width|
  1363     |item width|
  1353 
  1364 
  1354     width := renderer widthOfWidestLineBetween:firstLine and:lastLine.
  1365     width := listRenderer widthOfWidestLineBetween:firstLine and:lastLine.
  1355     width notNil ifTrue:[^ width].
  1366     width notNil ifTrue:[^ width].
  1356 
  1367 
  1357     width := textStartLeft.
  1368     width := textStartLeft.
  1358 
  1369 
  1359     firstLine to:lastLine do:[:anIndex|
  1370     firstLine to:lastLine do:[:anIndex|
  1360         item := self at:anIndex ifAbsent:nil.
  1371 	item := self at:anIndex ifAbsent:nil.
  1361 
  1372 
  1362         item isNil ifTrue:[^ width + textStartLeft].
  1373 	item isNil ifTrue:[^ width + textStartLeft].
  1363 
  1374 
  1364         width := (renderer widthFor:item) max:width
  1375 	width := (listRenderer widthFor:item) max:width
  1365     ].
  1376     ].
  1366     ^ width + textStartLeft
  1377     ^ width + textStartLeft
  1367 ! !
  1378 ! !
  1368 
  1379 
  1369 !ListModelView methodsFor:'queries'!
  1380 !ListModelView methodsFor:'queries'!
  1391     shown ifFalse:[^ false].
  1402     shown ifFalse:[^ false].
  1392 
  1403 
  1393     y := self yVisibleOfLine:aLineNr.
  1404     y := self yVisibleOfLine:aLineNr.
  1394 
  1405 
  1395     (y between:0 and:height) ifTrue:[
  1406     (y between:0 and:height) ifTrue:[
  1396         y := self yVisibleOfLine:(aLineNr + 1).
  1407 	y := self yVisibleOfLine:(aLineNr + 1).
  1397         y <= height ifTrue:[^ true ].
  1408 	y <= height ifTrue:[^ true ].
  1398     ].
  1409     ].
  1399     ^ false
  1410     ^ false
  1400 !
  1411 !
  1401 
  1412 
  1402 size
  1413 size
  1412 
  1423 
  1413     |x y|
  1424     |x y|
  1414 
  1425 
  1415     "/ If I have an explicit preferredExtent..
  1426     "/ If I have an explicit preferredExtent..
  1416     explicitExtent notNil ifTrue:[
  1427     explicitExtent notNil ifTrue:[
  1417         ^ explicitExtent
  1428 	^ explicitExtent
  1418     ].
  1429     ].
  1419 
  1430 
  1420     "/ If I have a cached preferredExtent value..
  1431     "/ If I have a cached preferredExtent value..
  1421     preferredExtent notNil ifTrue:[
  1432     preferredExtent notNil ifTrue:[
  1422         ^ preferredExtent
  1433 	^ preferredExtent
  1423     ].
  1434     ].
  1424     cachedPreferredExtent isNil ifTrue:[
  1435     cachedPreferredExtent isNil ifTrue:[
  1425         y := self heightOfContents.
  1436 	y := self heightOfContents.
  1426         x := self widthOfContents.
  1437 	x := self widthOfContents.
  1427         cachedPreferredExtent := x@y
  1438 	cachedPreferredExtent := x@y
  1428     ].
  1439     ].
  1429     ^ cachedPreferredExtent
  1440     ^ cachedPreferredExtent
  1430 !
  1441 !
  1431 
  1442 
  1432 recomputeHeightOfContents
  1443 recomputeHeightOfContents
  1433     "recompute all the y positions
  1444     "recompute all the y positions
  1434     "
  1445     "
  1435     |newList
  1446     |newList
  1436      yAbs "{ Class: SmallInteger }" 
  1447      yAbs "{ Class: SmallInteger }"
  1437      size "{ Class: SmallInteger }"|
  1448      size "{ Class: SmallInteger }"|
  1438 
  1449 
  1439     yAbs    := (textStartTop + margin).   "/ top inset of first line
  1450     yAbs    := (textStartTop + margin).   "/ top inset of first line
  1440     size    := self size.
  1451     size    := self size.
  1441     newList := OrderedCollection new:(size + 1).
  1452     newList := OrderedCollection new:(size + 1).
  1442     newList add:yAbs.
  1453     newList add:yAbs.
  1443 
  1454 
  1444     size ~~ 0 ifTrue:[
  1455     size ~~ 0 ifTrue:[
  1445         hasConstantHeight ifTrue:[
  1456 	hasConstantHeight ifTrue:[
  1446             constantHeight isNil ifTrue:[ constantHeight := self heightOfAnyNonNilItem ].
  1457 	    constantHeight isNil ifTrue:[ constantHeight := self heightOfAnyNonNilItem ].
  1447         ].
  1458 	].
  1448         
  1459 
  1449         1 to:size do:[:anIndex|
  1460 	1 to:size do:[:anIndex|
  1450             yAbs := yAbs + (constantHeight notNil 
  1461 	    yAbs := yAbs + (constantHeight notNil
  1451                                 ifTrue:[constantHeight] 
  1462 				ifTrue:[constantHeight]
  1452                                 ifFalse:[self realHeightOfLineAt:anIndex]).
  1463 				ifFalse:[self realHeightOfLineAt:anIndex]).
  1453             newList add:yAbs
  1464 	    newList add:yAbs
  1454         ].
  1465 	].
  1455     ].
  1466     ].
  1456     startOfLinesY := newList.
  1467     startOfLinesY := newList.
  1457     cachedPreferredExtent := nil.
  1468     cachedPreferredExtent := nil.
  1458 ! !
  1469 ! !
  1459 
  1470 
  1481 
  1492 
  1482 heightOfLineAt:aLineNr
  1493 heightOfLineAt:aLineNr
  1483     "returns the height of a line at an index (including lineSpacing...)"
  1494     "returns the height of a line at an index (including lineSpacing...)"
  1484 
  1495 
  1485     hasConstantHeight ifTrue:[
  1496     hasConstantHeight ifTrue:[
  1486         constantHeight isNil ifTrue:[ 
  1497 	constantHeight isNil ifTrue:[
  1487             constantHeight := self heightOfAnyNonNilItem.
  1498 	    constantHeight := self heightOfAnyNonNilItem.
  1488         ].
  1499 	].
  1489         ^ constantHeight
  1500 	^ constantHeight
  1490     ].
  1501     ].
  1491     ^ self realHeightOfLineAt:aLineNr
  1502     ^ self realHeightOfLineAt:aLineNr
  1492 !
  1503 !
  1493 
  1504 
  1494 innerHeight
  1505 innerHeight
  1518 
  1529 
  1519     |item|
  1530     |item|
  1520 
  1531 
  1521     item := self at:aLineNr ifAbsent:nil.
  1532     item := self at:aLineNr ifAbsent:nil.
  1522     item notNil ifTrue:[
  1533     item notNil ifTrue:[
  1523         ^ self lineHeightFor:item
  1534 	^ self lineHeightFor:item
  1524     ].
  1535     ].
  1525     ^ font height "arbitrary"
  1536     ^ font height "arbitrary"
  1526 !
  1537 !
  1527 
  1538 
  1528 setWidthOfContents: aWidth
  1539 setWidthOfContents: aWidth
  1534 
  1545 
  1535     ^ 10
  1546     ^ 10
  1536 !
  1547 !
  1537 
  1548 
  1538 viewOrigin
  1549 viewOrigin
  1539     "return the viewOrigin; thats the coordinate of the contents 
  1550     "return the viewOrigin; thats the coordinate of the contents
  1540      which is shown topLeft in the view.
  1551      which is shown topLeft in the view.
  1541     "
  1552     "
  1542     ^ viewOrigin
  1553     ^ viewOrigin
  1543 
  1554 
  1544 !
  1555 !
  1550      size  "{ Class:SmallInteger }"
  1561      size  "{ Class:SmallInteger }"
  1551      start "{ Class:SmallInteger }"
  1562      start "{ Class:SmallInteger }"
  1552      stop  "{ Class:SmallInteger }"
  1563      stop  "{ Class:SmallInteger }"
  1553     |
  1564     |
  1554     (widthOfContents notNil and:[computeWidthInRange isNil]) ifTrue:[
  1565     (widthOfContents notNil and:[computeWidthInRange isNil]) ifTrue:[
  1555         ^ widthOfContents + textStartLeft
  1566 	^ widthOfContents + textStartLeft
  1556     ].
  1567     ].
  1557     range               := computeWidthInRange.
  1568     range               := computeWidthInRange.
  1558     computeWidthInRange := nil.
  1569     computeWidthInRange := nil.
  1559 "/    preferredExtent     := nil.
  1570 "/    preferredExtent     := nil.
  1560 "/    cachedPreferredExtent := nil.
  1571 "/    cachedPreferredExtent := nil.
  1562     shown ifFalse:[ ^ 60 ].
  1573     shown ifFalse:[ ^ 60 ].
  1563 
  1574 
  1564     size := self size.
  1575     size := self size.
  1565 
  1576 
  1566     size == 0 ifTrue:[
  1577     size == 0 ifTrue:[
  1567         widthOfContents := 20.
  1578 	widthOfContents := 20.
  1568     ] ifFalse:[
  1579     ] ifFalse:[
  1569         widthOfContents isNil ifTrue:[
  1580 	widthOfContents isNil ifTrue:[
  1570             widthOfContents := self widthOfWidestLineBetween:1 and:size
  1581 	    widthOfContents := self widthOfWidestLineBetween:1 and:size
  1571         ] ifFalse:[
  1582 	] ifFalse:[
  1572             start := range x.
  1583 	    start := range x.
  1573             stop  := range y min:size.
  1584 	    stop  := range y min:size.
  1574 
  1585 
  1575             start > stop ifFalse:[
  1586 	    start > stop ifFalse:[
  1576                 size := self widthOfWidestLineBetween:start and:stop.
  1587 		size := self widthOfWidestLineBetween:start and:stop.
  1577 
  1588 
  1578                 widthOfContents < size ifTrue:[
  1589 		widthOfContents < size ifTrue:[
  1579                     widthOfContents := size
  1590 		    widthOfContents := size
  1580                 ]
  1591 		]
  1581             ]
  1592 	    ]
  1582         ]
  1593 	]
  1583     ].
  1594     ].
  1584     ^ widthOfContents + textStartLeft
  1595     ^ widthOfContents + textStartLeft
  1585 !
  1596 !
  1586 
  1597 
  1587 xOriginOfContents
  1598 xOriginOfContents
  1588     "return the horizontal origin of the contents in pixels
  1599     "return the horizontal origin of the contents in pixels
  1589     "
  1600     "
  1590     ^ viewOrigin x 
  1601     ^ viewOrigin x
  1591 
  1602 
  1592 !
  1603 !
  1593 
  1604 
  1594 yOriginOfContents
  1605 yOriginOfContents
  1595     "return the vertical origin of the contents in pixels
  1606     "return the vertical origin of the contents in pixels
  1616 
  1627 
  1617 makeLineVisible:aLnNr
  1628 makeLineVisible:aLnNr
  1618     "make the line visible
  1629     "make the line visible
  1619     "
  1630     "
  1620     aLnNr notNil ifTrue:[
  1631     aLnNr notNil ifTrue:[
  1621         self scrollToLine:aLnNr
  1632 	self scrollToLine:aLnNr
  1622     ].
  1633     ].
  1623 !
  1634 !
  1624 
  1635 
  1625 scrollTo:anOrigin redraw:doRedraw
  1636 scrollTo:anOrigin redraw:doRedraw
  1626     "change origin to have newOrigin be visible at the top-left.
  1637     "change origin to have newOrigin be visible at the top-left.
  1639      dX         "{ Class:SmallInteger }"
  1650      dX         "{ Class:SmallInteger }"
  1640      dY         "{ Class:SmallInteger }"
  1651      dY         "{ Class:SmallInteger }"
  1641     |
  1652     |
  1642 
  1653 
  1643     realized ifFalse:[
  1654     realized ifFalse:[
  1644         ^ self
  1655 	^ self
  1645     ].
  1656     ].
  1646 
  1657 
  1647     innerWT := self innerWidth.
  1658     innerWT := self innerWidth.
  1648     innerHG := self innerHeight.
  1659     innerHG := self innerHeight.
  1649 
  1660 
  1650     h := viewOrigin y.
  1661     h := viewOrigin y.
  1651 
  1662 
  1652     (y := anOrigin y) > h ifTrue:[              "/ end of contents
  1663     (y := anOrigin y) > h ifTrue:[              "/ end of contents
  1653         y > (dY := self maxViewOriginY) ifTrue:[
  1664 	y > (dY := self maxViewOriginY) ifTrue:[
  1654             y := dY max:h
  1665 	    y := dY max:h
  1655         ]
  1666 	]
  1656     ] ifFalse:[
  1667     ] ifFalse:[
  1657         y := y max:0.
  1668 	y := y max:0.
  1658     ].
  1669     ].
  1659 
  1670 
  1660     (x := anOrigin x) > 0 ifTrue:[
  1671     (x := anOrigin x) > 0 ifTrue:[
  1661         x := x min:(self widthOfContents - innerWT).
  1672 	x := x min:(self widthOfContents - innerWT).
  1662     ].
  1673     ].
  1663     x      := x max:0.
  1674     x      := x max:0.
  1664     newOrg := (x @ y).
  1675     newOrg := (x @ y).
  1665     dltOrg := newOrg - viewOrigin.
  1676     dltOrg := newOrg - viewOrigin.
  1666     dX     := dltOrg x.
  1677     dX     := dltOrg x.
  1667     dY     := dltOrg y.
  1678     dY     := dltOrg y.
  1668 
  1679 
  1669     (dX == 0 and:[dY == 0]) ifTrue:[
  1680     (dX == 0 and:[dY == 0]) ifTrue:[
  1670         ^ self
  1681 	^ self
  1671     ].
  1682     ].
  1672     dY := dY abs.
  1683     dY := dY abs.
  1673     dX := dX abs.
  1684     dX := dX abs.
  1674 
  1685 
  1675     (   (dX ~~ 0 and:[dY ~~ 0])                         "/ scroll vertical & horizontal
  1686     (   (dX ~~ 0 and:[dY ~~ 0])                         "/ scroll vertical & horizontal
  1676      or:[(innerHG - dY < 20 or:[innerWT - dX < 20])]    "/ faster to invalidate screen
  1687      or:[(innerHG - dY < 20 or:[innerWT - dX < 20])]    "/ faster to invalidate screen
  1677     ) ifTrue:[
  1688     ) ifTrue:[
  1678         viewOrigin := newOrg.
  1689 	viewOrigin := newOrg.
  1679         self originChanged:dltOrg.
  1690 	self originChanged:dltOrg.
  1680         self invalidate.
  1691 	self invalidate.
  1681         ^ self
  1692 	^ self
  1682     ].
  1693     ].
  1683 
  1694 
  1684     (winGrp := self windowGroup) notNil ifTrue:[
  1695     (winGrp := self windowGroup) notNil ifTrue:[
  1685         winGrp processRealExposeEventsFor:self.
  1696 	winGrp processRealExposeEventsFor:self.
  1686     ].
  1697     ].
  1687 
  1698 
  1688     self originWillChange.
  1699     self originWillChange.
  1689 
  1700 
  1690     doRedraw ifFalse:[
  1701     doRedraw ifFalse:[
  1691         viewOrigin := newOrg.
  1702 	viewOrigin := newOrg.
  1692         self originChanged:dltOrg.
  1703 	self originChanged:dltOrg.
  1693         ^ self 
  1704 	^ self
  1694     ].
  1705     ].
  1695 
  1706 
  1696     self catchExpose.
  1707     self catchExpose.
  1697     viewOrigin := newOrg.
  1708     viewOrigin := newOrg.
  1698 
  1709 
  1699     dY ~~ 0 ifTrue:[                            "/ SCROLL VERTICAL
  1710     dY ~~ 0 ifTrue:[                            "/ SCROLL VERTICAL
  1700         y0 := y1 := margin + dY.
  1711 	y0 := y1 := margin + dY.
  1701         h  := innerHG - dY.
  1712 	h  := innerHG - dY.
  1702 
  1713 
  1703         dltOrg y < 0 ifTrue:[y0 := margin. y := y0]
  1714 	dltOrg y < 0 ifTrue:[y0 := margin. y := y0]
  1704                     ifFalse:[y1 := margin. y := y1 + h].
  1715 		    ifFalse:[y1 := margin. y := y1 + h].
  1705 
  1716 
  1706         self copyFrom:self x:margin y:y0 toX:margin y:y1 width:innerWT height:h async:true.
  1717 	self copyFrom:self x:margin y:y0 toX:margin y:y1 width:innerWT height:h async:true.
  1707         self invalidateX:margin y:y width:innerWT height:(innerHG - h).
  1718 	self invalidateX:margin y:y width:innerWT height:(innerHG - h).
  1708 
  1719 
  1709     ] ifFalse:[                                 "/ SCROLL HORIZONTAL
  1720     ] ifFalse:[                                 "/ SCROLL HORIZONTAL
  1710         x0 := x1 := dX + margin.
  1721 	x0 := x1 := dX + margin.
  1711         w  := innerWT - dX.
  1722 	w  := innerWT - dX.
  1712 
  1723 
  1713         dltOrg x < 0 ifTrue:[x0 := x := margin ]
  1724 	dltOrg x < 0 ifTrue:[x0 := x := margin ]
  1714                     ifFalse:[x1 := margin. x := w].
  1725 		    ifFalse:[x1 := margin. x := w].
  1715 
  1726 
  1716         self copyFrom:self x:x0 y:margin toX:x1 y:margin width:w height:innerHG async:true.
  1727 	self copyFrom:self x:x0 y:margin toX:x1 y:margin width:w height:innerHG async:true.
  1717         self invalidateX:x y:margin width:(width - w) height:innerHG.
  1728 	self invalidateX:x y:margin width:(width - w) height:innerHG.
  1718     ].
  1729     ].
  1719     self originChanged:dltOrg.
  1730     self originChanged:dltOrg.
  1720     self waitForExpose.
  1731     self waitForExpose.
  1721 
  1732 
  1722     winGrp notNil ifTrue:[
  1733     winGrp notNil ifTrue:[
  1723         winGrp processRealExposeEventsFor:self.
  1734 	winGrp processRealExposeEventsFor:self.
  1724     ].
  1735     ].
  1725 !
  1736 !
  1726 
  1737 
  1727 scrollToLine:aLineNumber
  1738 scrollToLine:aLineNumber
  1728     "make line visible
  1739     "make line visible
  1731      yTop "{ Class:SmallInteger }"
  1742      yTop "{ Class:SmallInteger }"
  1732      orgY "{ Class:SmallInteger }"
  1743      orgY "{ Class:SmallInteger }"
  1733      yBot "{ Class:SmallInteger }"
  1744      yBot "{ Class:SmallInteger }"
  1734     |
  1745     |
  1735     (shown and:[aLineNumber notNil and:[aLineNumber between:1 and:(self size)]]) ifFalse:[
  1746     (shown and:[aLineNumber notNil and:[aLineNumber between:1 and:(self size)]]) ifFalse:[
  1736         ^ self
  1747 	^ self
  1737     ].
  1748     ].
  1738 
  1749 
  1739     yTop := self yAbsoluteOfLine:aLineNumber.
  1750     yTop := self yAbsoluteOfLine:aLineNumber.
  1740     inHg := self innerHeight.
  1751     inHg := self innerHeight.
  1741     orgY := viewOrigin y.
  1752     orgY := viewOrigin y.
  1742 
  1753 
  1743     yTop > orgY ifTrue:[
  1754     yTop > orgY ifTrue:[
  1744         yBot := self yAbsoluteOfLine:(aLineNumber + 1).
  1755 	yBot := self yAbsoluteOfLine:(aLineNumber + 1).
  1745 
  1756 
  1746         yBot <= (orgY + inHg) ifTrue:[
  1757 	yBot <= (orgY + inHg) ifTrue:[
  1747             ^ self
  1758 	    ^ self
  1748         ].
  1759 	].
  1749     ].
  1760     ].
  1750     yTop := (yTop - (inHg // 2)) max:0.
  1761     yTop := (yTop - (inHg // 2)) max:0.
  1751     self scrollTo:(viewOrigin x @ yTop).
  1762     self scrollTo:(viewOrigin x @ yTop).
  1752 ! !
  1763 ! !
  1753 
  1764 
  1758      - timeDelta for scroll is computed from distance
  1769      - timeDelta for scroll is computed from distance
  1759     "
  1770     "
  1760     |timeDelta scrollBlock|
  1771     |timeDelta scrollBlock|
  1761 
  1772 
  1762     autoScroll ifFalse:[
  1773     autoScroll ifFalse:[
  1763         self stopAutoScroll.
  1774 	self stopAutoScroll.
  1764         ^ self
  1775 	^ self
  1765     ].
  1776     ].
  1766 
  1777 
  1767     autoScrollBlock notNil ifTrue:[
  1778     autoScrollBlock notNil ifTrue:[
  1768         Processor removeTimedBlock:autoScrollBlock.
  1779 	Processor removeTimedBlock:autoScrollBlock.
  1769     ] ifFalse:[
  1780     ] ifFalse:[
  1770         self compressMotionEvents:false.
  1781 	self compressMotionEvents:false.
  1771     ].
  1782     ].
  1772 
  1783 
  1773     timeDelta := 0.5 / (aDistance abs).
  1784     timeDelta := 0.5 / (aDistance abs).
  1774 
  1785 
  1775     scrollBlock := 
  1786     scrollBlock :=
  1776         [
  1787 	[
  1777             aSelectorOrBlock isSymbol ifTrue:[
  1788 	    aSelectorOrBlock isSymbol ifTrue:[
  1778                 self perform:aSelectorOrBlock.
  1789 		self perform:aSelectorOrBlock.
  1779             ] ifFalse:[
  1790 	    ] ifFalse:[
  1780                 aSelectorOrBlock value
  1791 		aSelectorOrBlock value
  1781             ].
  1792 	    ].
  1782             autoScrollBlock notNil ifTrue:[
  1793 	    autoScrollBlock notNil ifTrue:[
  1783                 Processor addTimedBlock:autoScrollBlock afterSeconds:timeDelta.
  1794 		Processor addTimedBlock:autoScrollBlock afterSeconds:timeDelta.
  1784             ]
  1795 	    ]
  1785         ].
  1796 	].
  1786 
  1797 
  1787     autoScrollBlock := [self sensor pushUserEvent:#value for:scrollBlock].
  1798     autoScrollBlock := [self sensor pushUserEvent:#value for:scrollBlock].
  1788     Processor addTimedBlock:autoScrollBlock afterSeconds:timeDelta.
  1799     Processor addTimedBlock:autoScrollBlock afterSeconds:timeDelta.
  1789 !
  1800 !
  1790 
  1801 
  1812 "
  1823 "
  1813     prepared for ListItemRenderer
  1824     prepared for ListItemRenderer
  1814     .... SelectionItemRenderer ...
  1825     .... SelectionItemRenderer ...
  1815 
  1826 
  1816     goal:
  1827     goal:
  1817         allow the user to redefine the display operation and the dimesion queries
  1828 	allow the user to redefine the display operation and the dimesion queries
  1818 "
  1829 "
  1819 ! !
  1830 ! !
  1820 
  1831 
  1821 !ListModelView::Renderer class methodsFor:'instance creation'!
  1832 !ListModelView::Renderer class methodsFor:'instance creation'!
  1822 
  1833 
  1851 
  1862 
  1852     x0 := xLeft.
  1863     x0 := xLeft.
  1853     y0 := yTop.
  1864     y0 := yTop.
  1854 
  1865 
  1855     anItem isHierarchicalItem ifTrue:[
  1866     anItem isHierarchicalItem ifTrue:[
  1856         anItem displayOn:view x:x0 y:y0 h:h
  1867 	anItem displayOn:view x:x0 y:y0 h:h
  1857     ] ifFalse:[
  1868     ] ifFalse:[
  1858         anItem isNil ifTrue:[^ self].
  1869 	anItem isNil ifTrue:[^ self].
  1859 
  1870 
  1860         y0    := y0 - ((self heightFor:anItem) + 1 - h // 2).
  1871 	y0    := y0 - ((self heightFor:anItem) + 1 - h // 2).
  1861         label := anItem.
  1872 	label := anItem.
  1862 
  1873 
  1863         label isImageOrForm ifFalse:[
  1874 	label isImageOrForm ifFalse:[
  1864             label isNumber ifTrue:[
  1875 	    label isNumber ifTrue:[
  1865                 label := label printString
  1876 		label := label printString
  1866             ].
  1877 	    ].
  1867             y0 := y0 + view font ascent
  1878 	    y0 := y0 + view font ascent
  1868         ].
  1879 	].
  1869         label displayOn:view x:x0 y:y0
  1880 	label displayOn:view x:x0 y:y0
  1870     ].
  1881     ].
  1871 !
  1882 !
  1872 
  1883 
  1873 postRedrawX:damageX y:yStartOrYDamage w:damageWidth from:startOrNil to:stopOrNil
  1884 postRedrawX:damageX y:yStartOrYDamage w:damageWidth from:startOrNil to:stopOrNil
  1874     "called after redraw of the items in range from start to stop is done;
  1885     "called after redraw of the items in range from start to stop is done;
  1965     receiver := aReceiver.
  1976     receiver := aReceiver.
  1966 
  1977 
  1967     minimumRequiredColumnHeight := 0.
  1978     minimumRequiredColumnHeight := 0.
  1968 
  1979 
  1969     aSeqOfColumnSpecs size == 0 ifTrue:[
  1980     aSeqOfColumnSpecs size == 0 ifTrue:[
  1970         columnDescriptors := #().
  1981 	columnDescriptors := #().
  1971     ] ifFalse:[
  1982     ] ifFalse:[
  1972         columnDescriptors := aSeqOfColumnSpecs collect:[:aColumnSpec|
  1983 	columnDescriptors := aSeqOfColumnSpecs collect:[:aColumnSpec|
  1973             ColumnDescriptor dataSetColumnSpec:aColumnSpec
  1984 	    ColumnDescriptor dataSetColumnSpec:aColumnSpec
  1974         ].
  1985 	].
  1975         columnDescriptors keysAndValuesDo:[:colNr :spec|
  1986 	columnDescriptors keysAndValuesDo:[:colNr :spec|
  1976             spec columnNumber:colNr.
  1987 	    spec columnNumber:colNr.
  1977 
  1988 
  1978             minimumRequiredColumnHeight :=
  1989 	    minimumRequiredColumnHeight :=
  1979                     minimumRequiredColumnHeight max:(spec minimumRequiredColumnHeight).
  1990 		    minimumRequiredColumnHeight max:(spec minimumRequiredColumnHeight).
  1980         ].
  1991 	].
  1981     ].
  1992     ].
  1982     hasFixedItemWidth := attributes at:#hasFixedItemWidth ifAbsent:[false].
  1993     hasFixedItemWidth := attributes at:#hasFixedItemWidth ifAbsent:[false].
  1983 
  1994 
  1984     xInset      := 2 * self splitbarInset.
  1995     xInset      := 2 * self splitbarInset.
  1985     numCols     := columnDescriptors size.
  1996     numCols     := columnDescriptors size.
  1987 
  1998 
  1988     xSplitbars  := Array new:(numCols + 1).
  1999     xSplitbars  := Array new:(numCols + 1).
  1989     xSplitbars at:1 put:xOffset.
  2000     xSplitbars at:1 put:xOffset.
  1990 
  2001 
  1991     1 to:numCols do:[:aColNr|
  2002     1 to:numCols do:[:aColNr|
  1992         xOffset := xOffset + xInset + (self defaultColumnWidthAt:aColNr).
  2003 	xOffset := xOffset + xInset + (self defaultColumnWidthAt:aColNr).
  1993         xSplitbars at:(aColNr + 1) put:xOffset.
  2004 	xSplitbars at:(aColNr + 1) put:xOffset.
  1994     ].
  2005     ].
  1995     self splitbarsChanged
  2006     self splitbarsChanged
  1996 !
  2007 !
  1997 
  2008 
  1998 numberOfColumns
  2009 numberOfColumns
  2025 
  2036 
  2026 separatorOneDColor
  2037 separatorOneDColor
  2027     "answer the color used for drawing separators"
  2038     "answer the color used for drawing separators"
  2028 
  2039 
  2029     separatorOneDColor isNil ifTrue:[
  2040     separatorOneDColor isNil ifTrue:[
  2030         separatorOneDColor := self class separatorOneDColor.
  2041 	separatorOneDColor := self class separatorOneDColor.
  2031 
  2042 
  2032         (view notNil and:[view realized]) ifTrue:[
  2043 	(view notNil and:[view realized]) ifTrue:[
  2033             separatorOneDColor := separatorOneDColor onDevice:(view device).
  2044 	    separatorOneDColor := separatorOneDColor onDevice:(view device).
  2034         ].
  2045 	].
  2035     ].
  2046     ].
  2036     ^ separatorOneDColor
  2047     ^ separatorOneDColor
  2037 !
  2048 !
  2038 
  2049 
  2039 showHorizontalSeparators
  2050 showHorizontalSeparators
  2104      used to drag splitbars"
  2115      used to drag splitbars"
  2105 
  2116 
  2106     |xOld xNew xPrv deltaX xAbsoluteOfFirstSplitbar|
  2117     |xOld xNew xPrv deltaX xAbsoluteOfFirstSplitbar|
  2107 
  2118 
  2108     aSepIndex == 1 ifTrue:[
  2119     aSepIndex == 1 ifTrue:[
  2109         hasFixedItemWidth := true.
  2120 	hasFixedItemWidth := true.
  2110         xPrv := view margin.
  2121 	xPrv := view margin.
  2111     ] ifFalse:[
  2122     ] ifFalse:[
  2112         xPrv := xSplitbars at:(aSepIndex - 1).
  2123 	xPrv := xSplitbars at:(aSepIndex - 1).
  2113     ].
  2124     ].
  2114 
  2125 
  2115     aSepIndex == 1 ifTrue:[
  2126     aSepIndex == 1 ifTrue:[
  2116         hasFixedItemWidth := true.
  2127 	hasFixedItemWidth := true.
  2117         xPrv := view margin.
  2128 	xPrv := view margin.
  2118     ] ifFalse:[
  2129     ] ifFalse:[
  2119         xPrv := xSplitbars at:(aSepIndex - 1).
  2130 	xPrv := xSplitbars at:(aSepIndex - 1).
  2120     ].
  2131     ].
  2121     xOld := xSplitbars at:aSepIndex.
  2132     xOld := xSplitbars at:aSepIndex.
  2122     xNew := x max:xPrv.
  2133     xNew := x max:xPrv.
  2123 
  2134 
  2124     deltaX := xNew - xOld.
  2135     deltaX := xNew - xOld.
  2125     deltaX = 0 ifTrue:[ ^ self ].
  2136     deltaX = 0 ifTrue:[ ^ self ].
  2126 
  2137 
  2127     xAbsoluteOfFirstSplitbar := xSplitbars at:1.
  2138     xAbsoluteOfFirstSplitbar := xSplitbars at:1.
  2128 
  2139 
  2129     xSplitbars from:aSepIndex keysAndValuesDo:[:sepIdx :sepX|
  2140     xSplitbars from:aSepIndex keysAndValuesDo:[:sepIdx :sepX|
  2130         xSplitbars at:sepIdx put:(sepX + deltaX).
  2141 	xSplitbars at:sepIdx put:(sepX + deltaX).
  2131     ].
  2142     ].
  2132     view setWidthOfContents:(xSplitbars last).
  2143     view setWidthOfContents:(xSplitbars last).
  2133 
  2144 
  2134     view shown ifTrue:[
  2145     view shown ifTrue:[
  2135         |damage width height orgX|
  2146 	|damage width height orgX|
  2136 
  2147 
  2137         view windowGroup processRealExposeEventsFor:self.
  2148 	view windowGroup processRealExposeEventsFor:self.
  2138 
  2149 
  2139         width  := view width.
  2150 	width  := view width.
  2140         height := view height.
  2151 	height := view height.
  2141         orgX   := view viewOrigin x.
  2152 	orgX   := view viewOrigin x.
  2142 
  2153 
  2143         xNew := ((xNew - orgX) max:0) min:width.
  2154 	xNew := ((xNew - orgX) max:0) min:width.
  2144         xOld := ((xOld - orgX) max:0) min:width.
  2155 	xOld := ((xOld - orgX) max:0) min:width.
  2145         xPrv := ((xPrv - orgX) max:0) min:width.
  2156 	xPrv := ((xPrv - orgX) max:0) min:width.
  2146 
  2157 
  2147         xOld > xNew ifTrue:[                                    "/ <- copy to left
  2158 	xOld > xNew ifTrue:[                                    "/ <- copy to left
  2148             deltaX := xOld - xNew.
  2159 	    deltaX := xOld - xNew.
  2149 
  2160 
  2150             view copyFrom:view x:xOld y:0 toX:xNew y:0
  2161 	    view copyFrom:view x:xOld y:0 toX:xNew y:0
  2151                     width:(width - xOld) height:height.
  2162 		    width:(width - xOld) height:height.
  2152 
  2163 
  2153             damage := Rectangle left:(width - deltaX) top:0 width:deltaX height:height.
  2164 	    damage := Rectangle left:(width - deltaX) top:0 width:deltaX height:height.
  2154             view invalidateDeviceRectangle:damage repairNow:false.
  2165 	    view invalidateDeviceRectangle:damage repairNow:false.
  2155         ] ifFalse:[
  2166 	] ifFalse:[
  2156             xOld < xNew ifTrue:[                                "/ -> copy to right
  2167 	    xOld < xNew ifTrue:[                                "/ -> copy to right
  2157                 view copyFrom:view x:xOld y:0 toX:xNew y:0
  2168 		view copyFrom:view x:xOld y:0 toX:xNew y:0
  2158                         width:(width - xNew) height:height.
  2169 			width:(width - xNew) height:height.
  2159             ].
  2170 	    ].
  2160         ].
  2171 	].
  2161         xNew > xPrv ifTrue:[
  2172 	xNew > xPrv ifTrue:[
  2162             "/ should not invalidate the items display range..."
  2173 	    "/ should not invalidate the items display range..."
  2163 
  2174 
  2164             xAbsoluteOfFirstSplitbar := xAbsoluteOfFirstSplitbar - self splitbarInset.
  2175 	    xAbsoluteOfFirstSplitbar := xAbsoluteOfFirstSplitbar - self splitbarInset.
  2165             xPrv := (xPrv max:xAbsoluteOfFirstSplitbar).
  2176 	    xPrv := (xPrv max:xAbsoluteOfFirstSplitbar).
  2166 
  2177 
  2167             xNew > xPrv ifTrue:[
  2178 	    xNew > xPrv ifTrue:[
  2168                 damage := Rectangle left:xPrv top:0 width:(xNew -xPrv) height:height.
  2179 		damage := Rectangle left:xPrv top:0 width:(xNew -xPrv) height:height.
  2169                 view invalidateDeviceRectangle:damage repairNow:false.
  2180 		view invalidateDeviceRectangle:damage repairNow:false.
  2170             ].
  2181 	    ].
  2171         ].
  2182 	].
  2172     ].
  2183     ].
  2173     view contentsChanged.
  2184     view contentsChanged.
  2174 ! !
  2185 ! !
  2175 
  2186 
  2176 !ListModelView::TableRenderer methodsFor:'change & update'!
  2187 !ListModelView::TableRenderer methodsFor:'change & update'!
  2177 
  2188 
  2178 splitbarsChanged
  2189 splitbarsChanged
  2179     "called if the splitbars has changed; recompute the width of contents"
  2190     "called if the splitbars has changed; recompute the width of contents"
  2180 
  2191 
  2181     view notNil ifTrue:[
  2192     view notNil ifTrue:[
  2182         |newWidth oldWidth|
  2193 	|newWidth oldWidth|
  2183 
  2194 
  2184         oldWidth := view getWidthOfContents.
  2195 	oldWidth := view getWidthOfContents.
  2185 
  2196 
  2186         oldWidth notNil ifTrue:[
  2197 	oldWidth notNil ifTrue:[
  2187             newWidth := xSplitbars last.
  2198 	    newWidth := xSplitbars last.
  2188 
  2199 
  2189             newWidth ~= oldWidth ifTrue:[
  2200 	    newWidth ~= oldWidth ifTrue:[
  2190                 view setWidthOfContents:newWidth.
  2201 		view setWidthOfContents:newWidth.
  2191                 view contentsChanged.
  2202 		view contentsChanged.
  2192             ].
  2203 	    ].
  2193             view invalidate.
  2204 	    view invalidate.
  2194         ].
  2205 	].
  2195     ].
  2206     ].
  2196 !
  2207 !
  2197 
  2208 
  2198 withinUpdateFromListDo:aBlock
  2209 withinUpdateFromListDo:aBlock
  2199     "handle an change & update within the view"
  2210     "handle an change & update within the view"
  2202 
  2213 
  2203     xAbs := xSplitbars last.
  2214     xAbs := xSplitbars last.
  2204     super withinUpdateFromListDo:aBlock.
  2215     super withinUpdateFromListDo:aBlock.
  2205 
  2216 
  2206     xAbs ~~ xSplitbars last ifTrue:[
  2217     xAbs ~~ xSplitbars last ifTrue:[
  2207         self splitbarsChanged
  2218 	self splitbarsChanged
  2208     ].
  2219     ].
  2209 ! !
  2220 ! !
  2210 
  2221 
  2211 !ListModelView::TableRenderer methodsFor:'displaying'!
  2222 !ListModelView::TableRenderer methodsFor:'displaying'!
  2212 
  2223 
  2226     xNxt := xSplitbars first - xTrs.
  2237     xNxt := xSplitbars first - xTrs.
  2227 
  2238 
  2228     xNxt >= xMax ifTrue:[^ self].
  2239     xNxt >= xMax ifTrue:[^ self].
  2229 
  2240 
  2230     view hasSelection ifTrue:[
  2241     view hasSelection ifTrue:[
  2231         hgFgColor := view hilightForegroundColor.    
  2242 	hgFgColor := view hilightForegroundColor.
  2232         hgBgColor := view hilightBackgroundColor.
  2243 	hgBgColor := view hilightBackgroundColor.
  2233     ].
  2244     ].
  2234     fgColor := view foregroundColor.    
  2245     fgColor := view foregroundColor.
  2235     bgColor := view backgroundColor.
  2246     bgColor := view backgroundColor.
  2236     clip    := view clipRect.
  2247     clip    := view clipRect.
  2237 
  2248 
  2238     clip isNil ifTrue:[
  2249     clip isNil ifTrue:[
  2239         clip := Rectangle left:xDmg top:yStart width:wDmg height:(view height - yStart).
  2250 	clip := Rectangle left:xDmg top:yStart width:wDmg height:(view height - yStart).
  2240     ].
  2251     ].
  2241     colInset := self splitbarInset.
  2252     colInset := self splitbarInset.
  2242 
  2253 
  2243     2 to:numSplitbars do:[:anIndex|
  2254     2 to:numSplitbars do:[:anIndex|
  2244         |clipLft clipRgt colWdth colDesc|
  2255 	|clipLft clipRgt colWdth colDesc|
  2245 
  2256 
  2246         xNxt < xMax ifFalse:[^ self].
  2257 	xNxt < xMax ifFalse:[^ self].
  2247 
  2258 
  2248         x0   := xNxt.
  2259 	x0   := xNxt.
  2249         xNxt := (xSplitbars at:anIndex) - xTrs.
  2260 	xNxt := (xSplitbars at:anIndex) - xTrs.
  2250         x1   := xNxt.
  2261 	x1   := xNxt.
  2251 
  2262 
  2252         "/ workaround due to drawing the selection frame
  2263 	"/ workaround due to drawing the selection frame
  2253         anIndex == numSplitbars ifTrue:[ x1 := x1 + self textStartLeft ].
  2264 	anIndex == numSplitbars ifTrue:[ x1 := x1 + self textStartLeft ].
  2254 
  2265 
  2255         colDesc := columnDescriptors at:(anIndex - 1) ifAbsent:[ ^ self ].    "/ can give up...
  2266 	colDesc := columnDescriptors at:(anIndex - 1) ifAbsent:[ ^ self ].    "/ can give up...
  2256         clipLft := x0 max:xDmg.
  2267 	clipLft := x0 max:xDmg.
  2257         clipRgt := x1 min:xMax.
  2268 	clipRgt := x1 min:xMax.
  2258         colWdth := x1 - x0.
  2269 	colWdth := x1 - x0.
  2259 
  2270 
  2260         (colWdth > 2 and:[clipLft < clipRgt]) ifTrue:[
  2271 	(colWdth > 2 and:[clipLft < clipRgt]) ifTrue:[
  2261             clip := clip copy.
  2272 	    clip := clip copy.
  2262             clip setLeft:clipLft.
  2273 	    clip setLeft:clipLft.
  2263             clip right:clipRgt.
  2274 	    clip right:clipRgt.
  2264             view clippingRectangle:clip.
  2275 	    view clippingRectangle:clip.
  2265             y1 := yStart.
  2276 	    y1 := yStart.
  2266 
  2277 
  2267             start to:stop do:[:aRowNr| |recv|
  2278 	    start to:stop do:[:aRowNr| |recv|
  2268                 y0   := y1.
  2279 		y0   := y1.
  2269                 y1   := view yVisibleOfLine:(aRowNr + 1).
  2280 		y1   := view yVisibleOfLine:(aRowNr + 1).
  2270 
  2281 
  2271                 recv := receiver.
  2282 		recv := receiver.
  2272                 recv isNil ifTrue:[ recv := view at:aRowNr ifAbsent:nil ].
  2283 		recv isNil ifTrue:[ recv := view at:aRowNr ifAbsent:nil ].
  2273 
  2284 
  2274                 recv notNil ifTrue:[
  2285 		recv notNil ifTrue:[
  2275                     (hgFgColor notNil and:[view isInSelection:aRowNr]) ifTrue:[
  2286 		    (hgFgColor notNil and:[view isInSelection:aRowNr]) ifTrue:[
  2276                         shownSelected := true.
  2287 			shownSelected := true.
  2277                         view paint:hgFgColor on:hgBgColor
  2288 			view paint:hgFgColor on:hgBgColor
  2278                     ] ifFalse:[
  2289 		    ] ifFalse:[
  2279                         shownSelected := false.
  2290 			shownSelected := false.
  2280                         view paint:fgColor on:bgColor.
  2291 			view paint:fgColor on:bgColor.
  2281                     ].
  2292 		    ].
  2282                     colDesc
  2293 		    colDesc
  2283                         drawRowAt:aRowNr
  2294 			drawRowAt:aRowNr
  2284                         shownSelected:shownSelected
  2295 			shownSelected:shownSelected
  2285                         receiver:recv
  2296 			receiver:recv
  2286                         x:x0 + colInset
  2297 			x:x0 + colInset
  2287                         y:y0
  2298 			y:y0
  2288                         w:colWdth - colInset - colInset
  2299 			w:colWdth - colInset - colInset
  2289                         h:(y1 - y0) on:view.
  2300 			h:(y1 - y0) on:view.
  2290                 ].
  2301 		].
  2291             ].
  2302 	    ].
  2292         ].
  2303 	].
  2293     ].
  2304     ].
  2294 !
  2305 !
  2295 
  2306 
  2296 drawHorizontalSeparatorsX:x y:y w:w from:start to:stop
  2307 drawHorizontalSeparatorsX:x y:y w:w from:start to:stop
  2297     "draw horizontal seperators from start to stop.
  2308     "draw horizontal seperators from start to stop.
  2308     x1 <= x ifTrue:[^ self].
  2319     x1 <= x ifTrue:[^ self].
  2309 
  2320 
  2310     x0 := x.
  2321     x0 := x.
  2311 
  2322 
  2312     self showHorizontalSeparatorsForItem ifFalse:[
  2323     self showHorizontalSeparatorsForItem ifFalse:[
  2313         x0 := x0 max:(self xVisibleOfSplitbarAt:1).
  2324 	x0 := x0 max:(self xVisibleOfSplitbarAt:1).
  2314         x1 <= x0 ifTrue:[^ self].
  2325 	x1 <= x0 ifTrue:[^ self].
  2315     ].
  2326     ].
  2316     clipRec := Rectangle left:x0 top:0 right:x1 bottom:(view height).
  2327     clipRec := Rectangle left:x0 top:0 right:x1 bottom:(view height).
  2317 
  2328 
  2318     view clippingRectangle:clipRec.
  2329     view clippingRectangle:clipRec.
  2319     view paint:(self separatorOneDColor).
  2330     view paint:(self separatorOneDColor).
  2320 
  2331 
  2321     start to:stop do:[:aRowNr|
  2332     start to:stop do:[:aRowNr|
  2322         ySep := (view yVisibleOfLine:(aRowNr + 1)) - 1.
  2333 	ySep := (view yVisibleOfLine:(aRowNr + 1)) - 1.
  2323         view displayLineFromX:x0 y:ySep toX:x1 y:ySep.
  2334 	view displayLineFromX:x0 y:ySep toX:x1 y:ySep.
  2324     ].
  2335     ].
  2325 !
  2336 !
  2326 
  2337 
  2327 drawVerticalSplitbarsX:x0 y:y0 w:w from:start to:stop
  2338 drawVerticalSplitbarsX:x0 y:y0 w:w from:start to:stop
  2328     "draw vertical splitbars"
  2339     "draw vertical splitbars"
  2335     "/ workaround for textStartTop
  2346     "/ workaround for textStartTop
  2336 
  2347 
  2337     y1 := view height.
  2348     y1 := view height.
  2338 
  2349 
  2339     self showVerticalSplitbarsBelowContents ifFalse:[
  2350     self showVerticalSplitbarsBelowContents ifFalse:[
  2340         stop isNil ifTrue:[^ self].
  2351 	stop isNil ifTrue:[^ self].
  2341 
  2352 
  2342         y1 := y1 min:(view yVisibleOfLine:(stop + 1)).
  2353 	y1 := y1 min:(view yVisibleOfLine:(stop + 1)).
  2343         y1 <= y0 ifTrue:[ ^ self ].
  2354 	y1 <= y0 ifTrue:[ ^ self ].
  2344     ].
  2355     ].
  2345     x1 := x0 + w.
  2356     x1 := x0 + w.
  2346     vX := view viewOrigin x.
  2357     vX := view viewOrigin x.
  2347 
  2358 
  2348     xSplitbars keysAndValuesDo:[:anIndex :physY|
  2359     xSplitbars keysAndValuesDo:[:anIndex :physY|
  2349         (self showVerticalSplitbarAt:anIndex) ifTrue:[
  2360 	(self showVerticalSplitbarAt:anIndex) ifTrue:[
  2350             x := physY - vX.
  2361 	    x := physY - vX.
  2351             x > x1 ifTrue:[^ self]. "/ can giveup - behind max x1
  2362 	    x > x1 ifTrue:[^ self]. "/ can giveup - behind max x1
  2352 
  2363 
  2353             anIndex == nrOfSep ifTrue:[
  2364 	    anIndex == nrOfSep ifTrue:[
  2354                 "/ workaround due to drawing the selection frame
  2365 		"/ workaround due to drawing the selection frame
  2355                 x := x + self textStartLeft
  2366 		x := x + self textStartLeft
  2356             ].
  2367 	    ].
  2357             x >= x0  ifTrue:[
  2368 	    x >= x0  ifTrue:[
  2358                 clipRec isNil ifTrue:[
  2369 		clipRec isNil ifTrue:[
  2359                     "/ first time to setup clipping and colors
  2370 		    "/ first time to setup clipping and colors
  2360 
  2371 
  2361                     clipRec := Rectangle left:x0 top:y0 right:x1 bottom:y1.
  2372 		    clipRec := Rectangle left:x0 top:y0 right:x1 bottom:y1.
  2362                     view clippingRectangle:clipRec.
  2373 		    view clippingRectangle:clipRec.
  2363                     view paint:(self separatorOneDColor).
  2374 		    view paint:(self separatorOneDColor).
  2364                 ].
  2375 		].
  2365                 view displayLineFromX:x y:y0 toX:x y:y1.
  2376 		view displayLineFromX:x y:y0 toX:x y:y1.
  2366             ].
  2377 	    ].
  2367         ].
  2378 	].
  2368     ].
  2379     ].
  2369 !
  2380 !
  2370 
  2381 
  2371 postRedrawX:x y:y w:w from:start to:stop
  2382 postRedrawX:x y:y w:w from:start to:stop
  2372     "draw columns and than the splitbars"
  2383     "draw columns and than the splitbars"
  2373 
  2384 
  2374     self drawColumnsFrom:start to:stop x:x y:y w:w.
  2385     self drawColumnsFrom:start to:stop x:x y:y w:w.
  2375 
  2386 
  2376     self showHorizontalSeparators ifTrue:[
  2387     self showHorizontalSeparators ifTrue:[
  2377         self drawHorizontalSeparatorsX:x y:y w:w from:start to:stop.
  2388 	self drawHorizontalSeparatorsX:x y:y w:w from:start to:stop.
  2378     ].
  2389     ].
  2379     self showVerticalSplitbars ifTrue:[
  2390     self showVerticalSplitbars ifTrue:[
  2380         self drawVerticalSplitbarsX:x y:y w:w from:start to:stop.
  2391 	self drawVerticalSplitbarsX:x y:y w:w from:start to:stop.
  2381     ].
  2392     ].
  2382 !
  2393 !
  2383 
  2394 
  2384 validateDrawableItemsFrom:start to:stop
  2395 validateDrawableItemsFrom:start to:stop
  2385     "called before drawing the items in range from start to stop; the
  2396     "called before drawing the items in range from start to stop; the
  2402 
  2413 
  2403 !ListModelView::TableRenderer methodsFor:'enumerating'!
  2414 !ListModelView::TableRenderer methodsFor:'enumerating'!
  2404 
  2415 
  2405 columnDescriptorsDo:aOneArgBlock
  2416 columnDescriptorsDo:aOneArgBlock
  2406     columnDescriptors size > 0 ifTrue:[
  2417     columnDescriptors size > 0 ifTrue:[
  2407         columnDescriptors do:aOneArgBlock.
  2418 	columnDescriptors do:aOneArgBlock.
  2408     ].
  2419     ].
  2409 !
  2420 !
  2410 
  2421 
  2411 columnDescriptorsKeysAndValuesDo:aTwoArgBlock
  2422 columnDescriptorsKeysAndValuesDo:aTwoArgBlock
  2412 
  2423 
  2413     columnDescriptors size > 0 ifTrue:[
  2424     columnDescriptors size > 0 ifTrue:[
  2414         columnDescriptors keysAndValuesDo:aTwoArgBlock.
  2425 	columnDescriptors keysAndValuesDo:aTwoArgBlock.
  2415     ].
  2426     ].
  2416 !
  2427 !
  2417 
  2428 
  2418 xSplitbarsDo:aOneArgblock
  2429 xSplitbarsDo:aOneArgblock
  2419     "evaluate a block on each x splitbar position
  2430     "evaluate a block on each x splitbar position
  2433     "add event hook to window group"
  2444     "add event hook to window group"
  2434 
  2445 
  2435     |winGrp|
  2446     |winGrp|
  2436 
  2447 
  2437     view notNil ifTrue:[
  2448     view notNil ifTrue:[
  2438         winGrp := view windowGroup.
  2449 	winGrp := view windowGroup.
  2439 
  2450 
  2440         winGrp notNil ifTrue:[
  2451 	winGrp notNil ifTrue:[
  2441             view enableMotionEvents.
  2452 	    view enableMotionEvents.
  2442             winGrp addPreEventHook:self.
  2453 	    winGrp addPreEventHook:self.
  2443         ].        
  2454 	].
  2444     ].
  2455     ].
  2445 !
  2456 !
  2446 
  2457 
  2447 processEvent:ev
  2458 processEvent:ev
  2448     "only handled if drag splitbar is enabled"
  2459     "only handled if drag splitbar is enabled"
  2449 
  2460 
  2450     ev isInputEvent ifFalse:[^ false].
  2461     ev isInputEvent ifFalse:[^ false].
  2451 
  2462 
  2452     dragOperation notNil ifTrue:[
  2463     dragOperation notNil ifTrue:[
  2453         dragOperation value:ev.
  2464 	dragOperation value:ev.
  2454         ^ true
  2465 	^ true
  2455     ].
  2466     ].
  2456 
  2467 
  2457     (view shown
  2468     (view shown
  2458     and:[ev view == view
  2469     and:[ev view == view
  2459     and:[(ev isButtonPressEvent or:[ev isButtonMotionEvent])
  2470     and:[(ev isButtonPressEvent or:[ev isButtonMotionEvent])
  2460     and:[((ev button == 2) or:[ev button == #menu]) not]]]) ifTrue:[
  2471     and:[((ev button == 2) or:[ev button == #menu]) not]]]) ifTrue:[
  2461         |colIndex phyX colX|
  2472 	|colIndex phyX colX|
  2462 
  2473 
  2463         colIndex := self xVisibleToSplitbar:(ev x).
  2474 	colIndex := self xVisibleToSplitbar:(ev x).
  2464 
  2475 
  2465         (colIndex > 0 and:[self showVerticalSplitbarsBelowContents not]) ifTrue:[
  2476 	(colIndex > 0 and:[self showVerticalSplitbarsBelowContents not]) ifTrue:[
  2466             "/ test whether y is below contents....
  2477 	    "/ test whether y is below contents....
  2467             ev y > (view heightOfContents - view viewOrigin y) ifTrue:[
  2478 	    ev y > (view heightOfContents - view viewOrigin y) ifTrue:[
  2468                 colIndex := 0
  2479 		colIndex := 0
  2469             ].
  2480 	    ].
  2470         ].
  2481 	].
  2471 
  2482 
  2472         ev isButtonPressEvent ifTrue:[
  2483 	ev isButtonPressEvent ifTrue:[
  2473             colIndex < 1 ifTrue:[^ false].
  2484 	    colIndex < 1 ifTrue:[^ false].
  2474 
  2485 
  2475             colX := self xAbsoluteOfSplitbarAt:colIndex.
  2486 	    colX := self xAbsoluteOfSplitbarAt:colIndex.
  2476             phyX := ev x.
  2487 	    phyX := ev x.
  2477 
  2488 
  2478             dragOperation := [:event|
  2489 	    dragOperation := [:event|
  2479                 event isKeyEvent ifTrue:[
  2490 		event isKeyEvent ifTrue:[
  2480                     event rawKey == #Escape ifTrue:[
  2491 		    event rawKey == #Escape ifTrue:[
  2481                         dragOperation := nil.
  2492 			dragOperation := nil.
  2482                         self moveSplitbarAt:colIndex toAbsoluteX:colX.
  2493 			self moveSplitbarAt:colIndex toAbsoluteX:colX.
  2483                     ].
  2494 		    ].
  2484                 ] ifFalse:[
  2495 		] ifFalse:[
  2485                     event isButtonPressEvent ifTrue:[
  2496 		    event isButtonPressEvent ifTrue:[
  2486                         dragOperation := nil.
  2497 			dragOperation := nil.
  2487                         self moveSplitbarAt:colIndex toAbsoluteX:colX.
  2498 			self moveSplitbarAt:colIndex toAbsoluteX:colX.
  2488                     ].
  2499 		    ].
  2489                     event isButtonReleaseEvent ifTrue:[
  2500 		    event isButtonReleaseEvent ifTrue:[
  2490                         dragOperation := nil.
  2501 			dragOperation := nil.
  2491                     ].
  2502 		    ].
  2492                     event isButtonMotionEvent ifTrue:[
  2503 		    event isButtonMotionEvent ifTrue:[
  2493                         (view sensor hasExposeEventFor:nil) ifFalse:[
  2504 			(view sensor hasExposeEventFor:nil) ifFalse:[
  2494                             self
  2505 			    self
  2495                                 moveSplitbarAt:colIndex
  2506 				moveSplitbarAt:colIndex
  2496                                 toAbsoluteX:(colX + (event x) - phyX).
  2507 				toAbsoluteX:(colX + (event x) - phyX).
  2497                         ].
  2508 			].
  2498                     ].
  2509 		    ].
  2499                 ].
  2510 		].
  2500             ].
  2511 	    ].
  2501             ^ true
  2512 	    ^ true
  2502         ].
  2513 	].
  2503 
  2514 
  2504         colIndex == 0 ifTrue:[
  2515 	colIndex == 0 ifTrue:[
  2505             savedCursor notNil ifTrue:[
  2516 	    savedCursor notNil ifTrue:[
  2506                 view cursor:savedCursor.
  2517 		view cursor:savedCursor.
  2507                 savedCursor := nil.
  2518 		savedCursor := nil.
  2508             ].
  2519 	    ].
  2509         ] ifFalse:[
  2520 	] ifFalse:[
  2510             savedCursor isNil ifTrue:[
  2521 	    savedCursor isNil ifTrue:[
  2511                 savedCursor := view cursor.
  2522 		savedCursor := view cursor.
  2512                 view cursor:dragCursor.
  2523 		view cursor:dragCursor.
  2513             ].
  2524 	    ].
  2514         ].
  2525 	].
  2515     ].
  2526     ].
  2516     ^ false
  2527     ^ false
  2517 !
  2528 !
  2518 
  2529 
  2519 removeEventHook
  2530 removeEventHook
  2520     "release my event hook"
  2531     "release my event hook"
  2521 
  2532 
  2522     |winGrp|
  2533     |winGrp|
  2523 
  2534 
  2524     view notNil ifTrue:[
  2535     view notNil ifTrue:[
  2525         winGrp := view windowGroup.
  2536 	winGrp := view windowGroup.
  2526         winGrp notNil ifTrue:[ winGrp removePreEventHook:self ].        
  2537 	winGrp notNil ifTrue:[ winGrp removePreEventHook:self ].
  2527     ].
  2538     ].
  2528 ! !
  2539 ! !
  2529 
  2540 
  2530 !ListModelView::TableRenderer methodsFor:'instance creation'!
  2541 !ListModelView::TableRenderer methodsFor:'instance creation'!
  2531 
  2542 
  2532 forView:aView
  2543 forView:aView
  2533     "setup instance for a view;
  2544     "setup instance for a view;
  2534      setup my default columnDescription"
  2545      setup my default columnDescription"
  2535 
  2546 
  2536     attributes isNil ifTrue:[
  2547     attributes isNil ifTrue:[
  2537         attributes := IdentityDictionary new.
  2548 	attributes := IdentityDictionary new.
  2538     ].
  2549     ].
  2539     self columnDescriptors:nil.
  2550     self columnDescriptors:nil.
  2540     super forView:aView.
  2551     super forView:aView.
  2541 !
  2552 !
  2542 
  2553 
  2543 mapped
  2554 mapped
  2544     "install event hook and enable motion events
  2555     "install event hook and enable motion events
  2545     "
  2556     "
  2546     view notNil ifTrue:[
  2557     view notNil ifTrue:[
  2547         dragCursor isNil ifTrue:[
  2558 	dragCursor isNil ifTrue:[
  2548             dragCursor := self class dragCursor onDevice:(view device).
  2559 	    dragCursor := self class dragCursor onDevice:(view device).
  2549         ].
  2560 	].
  2550         separatorOneDColor notNil ifTrue:[
  2561 	separatorOneDColor notNil ifTrue:[
  2551             separatorOneDColor := separatorOneDColor onDevice:(view device).
  2562 	    separatorOneDColor := separatorOneDColor onDevice:(view device).
  2552         ].
  2563 	].
  2553         self isDragEnabled ifTrue:[ self addEventHook ].
  2564 	self isDragEnabled ifTrue:[ self addEventHook ].
  2554     ].
  2565     ].
  2555 !
  2566 !
  2556 
  2567 
  2557 release
  2568 release
  2558     "release event hook
  2569     "release event hook
  2570 defaultColumnWidthAt:aColIndex
  2581 defaultColumnWidthAt:aColIndex
  2571     ^ (columnDescriptors at:aColIndex) defaultColumnWidth
  2582     ^ (columnDescriptors at:aColIndex) defaultColumnWidth
  2572 !
  2583 !
  2573 
  2584 
  2574 showVerticalSplitbarAt:aColIndex
  2585 showVerticalSplitbarAt:aColIndex
  2575     aColIndex > 1 ifTrue:[ 
  2586     aColIndex > 1 ifTrue:[
  2576         ^ (columnDescriptors at:(aColIndex - 1)) showVerticalSplitbar
  2587 	^ (columnDescriptors at:(aColIndex - 1)) showVerticalSplitbar
  2577     ].
  2588     ].
  2578     ^ true
  2589     ^ true
  2579 ! !
  2590 ! !
  2580 
  2591 
  2581 !ListModelView::TableRenderer methodsFor:'queries-behavior'!
  2592 !ListModelView::TableRenderer methodsFor:'queries-behavior'!
  2590     "answer true if drag of separators is enabled"
  2601     "answer true if drag of separators is enabled"
  2591 
  2602 
  2592     attributes at:#isDragEnabled put:aBoolean.
  2603     attributes at:#isDragEnabled put:aBoolean.
  2593 
  2604 
  2594     aBoolean ifTrue:[ self addEventHook ]
  2605     aBoolean ifTrue:[ self addEventHook ]
  2595             ifFalse:[ self removeEventHook ].
  2606 	    ifFalse:[ self removeEventHook ].
  2596 ! !
  2607 ! !
  2597 
  2608 
  2598 !ListModelView::TableRenderer methodsFor:'queries-dimensions'!
  2609 !ListModelView::TableRenderer methodsFor:'queries-dimensions'!
  2599 
  2610 
  2600 heightFor:anItem
  2611 heightFor:anItem
  2625     |xStart xStop xDiff inset|
  2636     |xStart xStop xDiff inset|
  2626 
  2637 
  2627     xStart := view xAbsoluteOfItem:anItem.
  2638     xStart := view xAbsoluteOfItem:anItem.
  2628 
  2639 
  2629     hasFixedItemWidth ifFalse:[
  2640     hasFixedItemWidth ifFalse:[
  2630         inset := self splitbarInset.
  2641 	inset := self splitbarInset.
  2631         xStop := (anItem widthOn:view) + xStart + inset + inset.
  2642 	xStop := (anItem widthOn:view) + xStart + inset + inset.
  2632         xDiff := xStop - xSplitbars first.
  2643 	xDiff := xStop - xSplitbars first.
  2633 
  2644 
  2634         xDiff > 0 ifTrue:[
  2645 	xDiff > 0 ifTrue:[
  2635             xDiff := xDiff + 10.        "/ add more to have less computation
  2646 	    xDiff := xDiff + 10.        "/ add more to have less computation
  2636             xSplitbars := xSplitbars collect:[:xSep| xSep + xDiff ].
  2647 	    xSplitbars := xSplitbars collect:[:xSep| xSep + xDiff ].
  2637         ].
  2648 	].
  2638     ].
  2649     ].
  2639     ^ xSplitbars last - xStart
  2650     ^ xSplitbars last - xStart
  2640 !
  2651 !
  2641 
  2652 
  2642 widthOfColumn:aColumn
  2653 widthOfColumn:aColumn
  2645     |index x0 x1|
  2656     |index x0 x1|
  2646 
  2657 
  2647     index := columnDescriptors identityIndexOf:aColumn.
  2658     index := columnDescriptors identityIndexOf:aColumn.
  2648 
  2659 
  2649     index > 0 ifTrue:[
  2660     index > 0 ifTrue:[
  2650         (     (x0 := xSplitbars at:index       ifAbsent:nil) notNil
  2661 	(     (x0 := xSplitbars at:index       ifAbsent:nil) notNil
  2651          and:[(x1 := xSplitbars at:(index + 1) ifAbsent:nil) notNil])
  2662 	 and:[(x1 := xSplitbars at:(index + 1) ifAbsent:nil) notNil])
  2652         ifTrue:[
  2663 	ifTrue:[
  2653             ^ (x1 - x0 - (2 * (self splitbarInset))) max:0
  2664 	    ^ (x1 - x0 - (2 * (self splitbarInset))) max:0
  2654         ].
  2665 	].
  2655     ].
  2666     ].
  2656     ^ nil
  2667     ^ nil
  2657 !
  2668 !
  2658 
  2669 
  2659 widthOfItemColumn
  2670 widthOfItemColumn
  2667     "returns the width of the longest line in pixels in a range
  2678     "returns the width of the longest line in pixels in a range
  2668     "
  2679     "
  2669     |item|
  2680     |item|
  2670 
  2681 
  2671     hasFixedItemWidth ifFalse:[
  2682     hasFixedItemWidth ifFalse:[
  2672         firstLine to:lastLine do:[:i|
  2683 	firstLine to:lastLine do:[:i|
  2673             item := view at:i ifAbsent:nil.
  2684 	    item := view at:i ifAbsent:nil.
  2674             item notNil ifTrue:[self widthFor:item].
  2685 	    item notNil ifTrue:[self widthFor:item].
  2675         ].
  2686 	].
  2676     ].
  2687     ].
  2677     ^ xSplitbars last
  2688     ^ xSplitbars last
  2678 !
  2689 !
  2679 
  2690 
  2680 xAbsoluteOfSplitbarAt:anIndex
  2691 xAbsoluteOfSplitbarAt:anIndex
  2692     minX  := absX - 2.
  2703     minX  := absX - 2.
  2693     maxX  := absX + 2.
  2704     maxX  := absX + 2.
  2694 
  2705 
  2695     "/ must walk reverse because a column could have a zero width
  2706     "/ must walk reverse because a column could have a zero width
  2696     xSplitbars keysAndValuesReverseDo:[:index :x|
  2707     xSplitbars keysAndValuesReverseDo:[:index :x|
  2697         (x between:minX and:maxX) ifTrue:[^ index].
  2708 	(x between:minX and:maxX) ifTrue:[^ index].
  2698     ].
  2709     ].
  2699     ^ 0
  2710     ^ 0
  2700 !
  2711 !
  2701 
  2712 
  2702 xVisibleOfLastSplitbar
  2713 xVisibleOfLastSplitbar
  2727     ^ self new dataSetColumnSpec:aDataSetColumnSpec
  2738     ^ self new dataSetColumnSpec:aDataSetColumnSpec
  2728 !
  2739 !
  2729 
  2740 
  2730 new
  2741 new
  2731     ClipColumnQuerySignal isNil ifTrue:[
  2742     ClipColumnQuerySignal isNil ifTrue:[
  2732         ClipColumnQuerySignal := QuerySignal new.
  2743 	ClipColumnQuerySignal := QuerySignal new.
  2733     ].
  2744     ].
  2734     ^ self basicNew initialize
  2745     ^ self basicNew initialize
  2735 ! !
  2746 ! !
  2736 
  2747 
  2737 !ListModelView::TableRenderer::ColumnDescriptor methodsFor:'accessing'!
  2748 !ListModelView::TableRenderer::ColumnDescriptor methodsFor:'accessing'!
  2750 !
  2761 !
  2751 
  2762 
  2752 dataSetColumnSpec:aDataSetColumnSpec
  2763 dataSetColumnSpec:aDataSetColumnSpec
  2753 
  2764 
  2754     aDataSetColumnSpec isSequenceable ifTrue:[
  2765     aDataSetColumnSpec isSequenceable ifTrue:[
  2755         dataSetColumnSpec := DataSetColumnSpec decodeFromLiteralArray:aDataSetColumnSpec.
  2766 	dataSetColumnSpec := DataSetColumnSpec decodeFromLiteralArray:aDataSetColumnSpec.
  2756     ] ifFalse:[
  2767     ] ifFalse:[
  2757         dataSetColumnSpec := aDataSetColumnSpec.
  2768 	dataSetColumnSpec := aDataSetColumnSpec.
  2758     ].
  2769     ].
  2759 !
  2770 !
  2760 
  2771 
  2761 defaultColumnWidth
  2772 defaultColumnWidth
  2762     |width|
  2773     |width|
  2783     "display a column for a specific row"
  2794     "display a column for a specific row"
  2784 
  2795 
  2785     |deviceClipRectangle paint savedPaint label|
  2796     |deviceClipRectangle paint savedPaint label|
  2786 
  2797 
  2787     isShownSelected ifFalse:[
  2798     isShownSelected ifFalse:[
  2788         "/ draw the background color if required by spec..
  2799 	"/ draw the background color if required by spec..
  2789         paint := self extractBackgroundColorFrom:aReceiver rowNr:aRowNr on:aGC.
  2800 	paint := self extractBackgroundColorFrom:aReceiver rowNr:aRowNr on:aGC.
  2790 
  2801 
  2791         paint notNil ifTrue:[
  2802 	paint notNil ifTrue:[
  2792             savedPaint := aGC paint.
  2803 	    savedPaint := aGC paint.
  2793             aGC paint:paint.
  2804 	    aGC paint:paint.
  2794             "/ splitbarInset - draw from 0 to width of aGC (is clipped)
  2805 	    "/ splitbarInset - draw from 0 to width of aGC (is clipped)
  2795             aGC fillRectangleX:0 y:y width:(aGC width) height:h.
  2806 	    aGC fillRectangleX:0 y:y width:(aGC width) height:h.
  2796         ].
  2807 	].
  2797     ].
  2808     ].
  2798     w < 5 ifTrue:[ ^ self ].    "/ makes no sense to draw the label
  2809     w < 5 ifTrue:[ ^ self ].    "/ makes no sense to draw the label
  2799 
  2810 
  2800     label := self extractColumnFrom:aReceiver rowNr:aRowNr on:aGC.
  2811     label := self extractColumnFrom:aReceiver rowNr:aRowNr on:aGC.
  2801     label isEmptyOrNil ifTrue:[^ self].
  2812     label isEmptyOrNil ifTrue:[^ self].
  2802 
  2813 
  2803     ClipColumnQuerySignal handle:[:ex|
  2814     ClipColumnQuerySignal handle:[:ex|
  2804         deviceClipRectangle isNil ifTrue:[
  2815 	deviceClipRectangle isNil ifTrue:[
  2805             deviceClipRectangle := aGC clippingRectangleOrNil.
  2816 	    deviceClipRectangle := aGC clippingRectangleOrNil.
  2806             aGC clippingRectangle:(Rectangle left:x top:y width:w height:h).
  2817 	    aGC clippingRectangle:(Rectangle left:x top:y width:w height:h).
  2807         ].
  2818 	].
  2808         ex proceedWith:true.
  2819 	ex proceedWith:true.
  2809     ] do:[
  2820     ] do:[
  2810         isShownSelected ifFalse:[
  2821 	isShownSelected ifFalse:[
  2811             paint := self extractForegroundColorFrom:aReceiver rowNr:aRowNr on:aGC.
  2822 	    paint := self extractForegroundColorFrom:aReceiver rowNr:aRowNr on:aGC.
  2812 
  2823 
  2813             paint notNil ifTrue:[
  2824 	    paint notNil ifTrue:[
  2814                 aGC paint:paint.
  2825 		aGC paint:paint.
  2815             ] ifFalse:[
  2826 	    ] ifFalse:[
  2816                 savedPaint notNil ifTrue:[ aGC paint:savedPaint ].
  2827 		savedPaint notNil ifTrue:[ aGC paint:savedPaint ].
  2817             ].        
  2828 	    ].
  2818         ].
  2829 	].
  2819         self drawObject:label x:x y:y w:w h:h on:aGC.
  2830 	self drawObject:label x:x y:y w:w h:h on:aGC.
  2820     ].
  2831     ].
  2821     deviceClipRectangle notNil ifTrue:[
  2832     deviceClipRectangle notNil ifTrue:[
  2822         aGC deviceClippingRectangle:deviceClipRectangle.
  2833 	aGC deviceClippingRectangle:deviceClipRectangle.
  2823     ].
  2834     ].
  2824 ! !
  2835 ! !
  2825 
  2836 
  2826 !ListModelView::TableRenderer::ColumnDescriptor methodsFor:'extract values'!
  2837 !ListModelView::TableRenderer::ColumnDescriptor methodsFor:'extract values'!
  2827 
  2838 
  2828 extractBackgroundColorFrom:aReceiver rowNr:aRowNr on:aView
  2839 extractBackgroundColorFrom:aReceiver rowNr:aRowNr on:aView
  2829     |color selector|
  2840     |color selector|
  2830 
  2841 
  2831     aReceiver notNil ifTrue:[
  2842     aReceiver notNil ifTrue:[
  2832         selector := dataSetColumnSpec backgroundSelector.
  2843 	selector := dataSetColumnSpec backgroundSelector.
  2833 
  2844 
  2834         selector notNil ifTrue:[
  2845 	selector notNil ifTrue:[
  2835             color := aReceiver perform:selector withOptionalArgument:columnNumber and:aRowNr and:aView.
  2846 	    color := aReceiver perform:selector withOptionalArgument:columnNumber and:aRowNr and:aView.
  2836             color notNil ifTrue:[ ^ color ].
  2847 	    color notNil ifTrue:[ ^ color ].
  2837         ].
  2848 	].
  2838     ].
  2849     ].
  2839     ^ dataSetColumnSpec backgroundColor.
  2850     ^ dataSetColumnSpec backgroundColor.
  2840 !
  2851 !
  2841 
  2852 
  2842 extractColumnFrom:aReceiver rowNr:aRowNr on:aView
  2853 extractColumnFrom:aReceiver rowNr:aRowNr on:aView
  2843     |selector|
  2854     |selector|
  2844 
  2855 
  2845     aReceiver notNil ifTrue:[
  2856     aReceiver notNil ifTrue:[
  2846         selector := dataSetColumnSpec readSelector.
  2857 	selector := dataSetColumnSpec readSelector.
  2847 
  2858 
  2848         selector notNil ifTrue:[
  2859 	selector notNil ifTrue:[
  2849             ^ aReceiver perform:selector withOptionalArgument:columnNumber and:aRowNr and:aView 
  2860 	    ^ aReceiver perform:selector withOptionalArgument:columnNumber and:aRowNr and:aView
  2850         ].
  2861 	].
  2851     ].
  2862     ].
  2852     ^ nil
  2863     ^ nil
  2853 !
  2864 !
  2854 
  2865 
  2855 extractForegroundColorFrom:aReceiver rowNr:aRowNr on:aView
  2866 extractForegroundColorFrom:aReceiver rowNr:aRowNr on:aView
  2856     |color selector|
  2867     |color selector|
  2857 
  2868 
  2858     aReceiver notNil ifTrue:[
  2869     aReceiver notNil ifTrue:[
  2859         selector := dataSetColumnSpec foregroundSelector.
  2870 	selector := dataSetColumnSpec foregroundSelector.
  2860 
  2871 
  2861         selector notNil ifTrue:[
  2872 	selector notNil ifTrue:[
  2862             color := aReceiver perform:selector withOptionalArgument:columnNumber and:aRowNr and:aView.
  2873 	    color := aReceiver perform:selector withOptionalArgument:columnNumber and:aRowNr and:aView.
  2863             color notNil ifTrue:[ ^ color ].
  2874 	    color notNil ifTrue:[ ^ color ].
  2864         ].
  2875 	].
  2865     ].
  2876     ].
  2866     ^ dataSetColumnSpec foregroundColor.
  2877     ^ dataSetColumnSpec foregroundColor.
  2867 ! !
  2878 ! !
  2868 
  2879 
  2869 !ListModelView::TableRenderer::ColumnDescriptor methodsFor:'instance creation'!
  2880 !ListModelView::TableRenderer::ColumnDescriptor methodsFor:'instance creation'!
  2881 
  2892 
  2882     x0    := x.
  2893     x0    := x.
  2883     align := self alignment.
  2894     align := self alignment.
  2884 
  2895 
  2885     align ~~ #left ifTrue:[
  2896     align ~~ #left ifTrue:[
  2886         width := anObject widthOn:aGC.
  2897 	width := anObject widthOn:aGC.
  2887 
  2898 
  2888         width < w ifTrue:[
  2899 	width < w ifTrue:[
  2889             align == #right ifTrue:[
  2900 	    align == #right ifTrue:[
  2890                 x0 := x0 + w - width
  2901 		x0 := x0 + w - width
  2891             ] ifFalse:[
  2902 	    ] ifFalse:[
  2892                 x0 := x0 + ((w - width) // 2)
  2903 		x0 := x0 + ((w - width) // 2)
  2893             ].
  2904 	    ].
  2894         ].
  2905 	].
  2895     ].
  2906     ].
  2896     anObject displayOn:aGC x:x0 y:y.
  2907     anObject displayOn:aGC x:x0 y:y.
  2897 !
  2908 !
  2898 
  2909 
  2899 displayImage:anImage x:x y:y w:w h:h on:aGC
  2910 displayImage:anImage x:x y:y w:w h:h on:aGC
  2902     |height|
  2913     |height|
  2903 
  2914 
  2904     height := anImage heightOn:aGC.
  2915     height := anImage heightOn:aGC.
  2905 
  2916 
  2906     height > h ifTrue:[
  2917     height > h ifTrue:[
  2907         (self queryForClipColumnWithAvailableHeight:h) ifFalse:[
  2918 	(self queryForClipColumnWithAvailableHeight:h) ifFalse:[
  2908             ^ height
  2919 	    ^ height
  2909         ].
  2920 	].
  2910     ].
  2921     ].
  2911     self alignAndDisplay:anImage x:x y:y w:w on:aGC.
  2922     self alignAndDisplay:anImage x:x y:y w:w on:aGC.
  2912     ^ height
  2923     ^ height
  2913 !
  2924 !
  2914 
  2925 
  2918     |height|
  2929     |height|
  2919 
  2930 
  2920     height := aLabelAndIcon heightOn:aGC.
  2931     height := aLabelAndIcon heightOn:aGC.
  2921 
  2932 
  2922     height > h ifTrue:[
  2933     height > h ifTrue:[
  2923         (self queryForClipColumnWithAvailableHeight:h) ifFalse:[
  2934 	(self queryForClipColumnWithAvailableHeight:h) ifFalse:[
  2924             ^ height
  2935 	    ^ height
  2925         ].
  2936 	].
  2926     ].
  2937     ].
  2927 
  2938 
  2928     self alignAndDisplay:aLabelAndIcon x:x y:(y + aGC font ascent) w:w on:aGC.
  2939     self alignAndDisplay:aLabelAndIcon x:x y:(y + aGC font ascent) w:w on:aGC.
  2929     ^ height
  2940     ^ height
  2930 !
  2941 !
  2938     fontHeight := font height.
  2949     fontHeight := font height.
  2939 
  2950 
  2940     aString isEmptyOrNil ifTrue:[ ^ fontHeight ].
  2951     aString isEmptyOrNil ifTrue:[ ^ fontHeight ].
  2941 
  2952 
  2942     (self queryForClipColumnWithAvailableHeight:h) ifFalse:[
  2953     (self queryForClipColumnWithAvailableHeight:h) ifFalse:[
  2943         ^ fontHeight
  2954 	^ fontHeight
  2944     ].
  2955     ].
  2945     dataSetColumnSpec longStringCompression ifTrue:[
  2956     dataSetColumnSpec longStringCompression ifTrue:[
  2946         shortWidth := font widthOf:aString.
  2957 	shortWidth := font widthOf:aString.
  2947 
  2958 
  2948         shortWidth <= w ifTrue:[
  2959 	shortWidth <= w ifTrue:[
  2949             shortedLabel := aString.
  2960 	    shortedLabel := aString.
  2950         ] ifFalse:[
  2961 	] ifFalse:[
  2951             |dottedString dottedWidth index|
  2962 	    |dottedString dottedWidth index|
  2952 
  2963 
  2953             dottedString := '...'.
  2964 	    dottedString := '...'.
  2954             dottedWidth  := font widthOf:dottedString.
  2965 	    dottedWidth  := font widthOf:dottedString.
  2955 
  2966 
  2956             w < dottedWidth ifTrue:[ ^ fontHeight ].   "/ give up
  2967 	    w < dottedWidth ifTrue:[ ^ fontHeight ].   "/ give up
  2957 
  2968 
  2958             index := aString size // 2.
  2969 	    index := aString size // 2.
  2959 
  2970 
  2960             [   index := index - 1.
  2971 	    [   index := index - 1.
  2961 
  2972 
  2962                 index > 0 ifTrue:[
  2973 		index > 0 ifTrue:[
  2963                     shortedLabel := (aString copyFirst:index), '...', (aString copyLast:index).
  2974 		    shortedLabel := (aString copyFirst:index), '...', (aString copyLast:index).
  2964                     shortWidth   := font widthOf:shortedLabel.
  2975 		    shortWidth   := font widthOf:shortedLabel.
  2965                 ] ifFalse:[
  2976 		] ifFalse:[
  2966                     shortedLabel := dottedString.
  2977 		    shortedLabel := dottedString.
  2967                     shortWidth   := dottedWidth.
  2978 		    shortWidth   := dottedWidth.
  2968                 ].
  2979 		].
  2969                 shortWidth > w
  2980 		shortWidth > w
  2970             ] whileTrue.
  2981 	    ] whileTrue.
  2971         ].
  2982 	].
  2972     ] ifFalse:[
  2983     ] ifFalse:[
  2973         shortedLabel := aString
  2984 	shortedLabel := aString
  2974     ].
  2985     ].
  2975 
  2986 
  2976     shortedLabel notNil ifTrue:[
  2987     shortedLabel notNil ifTrue:[
  2977         self alignAndDisplay:shortedLabel x:x y:(y + aGC font ascent) w:w on:aGC.
  2988 	self alignAndDisplay:shortedLabel x:x y:(y + aGC font ascent) w:w on:aGC.
  2978     ].
  2989     ].
  2979     ^ fontHeight.
  2990     ^ fontHeight.
  2980 !
  2991 !
  2981 
  2992 
  2982 drawObject:anObject x:x y:y w:w h:h on:aGC
  2993 drawObject:anObject x:x y:y w:w h:h on:aGC
  2987     h < 4 ifTrue:[ ^ h ].
  2998     h < 4 ifTrue:[ ^ h ].
  2988 
  2999 
  2989     anObject isEmptyOrNil ifTrue:[ ^ 2 ]. "/ nothing to draw; add 2 pixels
  3000     anObject isEmptyOrNil ifTrue:[ ^ 2 ]. "/ nothing to draw; add 2 pixels
  2990 
  3001 
  2991     anObject isImage ifTrue:[
  3002     anObject isImage ifTrue:[
  2992         ^ self displayImage:anObject x:x y:y w:w h:h on:aGC.
  3003 	^ self displayImage:anObject x:x y:y w:w h:h on:aGC.
  2993     ].
  3004     ].
  2994     anObject isString ifTrue:[
  3005     anObject isString ifTrue:[
  2995         ^ self displayString:anObject x:x y:y w:w h:h on:aGC.
  3006 	^ self displayString:anObject x:x y:y w:w h:h on:aGC.
  2996     ].        
  3007     ].
  2997     anObject isSequenceable ifFalse:[
  3008     anObject isSequenceable ifFalse:[
  2998         "/ not yet handled....
  3009 	"/ not yet handled....
  2999         anObject class == LabelAndIcon ifTrue:[
  3010 	anObject class == LabelAndIcon ifTrue:[
  3000             ^ self displayLabelAndIcon:anObject x:x y:y w:w h:h on:aGC
  3011 	    ^ self displayLabelAndIcon:anObject x:x y:y w:w h:h on:aGC
  3001         ].
  3012 	].
  3002 
  3013 
  3003         ^ self displayString:(anObject printString) x:x y:y w:w h:h on:aGC
  3014 	^ self displayString:(anObject printString) x:x y:y w:w h:h on:aGC
  3004     ].
  3015     ].
  3005 
  3016 
  3006     totalHeight := 0.
  3017     totalHeight := 0.
  3007 
  3018 
  3008     anObject do:[:aSubObj|
  3019     anObject do:[:aSubObj|
  3009         totalHeight < h ifTrue:[
  3020 	totalHeight < h ifTrue:[
  3010             usedHeight := self
  3021 	    usedHeight := self
  3011                     drawObject:aSubObj
  3022 		    drawObject:aSubObj
  3012                     x:x
  3023 		    x:x
  3013                     y:(y + totalHeight)
  3024 		    y:(y + totalHeight)
  3014                     w:w
  3025 		    w:w
  3015                     h:(h - totalHeight)
  3026 		    h:(h - totalHeight)
  3016                     on:aGC.
  3027 		    on:aGC.
  3017 
  3028 
  3018             totalHeight := totalHeight + usedHeight.
  3029 	    totalHeight := totalHeight + usedHeight.
  3019         ].
  3030 	].
  3020     ].
  3031     ].
  3021     ^ (h - totalHeight)
  3032     ^ (h - totalHeight)
  3022 !
  3033 !
  3023 
  3034 
  3024 queryForClipColumnWithAvailableHeight:anAvailableHeight
  3035 queryForClipColumnWithAvailableHeight:anAvailableHeight
  3025 
  3036 
  3026     anAvailableHeight > 8 ifTrue:[
  3037     anAvailableHeight > 8 ifTrue:[
  3027         ^ (ClipColumnQuerySignal query) == true
  3038 	^ (ClipColumnQuerySignal query) == true
  3028     ].
  3039     ].
  3029     ^ false.
  3040     ^ false.
  3030 ! !
  3041 ! !
  3031 
  3042 
  3032 !ListModelView class methodsFor:'documentation'!
  3043 !ListModelView class methodsFor:'documentation'!
  3033 
  3044 
  3034 version
  3045 version
  3035     ^ '$Header: /cvs/stx/stx/libwidg2/ListModelView.st,v 1.117 2009-07-20 13:25:27 ca Exp $'
  3046     ^ '$Header: /cvs/stx/stx/libwidg2/ListModelView.st,v 1.118 2009-08-07 10:50:41 sr Exp $'
  3036 ! !
  3047 ! !
  3037 
  3048 
  3038 ListModelView initialize!
  3049 ListModelView initialize!