--- a/DSVColumnView.st Thu Nov 28 18:51:39 2002 +0100
+++ b/DSVColumnView.st Thu Dec 05 16:20:16 2002 +0100
@@ -17,7 +17,8 @@
View subclass:#DSVColumnView
instanceVariableNames:'labelView listHolder editValue editView multipleSelectOk useIndex
- selectedColIndex selectedRowIndex selectRowOnDefault rowHeight
+ selectedColIndex selectedRowIndex selectRowOnDefault
+ buttonMotionAction buttonReleaseAction rowHeight
columnDescriptors viewOrigin colorMap rowFontAscent lockRowIndex
rowIfAbsentBlock columnHolder registererImages list fgColor
separatorSize catchChangeEvents beDependentOfRows bgColor
@@ -26,11 +27,11 @@
buttonLightColor buttonShadowColor buttonHalfLightColor
buttonHalfShadowColor checkToggleExtent checkToggleForm
checkToggleActiveImage checkTogglePassiveImage checkToggleLevel
- comboButtonExtent comboButtonForm comboButtonLevel clickPosition
- dragAccessPoint dragIsActive dropTarget dropSource columnAdaptor
- tabAtEndAction tabAtStartAction modifiedChannel autoScroll
- autoScrollBlock needFitColumns scrollWhenUpdating
- selectionForegroundColor selectionBackgroundColor previousExtent'
+ comboButtonExtent comboButtonForm comboButtonLevel dropTarget
+ dropSource columnAdaptor tabAtEndAction tabAtStartAction
+ modifiedChannel autoScroll autoScrollBlock needFitColumns
+ scrollWhenUpdating selectionForegroundColor
+ selectionBackgroundColor previousExtent'
classVariableNames:'DefaultForegroundColor DefaultBackgroundColor
DefaultHilightForegroundColor DefaultHilightBackgroundColor
ButtonLightColor ButtonShadowColor CheckToggleActiveImage
@@ -70,6 +71,10 @@
editValue <Model> current editing model
editView <View> current editing component
+ buttonReleaseAction <Action or nil> called if the mouse button is released
+ buttonMotionAction <Action or nil> called during mouse motion with one
+ argument the point under the mouse.
+
multipleSelectOk <Boolean> multiple selection enabled/disabled
selectedColIndex <Integer> selected column index or 0
@@ -140,10 +145,6 @@
comboButtonExtent <Point> extent of a comboList or -Box
comboButtonLevel <SmallInteger> level used to draw a comboList or -Box
- clickPosition <Point> click position of the mouse
-
- dragAccessPoint <Point> point where the drag operation starts
- dragIsActive <Boolean> true if a drag operation is active
dropTarget <DropTarget> drag & drop target
dropSource <DropSource> drag & drop source
@@ -155,7 +156,6 @@
DataSetColumn
DataSetView
"
-
! !
!DSVColumnView class methodsFor:'accessing forms'!
@@ -1514,11 +1514,11 @@
!
startDragAt:aPoint
- (dragIsActive not and:[dropSource notNil]) ifTrue:[
- dragIsActive := true.
- dropSource startDragIn:self at:aPoint
+
+ dropSource notNil ifTrue:[
+ dropSource startDragIn:self at:aPoint.
+ buttonReleaseAction := buttonMotionAction := nil.
]
-
! !
!DSVColumnView methodsFor:'drawing'!
@@ -1866,81 +1866,85 @@
!DSVColumnView methodsFor:'event handling'!
+buttonControlPressAtRowNr:aStartRow
+ |isSelected prvRow doAdd chgSet|
+
+ buttonMotionAction := nil.
+ isSelected := self isInSelection:aStartRow.
+
+ isSelected ifTrue:[ self removeRowFromSelection:aStartRow ]
+ ifFalse:[ self addRowToSelection:aStartRow ].
+
+ multipleSelectOk ifFalse:[ ^ self ].
+
+ prvRow := aStartRow.
+ chgSet := IdentitySet new.
+ doAdd := isSelected not.
+
+ buttonMotionAction := [:p| |rowNr mustRestore step f|
+ rowNr := self yVisibleToRowNr:(p y).
+
+ (rowNr notNil and:[rowNr ~~ prvRow]) ifTrue:[
+ rowNr == aStartRow ifTrue:[
+ mustRestore := true
+ ] ifFalse:[
+ rowNr > aStartRow ifTrue:[ mustRestore := (rowNr < prvRow) ]
+ ifFalse:[ mustRestore := (rowNr > prvRow) ].
+ ].
+ prvRow > rowNr ifTrue:[ step := -1 ]
+ ifFalse:[ step := 1 ].
+ mustRestore ifTrue:[
+ [ prvRow ~~ rowNr ] whileTrue:[
+ (chgSet removeIdentical:prvRow ifAbsent:nil) notNil ifTrue:[
+ doAdd ifFalse:[ self addRowToSelection:prvRow ]
+ ifTrue:[ self removeRowFromSelection:prvRow ].
+ ].
+ prvRow := prvRow + step.
+ ].
+ ] ifFalse:[
+ [ prvRow ~~ rowNr ] whileTrue:[
+ prvRow := prvRow + step.
+
+ doAdd ~~ (self isInSelection:rowNr) ifTrue:[
+ chgSet add:prvRow.
+
+ doAdd ifTrue:[ self addRowToSelection:prvRow ]
+ ifFalse:[ self removeRowFromSelection:prvRow ].
+ ]
+ ].
+ ].
+ ].
+ ].
+!
+
buttonMotion:buttonMask x:x y:y
"mouse-move while button was pressed - handle multiple selection changes
"
- |lnNr p oldSelection step|
-
- buttonMask = 0 ifTrue:[
- dragAccessPoint := nil.
- dragIsActive := false.
- ].
-
self isEnabled ifFalse:[^ self].
- dragAccessPoint notNil ifTrue:[
- dragIsActive ifFalse:[
- p := x @ y.
- (clickPosition dist:p) > 5.0 ifTrue:[ self startDragAt:p ]
- ].
- ^ self
- ].
- self sensor ctrlDown ifTrue:[^ self ].
-
- (multipleSelectOk and:[selectedColIndex == 0 and:[selectedRowIndex notNil]]) ifFalse:[
- ^ self
- ].
- "is it the select or 1-button ?"
-
- self sensor leftButtonPressed ifFalse:[^ self].
-
- autoScroll ifTrue:[
- "/ if moved outside of view, start autoscroll
- (y < 0) ifTrue:[
- ^ self startAutoScroll:[self scrollUp] distance:y.
- ].
- (y > height) ifTrue:[
- ^ self startAutoScroll:[self scrollDown] distance:(y - height).
- ].
- ].
-
- "move inside - stop autoscroll if any"
- self stopAutoScroll.
-
- y > height ifTrue:[
- lnNr := self yVisibleToRowNr:(height + rowHeight).
- ] ifFalse:[
- y < 0 ifTrue:[
- lnNr := self yVisibleToRowNr:(rowHeight negated).
- ] ifFalse:[
- lnNr := self yVisibleToRowNr:y.
+ buttonMotionAction notNil ifTrue:[
+ buttonMotionAction value:(x@y).
+
+ buttonMotionAction notNil ifTrue:[
+ autoScroll ifTrue:[
+ "/ if moved outside of view, start autoscroll
+ (y < 0) ifTrue:[
+ ^ self startAutoScroll:[self scrollUp] distance:y.
+ ].
+ (y > height) ifTrue:[
+ ^ self startAutoScroll:[self scrollDown] distance:(y - height).
+ ].
+ ]
]
].
-
- (lnNr isNil or:[lnNr < 1]) ifTrue:[
- ^ self
- ].
-
- oldSelection := selectedRowIndex asOrderedCollection.
- selectedRowIndex := OrderedCollection new.
-
- clickPosition isNil ifTrue:[
- clickPosition := oldSelection at:1 ifAbsent:lnNr
- ].
-
- step := lnNr < clickPosition ifTrue:[-1] ifFalse:[1].
-
- clickPosition to:lnNr by:step do:[:i|
- selectedRowIndex add:i.
- oldSelection removeIdentical:i ifAbsent:[ self invalidateRowAt:i colAt:0 ].
- ].
- oldSelection do:[:i| self invalidateRowAt:i colAt:0 ].
- self scrollToRowAt:lnNr colAt:0.
+ self stopAutoScroll.
!
buttonMultiPress:button x:x y:y
"a button was pressed twice - handle doubleclick here
"
+ buttonMotionAction := buttonReleaseAction := nil.
+
self isEnabled ifFalse:[^ self].
((button == 1) or:[button == #select]) ifFalse:[
@@ -1960,97 +1964,80 @@
buttonPress:button x:x y:y
"a button was pressed - handle selection here
"
- |rowNr colNr menu sz first sensor|
+ |rowNr colNr menu sensor clickPoint|
+
+ buttonMotionAction := buttonReleaseAction := nil.
self isEnabled ifFalse:[^ self].
sensor := self sensor.
-
- clickPosition := nil.
- dragAccessPoint := nil.
- dragIsActive := false.
+ sensor isNil ifTrue:[^ self].
((button == 2) or:[button == #menu]) ifTrue:[
- (menu := self findMenuForSelection) notNil ifTrue:[
- ^ self startUpMenu:menu
- ]
- ] ifFalse:[
- ( (button == 1 or:[button == #select])
- and:[(rowNr := self yVisibleToRowNr:y) notNil
- and:[(colNr := self xVisibleToColNr:x) notNil]]
- ) ifTrue:[
- multipleSelectOk ifTrue:[
- sensor ctrlDown ifTrue:[
- "/ toggle
- selectedColIndex ~~ 0 ifTrue:[
- colNr := 0
- ] ifFalse:[
- (sz := self numberOfSelections == 0) ifFalse:[
- (self isInSelection:rowNr) ifTrue:[
- sz == 1 ifTrue:[
- self selectColIndex:0 rowIndex:nil.
- sensor flushMotionEventsFor:self.
- ^ self
- ].
- selectedRowIndex remove:rowNr.
- ] ifFalse:[
- selectedRowIndex add:rowNr
- ].
- self invalidateRowAt:rowNr.
- self selectionChanged.
- sensor flushMotionEventsFor:self.
- ^ self
- ]
- ]
- ] ifFalse:[
- "/ range
- ( selectedColIndex == 0
- and:[(first := self firstIndexSelected) ~~ 0
- and:[sensor shiftDown]]
- ) ifTrue:[|step list|
- list := OrderedCollection new.
- step := first < rowNr ifTrue:[1] ifFalse:[-1].
- first to:rowNr by:step do:[:i|list add:i].
- self selectedRowIndex:list.
- ^ self.
- ]
- ]
- ].
- (self canDrag and:[self isSelected:rowNr inColumn:colNr]) ifTrue:[
- clickPosition := x @ y.
- dragAccessPoint := (colNr @ rowNr).
- ] ifFalse:[
- self withWaitCursorDo:[
- self selectRowAt:rowNr colAt:colNr atPoint:(x @ y)
- ]
- ].
- ^ self
+ menu := self findMenuForSelection.
+
+ menu notNil ifTrue:[ self startUpMenu:menu ]
+ ifFalse:[ super buttonPress:button x:x y:y ].
+ ^ self
+ ].
+
+ ( (rowNr := self yVisibleToRowNr:y) notNil
+ and:[(colNr := self xVisibleToColNr:x) notNil]
+ ) ifFalse:[
+ super buttonPress:button x:x y:y.
+ ^ self
+ ].
+
+ sensor ctrlDown ifTrue:[
+ self buttonControlPressAtRowNr:rowNr.
+ ^ self
+ ].
+
+ sensor shiftDown ifTrue:[
+ (multipleSelectOk and:[selectedRowIndex size ~~ 0]) ifTrue:[
+ self selectRowFrom:(selectedRowIndex min min:rowNr)
+ to:(selectedRowIndex max max:rowNr).
+ ] ifFalse:[
+ self selectColIndex:0 rowIndex:rowNr.
+ ].
+ ^ self
+ ].
+
+ (self canDrag and:[self isSelected:rowNr inColumn:colNr]) ifTrue:[
+ clickPoint := x @ y.
+ buttonReleaseAction := [ self selectRowAt:rowNr colAt:colNr atPoint:(x @ y) ].
+
+ buttonMotionAction := [:aPoint|
+ (clickPoint dist:aPoint) > 5.0 ifTrue:[
+ buttonReleaseAction := buttonMotionAction := nil.
+ self startDragAt:aPoint.
+ ]
+ ].
+ ^ self.
+ ].
+
+ self withWaitCursorDo:[
+ self selectRowAt:rowNr colAt:colNr atPoint:(x @ y)
+ ].
+
+ (multipleSelectOk and:[selectedColIndex == 0 and:[selectedRowIndex size == 1]]) ifTrue:[
+ buttonMotionAction := [:p| |r|
+ r := self yVisibleToRowNr:(p y).
+ r notNil ifTrue:[ self selectRowFrom:rowNr to:r ].
]
].
- super buttonPress:button x:x y:y
!
buttonRelease:button x:x y:y
+ buttonMotionAction := nil.
self stopAutoScroll.
- clickPosition notNil ifTrue:[
- dragAccessPoint notNil ifTrue:[
- dragIsActive ifFalse:[
- self selectRowAt:(dragAccessPoint y)
- colAt:(dragAccessPoint x)
- atPoint:clickPosition
- ].
- dragAccessPoint := nil.
- dragIsActive := false.
- ] ifFalse:[
- self selectionChanged
- ].
- clickPosition := nil.
+ buttonReleaseAction notNil ifTrue:[
+ buttonReleaseAction value.
+ buttonReleaseAction := nil.
].
super buttonRelease:button x:x y:y
-
-
!
characterPress:aChar x:x y:y
@@ -2542,7 +2529,6 @@
horizontalSpacing := self class horizontalSpacing.
colorMap := Dictionary new.
catchChangeEvents := false.
- dragIsActive := false.
rowFontAscent := 1. "/ dummy initialization
separatorSize := 1. "/ separators mode 2D
selectRowOnDefault := true.
@@ -2841,11 +2827,14 @@
yVisibleToRowNr:y
"returns the row number assigned to a physical y or nil
"
- |y0|
-
- y0 := (y + viewOrigin y - margin) // rowHeight + 1.
- ^ (y0 <= list size) ifTrue:[y0] ifFalse:[nil]
-
+ |rowNr|
+
+ rowNr := (y + viewOrigin y - margin) // rowHeight + 1.
+
+ (rowNr between:1 and:(list size)) ifTrue:[
+ ^ rowNr
+ ].
+ ^ nil
! !
!DSVColumnView methodsFor:'queries'!
@@ -3258,25 +3247,25 @@
"
|newSelection|
- multipleSelectOk ifFalse:[^ self].
-
- selectedRowIndex size == 0 ifTrue:[
- self selectedRowIndex:aRowNr.
+ self numberOfSelections == 0 ifTrue:[
+ self selectColIndex:0 rowIndex:aRowNr.
^ self
].
- (selectedRowIndex includesIdentical:aRowNr) ifTrue:[
+ (self isInSelection:aRowNr) ifTrue:[^ self].
+
+ multipleSelectOk ifFalse:[
+ self selectColIndex:0 rowIndex:aRowNr.
^ self
].
newSelection := selectedRowIndex copyWith:aRowNr.
selectedColIndex ~~ 0 ifTrue:[
- "/ there is a column selected (including an editor..)
self selectColIndex:0 rowIndex:newSelection.
- ^ self
+ ] ifFalse:[
+ selectedRowIndex := selectedRowIndex copyWith:aRowNr.
+ self invalidateRowAt:aRowNr.
+ self selectionChanged.
].
- selectedRowIndex := newSelection.
- self invalidateRowAt:aRowNr colAt:0.
- self selectionChanged.
!
deselect
@@ -3456,6 +3445,20 @@
^ selectedRowIndex size
!
+removeRowFromSelection:aRowNr
+ "remove a row from the selection
+ "
+ (self isInSelection:aRowNr) ifFalse:[^ self].
+
+ self numberOfSelections == 1 ifTrue:[
+ self deselect.
+ ] ifFalse:[
+ selectedRowIndex := selectedRowIndex copyWithout:aRowNr.
+ self invalidateRowAt:aRowNr.
+ self selectionChanged.
+ ].
+!
+
selectAllRows
"select all
"
@@ -3503,6 +3506,46 @@
].
!
+selectRowFrom:start to:stop
+ |step oldSelect newSelect|
+
+ start == stop ifTrue:[
+ self selectColIndex:0 rowIndex:start.
+ ^ self
+ ].
+
+ start <= stop ifTrue:[ step := 1 ]
+ ifFalse:[ step := -1 ].
+
+ newSelect := OrderedCollection new.
+ start to:stop by:step do:[:i| newSelect add:i ].
+
+ selectedColIndex ~~ 0 ifTrue:[
+ newSelect := OrderedCollection new.
+ start to:stop by:step do:[:i| newSelect add:i ].
+ self selectColIndex:0 rowIndex:newSelect.
+ ^ self
+ ].
+ oldSelect := selectedRowIndex ? #().
+ selectedRowIndex := OrderedCollection new.
+
+ start to:stop by:step do:[:i|
+ selectedRowIndex add:i.
+
+ (oldSelect includesIdentical:i) ifFalse:[
+ self invalidateRowAt:i
+ ].
+ ].
+
+ oldSelect do:[:i|
+ (selectedRowIndex includesIdentical:i) ifFalse:[
+ self invalidateRowAt:i
+ ]
+ ].
+
+ self selectionChanged.
+!
+
selectRowIndex:something
"set selection of rows
"
@@ -3789,5 +3832,5 @@
!DSVColumnView class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libwidg2/DSVColumnView.st,v 1.159 2002-11-12 08:27:20 ca Exp $'
+ ^ '$Header: /cvs/stx/stx/libwidg2/DSVColumnView.st,v 1.160 2002-12-05 15:20:16 ca Exp $'
! !