--- a/SelectionInListView.st Tue Apr 26 15:46:00 1994 +0200
+++ b/SelectionInListView.st Thu Jun 02 20:30:26 1994 +0200
@@ -18,8 +18,10 @@
selectConditionBlock
listAttributes multipleSelectOk clickLine
listSymbol initialSelectionSymbol printItems oneItem
- hilightLevel hilightFrameColor ignoreReselect'
- classVariableNames: 'RightArrowShadowForm RightArrowLightForm RightArrowForm'
+ hilightLevel hilightFrameColor ignoreReselect
+ arrowLevel smallArrow'
+ classVariableNames: 'RightArrowShadowForm RightArrowLightForm RightArrowForm
+ SmallRightArrowShadowForm SmallRightArrowLightForm'
poolDictionaries:''
category:'Views-Text'
!
@@ -34,14 +36,55 @@
documentation
"
-this one is a ListView with a selected line (which is shown highlighted)
-If multipleSelectionsOk is true, it is also allowed to shift-click multiple entries.
+ this one is a ListView with a selected line (which is shown highlighted)
+ If multipleSelectionsOk is true, it is also allowed to shift-click multiple entries.
+
+ Whenever the selection changes, an action-block is called for,
+ passing the current selection as argument.
+ Currently, the selection can be nil, aNumber or a collection of
+ numbers; this will change to be either nil or a collection, making
+ selection handling easier in the future.
+ The actionBlock is called with the current selection as argument.
+
+ InstanceVariables:
+ selection <misc> the current selection. nil, a number or collection of numbers
+
+ actionBlock <Block> block to be evaluated on selection changes
+
+ enabled <Boolean> true: selection changes allowed; false: ignore clicks
+
+ hilightFgColor
+ hilightBgColor <Color> how highlighted items are drawn
+
+ halfIntensityColor <Color> foreground for disabled items
+
+ selectConditionBlock <Block> if non-nil, this nlock can decide if selection is ok
-$Header: /cvs/stx/stx/libwidg/SelectionInListView.st,v 1.7 1994-01-13 00:18:21 claus Exp $
+ doubleClickActionBlock <Block> action to perform on double-click
+
+ listAttributes dont use - will vanish
+
+ multipleSelectOk <Boolean> if true, multiple selections (with shift) are ok
+ hilightLevel <Integer> level to draw selections (i.e. for 3D effect)
+ hilightFrameColor <Color> rectangle around highlighted items
+
+ ignoreReselect <Boolean> if true, selecting same again does not trigger action;
+ if false, every select triggers it
-written spring/summer 89 by claus
-3D Jan 90 by claus
-multiselect Jun 92 my claus
+ arrowLevel <Integer> level to draw right-arrows (for submenus etc.)
+ smallArrow <Boolean> if true, uses a small arrow bitmap
+
+ listSymbol if non-nil, use ST-80 style (model-access)
+ initialSelectionSymbol
+ printItems
+ oneItem
+
+
+ $Header: /cvs/stx/stx/libwidg/SelectionInListView.st,v 1.8 1994-06-02 18:30:26 claus Exp $
+
+ written spring/summer 89 by claus
+ 3D Jan 90 by claus
+ multiselect Jun 92 my claus
"
! !
@@ -147,6 +190,60 @@
RightArrowForm := f
].
^ f
+!
+
+smallRightArrowLightFormOn:aDevice
+ "return the form used for the small right arrow light pixels (3D only)"
+
+ |f|
+
+ ((aDevice == Display) and:[SmallRightArrowLightForm notNil]) ifTrue:[
+ ^ SmallRightArrowLightForm
+ ].
+ f := Form fromFile:'SmallRightArrowLight.xbm' resolution:100 on:aDevice.
+ f isNil ifTrue:[
+ f := Form width:9 height:9 fromArray:#(2r00000000 2r00000000
+ 2r01100000 2r00000000
+ 2r01011000 2r00000000
+ 2r01000110 2r00000000
+ 2r01000000 2r00000000
+ 2r01000000 2r00000000
+ 2r01000000 2r00000000
+ 2r01000000 2r00000000
+ 2r00000000 2r00000000)
+ on:aDevice
+ ].
+ (aDevice == Display) ifTrue:[
+ SmallRightArrowLightForm := f
+ ].
+ ^ f
+!
+
+smallRightArrowShadowFormOn:aDevice
+ "return the form used for the small right arrow light pixels (3D only)"
+
+ |f|
+
+ ((aDevice == Display) and:[SmallRightArrowShadowForm notNil]) ifTrue:[
+ ^ SmallRightArrowShadowForm
+ ].
+ f := Form fromFile:'SmallRightArrowShadow.xbm' resolution:100 on:aDevice.
+ f isNil ifTrue:[
+ f := Form width:9 height:9 fromArray:#(2r00000000 2r00000000
+ 2r00000000 2r00000000
+ 2r00000000 2r00000000
+ 2r00000000 2r00000000
+ 2r00000001 2r00000000
+ 2r00000110 2r00000000
+ 2r00011000 2r00000000
+ 2r00100000 2r00000000
+ 2r00000000 2r00000000)
+ on:aDevice
+ ].
+ (aDevice == Display) ifTrue:[
+ SmallRightArrowShadowForm := f
+ ].
+ ^ f
! !
!SelectionInListView class methodsFor:'instance creation'!
@@ -179,11 +276,8 @@
bgColor := viewBackground.
hilightFrameColor := nil.
hilightLevel := 0.
- (style == #openwin) ifTrue:[
- lineSpacing := 3
- ] ifFalse:[
- lineSpacing := 2
- ].
+ arrowLevel := 1.
+ smallArrow := false.
(style == #next) ifTrue:[
device hasGreyscales ifTrue:[
@@ -197,9 +291,13 @@
] ifFalse:[
(style == #motif) ifTrue:[
device hasGreyscales ifTrue:[
- hilightFgColor := fgColor.
- hilightBgColor := bgColor.
- hilightLevel := 2.
+ fgColor := White.
+ bgColor := Grey.
+ viewBackground := bgColor.
+ hilightFgColor := bgColor "fgColor" "White".
+ hilightBgColor := fgColor "bgColor lightened" "darkened".
+ hilightLevel := 0 "1".
+ arrowLevel := -1.
] ifFalse:[
hilightFgColor := White.
hilightBgColor := Black
@@ -210,6 +308,8 @@
hilightFgColor := fgColor.
hilightBgColor := Color grey.
hilightLevel := -1.
+ arrowLevel := -1.
+ smallArrow := true.
] ifFalse:[
hilightFgColor := White.
hilightBgColor := Black
@@ -224,7 +324,7 @@
hilightBgColor := Black
]
] ifFalse:[
- self is3D ifTrue:[
+ (style == #view3D) ifTrue:[
device hasColors ifTrue:[
hilightFgColor := Color name:'yellow'
] ifFalse:[
@@ -241,6 +341,12 @@
]
].
+ (hilightLevel abs > 0) ifTrue:[
+ lineSpacing := 3
+ ] ifFalse:[
+ lineSpacing := 2
+ ].
+
hilightFgColor isNil ifTrue:[
hilightFgColor := bgColor.
hilightBgColor := fgColor
@@ -281,10 +387,11 @@
!
ignoreReselect:aBoolean
- "set/clear the ignoreReselect flag - if set,
- a click on an already selected entry is ignored.
+ "set/clear the ignoreReselect flag -
+ if set, a click on an already selected entry is ignored.
Otherwise the notification is done, even if no
- change in the selection occurs."
+ change in the selection occurs.
+ (for example, in browser to update a method)"
ignoreReselect := aBoolean
!
@@ -577,7 +684,7 @@
|newSelection|
selection notNil ifTrue:[
- (selection isKindOf:Collection) ifTrue:[
+ (selection size > 0) ifTrue:[
newSelection := OrderedCollection new.
selection do:[:sel |
sel < lineNr ifTrue:[
@@ -586,6 +693,7 @@
sel > lineNr ifTrue:[
newSelection add:(sel - 1)
]
+ "otherwise remove it from the selection"
]
].
newSelection size == 1 ifTrue:[
@@ -661,6 +769,8 @@
].
anySelectionInRange ifTrue:[
+ ^ width
+"
self is3D ifFalse:[
^ width
].
@@ -670,6 +780,7 @@
viewBackground = background ifFalse:[
^ width
]
+"
].
^ super widthForScrollBetween:start and:end
!
@@ -727,7 +838,7 @@
This method is not used here, but provided for subclasses such
as menus or file-lists."
- |w h y x l form|
+ |w h y x l form form2 topLeftColor botRightColor t|
x := width - 16.
y := (self yOfLine:visLineNr).
@@ -738,14 +849,36 @@
self foreground:Black.
self displayForm:form x:x y:y.
] ifFalse:[
- form := self class rightArrowLightFormOn:device.
+ smallArrow ifTrue:[
+ form := self class smallRightArrowLightFormOn:device.
+ form2 := self class smallRightArrowShadowFormOn:device.
+ ] ifFalse:[
+ form := self class rightArrowLightFormOn:device.
+ form2 := self class rightArrowShadowFormOn:device.
+ ].
y := y + ((font height - form height) // 2).
- self foreground:lightColor.
- self displayForm:form x:x y:y.
+ topLeftColor := lightColor.
+ botRightColor := shadowColor.
- self foreground:shadowColor.
- self displayForm:(self class rightArrowShadowFormOn:device) x:x y:y.
+ "openwin arrow stays down"
+ style ~~ #openwin ifTrue:[
+ (self isInSelection:(self visibleLineToListLine:visLineNr)) ifTrue:[
+ t := topLeftColor.
+ topLeftColor := botRightColor.
+ botRightColor := t.
+ ]
+ ].
+ arrowLevel < 0 ifTrue:[
+ t := topLeftColor.
+ topLeftColor := botRightColor.
+ botRightColor := t.
+ ].
+
+ self foreground:topLeftColor.
+ self displayForm:form x:x y:y.
+ self foreground:botRightColor.
+ self displayForm:form2 x:x y:y.
]
!
@@ -756,6 +889,9 @@
!
redrawVisibleLine:visLineNr col:colNr
+ "redraw a single character.
+ Must check, if its in the selection and handle this case."
+
(self visibleLineNeedsSpecialCare:visLineNr) ifTrue:[
^ self redrawVisibleLine:visLineNr
].
@@ -763,6 +899,9 @@
!
redrawVisibleLine:visLineNr from:startCol
+ "redraw from a col to the right end.
+ Must check, if its in the selection and handle this case."
+
(self visibleLineNeedsSpecialCare:visLineNr) ifTrue:[
^ self redrawVisibleLine:visLineNr
].
@@ -770,6 +909,9 @@
!
redrawVisibleLine:visLineNr from:startCol to:endCol
+ "redraw from a startCol to endCol.
+ Must check, if its in the selection and handle this case."
+
(self visibleLineNeedsSpecialCare:visLineNr) ifTrue:[
^ self redrawVisibleLine:visLineNr
].
@@ -777,6 +919,10 @@
!
redrawFromVisibleLine:startVisLineNr to:endVisLineNr
+ "redraw a range of lines.
+ Must check, if any is in the selection and handle this case.
+ Otherwise draw it en-bloque using supers method."
+
|special sel
selNo "{ Class: SmallInteger }" |
@@ -787,6 +933,11 @@
^ self
].
+"XXX only if -1/+1"
+"/ hilightLevel ~~ 0 ifTrue:[
+"/ self paint:bgColor.
+"/ self fillRectangleX:0 y:(self yOfLine:startVisLineNr)-1 width:width height:1
+"/ ].
special := true.
selection isNil ifTrue:[
special := false
@@ -814,39 +965,83 @@
!
redrawVisibleLine:visLineNr
- |listLine fg bg
- y "{ Class: SmallInteger }" |
+ "redraw a single line.
+ Must check, if any is in the selection and handle this case.
+ Otherwise draw using supers method."
+
+ |listLine fg bg|
fg := fgColor.
bg := bgColor.
listLine := self visibleLineToListLine:visLineNr.
listLine notNil ifTrue:[
+ (self isInSelection:listLine) ifTrue:[
+ ^ self drawVisibleLineSelected:visLineNr
+ ].
(self attributeAt:listLine) == #halfIntensity ifTrue:[
fg := halfIntensityFgColor
].
- (self isInSelection:listLine) ifTrue:[
- bg := hilightBgColor.
- fg := hilightFgColor.
- hilightFrameColor notNil ifTrue:[
- self drawVisibleLine:visLineNr with:fg and:bg.
- y := self yOfLine:visLineNr.
- self paint:hilightFrameColor.
- self displayLineFromX:0 y:y toX:width y:y.
- y := y + fontHeight - 1.
- self displayLineFromX:0 y:y toX:width y:y.
- ^ self
- ].
- (hilightLevel ~~ 0) ifTrue:[
- self drawVisibleLine:visLineNr with:fg and:bg.
- y := self yOfLine:visLineNr.
- self drawEdgesForX:0 y:y
- width:width height:fontHeight
- level:hilightLevel.
- ^ self
- ]
+ ].
+ ^ self drawVisibleLine:visLineNr with:fg and:bg
+!
+
+drawVisibleLineSelected:visLineNr
+ "redraw a single line as selected."
+
+ |listLine fg bg
+ y "{ Class: SmallInteger }"
+ wEdge|
+
+ bg := hilightBgColor.
+ fg := hilightFgColor.
+ listLine := self visibleLineToListLine:visLineNr.
+ listLine notNil ifTrue:[
+"XXX only if -1/+1"
+"/ hilightLevel ~~ 0 ifTrue:[
+"/ self paint:bg.
+"/ self fillRectangleX:0 y:(self yOfLine:visLineNr)-1 width:width height:1
+"/ ].
+
+ self drawVisibleLine:visLineNr with:fg and:bg.
+ y := self yOfLine:visLineNr.
+
+ "
+ a line above and below
+ "
+ hilightFrameColor notNil ifTrue:[
+ self paint:hilightFrameColor.
+ self displayLineFromX:0 y:y toX:width y:y.
+ y := y + fontHeight - 1.
+ self displayLineFromX:0 y:y toX:width y:y.
+ ^ self
+ ].
+
+ "
+ an edge it around
+ "
+ (hilightLevel ~~ 0) ifTrue:[
+"XXX the -1/+1 need some more work"
+"/ self drawEdgesForX:0 y:y-1
+"/ width:width height:fontHeight+1
+"/ level:hilightLevel.
+
+ "
+ let edge start at left, extending to the full width
+ XXX: widthOfContents should be cached in ListView
+ (instead of recumputing all over)
+ "
+ wEdge := width-(2 * margin).
+ wEdge := wEdge max:(self widthOfContents).
+
+ self drawEdgesForX:(margin - leftOffset) y:y
+ width:wEdge height:fontHeight
+ level:hilightLevel.
+
+
+ ^ self
]
].
- ^ self drawVisibleLine:visLineNr with:fg and:bg
+ ^ super drawVisibleLine:visLineNr with:fg and:bg
! !
!SelectionInListView methodsFor:'event handling'!
@@ -914,7 +1109,7 @@
buttonPress:button x:x y:y
|oldSelection listLineNr|
- (button == 1) ifTrue:[
+ ((button == 1) or:[button == #select]) ifTrue:[
enabled ifTrue:[
(selectConditionBlock isNil or:[selectConditionBlock value]) ifTrue:[
oldSelection := selection.
@@ -941,7 +1136,7 @@
buttonShiftPress:button x:x y:y
|oldSelection listLineNr|
- (button == 1) ifTrue:[
+ ((button == 1) or:[button == #select]) ifTrue:[
enabled ifTrue:[
(selectConditionBlock isNil or:[selectConditionBlock value]) ifTrue:[
oldSelection := selection copy.
@@ -960,7 +1155,9 @@
(selection ~= oldSelection) ifTrue:[
actionBlock notNil ifTrue:[actionBlock value:selection].
"the ST-80 way of doing things"
- model notNil ifTrue:[model perform:changeSymbol with:(self selectionValue)]
+ (model notNil and:[changeSymbol notNil]) ifTrue:[
+ model perform:changeSymbol with:(self selectionValue)
+ ]
].
clickLine := listLineNr
]
@@ -971,7 +1168,7 @@
!
buttonMultiPress:button x:x y:y
- (button == 1) ifTrue:[
+ ((button == 1) or:[button == #select]) ifTrue:[
doubleClickActionBlock isNil ifTrue:[
self buttonPress:button x:x y:y
] ifFalse:[