From 9e23fc2b13acf378c2ee8b5d8b2decad61702588 Mon Sep 17 00:00:00 2001 From: Alain Plantec Date: Fri, 22 Mar 2024 16:16:07 +0100 Subject: [PATCH] changed selectionModel --- .../ToPicsumPhotosGalleryImageHolder.class.st | 5 + src/Toplo-Examples/ToSandBox.class.st | 12 +- .../ToBasicListSelectionModelTest.class.st | 82 ++-- .../ToSelectionModelHolderForTest.class.st | 2 +- .../ToAbstractListElement.class.st | 14 + .../ToBasicListElement.class.st | 26 +- .../ToBasicListElementEventHandler.class.st | 2 +- .../ToBasicListSelectionModel.class.st | 350 ------------------ .../ToBasicNodeHolder.class.st | 7 + .../ToCommandOperator.class.st | 5 - src/Toplo-Widget-List/ToListElement.class.st | 27 +- .../ToListElementSieve2.class.st | 128 ------- .../ToListPrimarySelectionModel.class.st | 152 ++++++++ .../ToListSecondarySelectionModel.class.st | 28 ++ .../ToListSelectionModel.class.st | 336 ++++++++++++++--- .../ToListStandardSelectionModel.class.st | 112 ++++++ .../ToPrimarySelectionModelOperator.class.st | 6 - ...ToSecondarySelectionModelOperator.class.st | 2 +- .../ToSievedListElementEventHandler.class.st | 33 +- .../ToSievedListElementEventHandler2.class.st | 228 ------------ .../ToStandardSelectionModelOperator.class.st | 6 + 21 files changed, 710 insertions(+), 853 deletions(-) create mode 100644 src/Toplo-Examples/ToPicsumPhotosGalleryImageHolder.class.st delete mode 100644 src/Toplo-Widget-List/ToBasicListSelectionModel.class.st delete mode 100644 src/Toplo-Widget-List/ToListElementSieve2.class.st create mode 100644 src/Toplo-Widget-List/ToListPrimarySelectionModel.class.st create mode 100644 src/Toplo-Widget-List/ToListSecondarySelectionModel.class.st create mode 100644 src/Toplo-Widget-List/ToListStandardSelectionModel.class.st delete mode 100644 src/Toplo-Widget-List/ToSievedListElementEventHandler2.class.st diff --git a/src/Toplo-Examples/ToPicsumPhotosGalleryImageHolder.class.st b/src/Toplo-Examples/ToPicsumPhotosGalleryImageHolder.class.st new file mode 100644 index 00000000..250a395b --- /dev/null +++ b/src/Toplo-Examples/ToPicsumPhotosGalleryImageHolder.class.st @@ -0,0 +1,5 @@ +Class { + #name : #ToPicsumPhotosGalleryImageHolder, + #superclass : #ToNodeHolder, + #category : #'Toplo-Examples' +} diff --git a/src/Toplo-Examples/ToSandBox.class.st b/src/Toplo-Examples/ToSandBox.class.st index 6cdb2aba..39e72588 100644 --- a/src/Toplo-Examples/ToSandBox.class.st +++ b/src/Toplo-Examples/ToSandBox.class.st @@ -937,7 +937,7 @@ ToSandBox class >> example_ListWithEditableAndContextMenu [ menu addItem: (ToMenuItem new labelText: 'Show all'; whenClickedDo: [ :event | - target hiddenSelecter deselectAll ]; + target selectionModel unhideAll ]; yourself) ]. selectedIndexes ifNotEmpty: [ selectionMenu := ToMenu new. @@ -972,21 +972,21 @@ ToSandBox class >> example_ListWithEditableAndContextMenu [ (target disabledSelectionModel containsIndex: idx) ifTrue: [ - target disabledSelecter deselectIndex: idx ] + target selectionModel enableIndex: idx ] ifFalse: [ - target disabledSelecter selectIndex: idx ] ] ]; + target selectionModel disableIndex: idx ] ] ]; yourself). selectionMenu addItem: (ToMenuItem new labelText: 'Set unselectable'; whenClickedDo: [ :event | selectedIndexes do: [ :idx | - target unselectableSelecter selectIndex: idx ] ]; + target selectionModel unselectableIndex: idx ] ]; yourself). selectionMenu addItem: (ToMenuItem new labelText: 'Hide'; whenClickedDo: [ :event | selectedIndexes do: [ :idx | - target hiddenSelecter selectIndex: idx ] ]; + target selectionModel hideIndex: idx ] ]; yourself). selectionMenu addItem: (ToMenuItem new labelText: 'Insert before'; @@ -2429,7 +2429,7 @@ ToSandBox class >> example_contactList [ on: BlClickEvent do: [ :event | event consumed: true. - holder infiniteElement dataAccessor removeAt: holder position ]). + holder listElement dataAccessor removeAt: holder position ]). line addChild: remBut. node addChild: line ]. list dataAccessor addAll: contacts. diff --git a/src/Toplo-Widget-List-Tests/ToBasicListSelectionModelTest.class.st b/src/Toplo-Widget-List-Tests/ToBasicListSelectionModelTest.class.st index 9573c566..48693f61 100644 --- a/src/Toplo-Widget-List-Tests/ToBasicListSelectionModelTest.class.st +++ b/src/Toplo-Widget-List-Tests/ToBasicListSelectionModelTest.class.st @@ -17,7 +17,7 @@ ToBasicListSelectionModelTest >> itemCount [ ToBasicListSelectionModelTest >> testContainsIndex [ | s | - s := ToBasicListSelectionModel new. + s := ToListSelectionModel new. self deny: (s containsIndex: 1). s selectIndex: 1. s assert: (s containsIndex: 1). @@ -28,7 +28,7 @@ ToBasicListSelectionModelTest >> testContainsIndex [ ToBasicListSelectionModelTest >> testCopyCompositeModel [ | s c | - s := ToBasicListSelectionModel new. + s := ToListSelectionModel new. c := s copy. self deny: s underlyingModel identicalTo: c underlyingModel. self assert: c equals: s @@ -38,7 +38,7 @@ ToBasicListSelectionModelTest >> testCopyCompositeModel [ ToBasicListSelectionModelTest >> testCopySelectionFrom [ | s s2 | - s := ToBasicListSelectionModel new itemCountGetter: 100. + s := ToListSelectionModel new itemCountGetter: 100. s2 := s copy. s selectIndexes: { 1. 5. 6 }. s2 copySelectionFrom: s. @@ -57,7 +57,7 @@ ToBasicListSelectionModelTest >> testCopySelectionFrom [ ToBasicListSelectionModelTest >> testDeselectAll [ | s | - s := ToBasicListSelectionModel new itemCountGetter: 100. + s := ToListSelectionModel new itemCountGetter: 100. s deselectAll. self assert: s isEmpty . s selectIndex: 10. @@ -70,7 +70,7 @@ ToBasicListSelectionModelTest >> testDeselectAll [ ToBasicListSelectionModelTest >> testDeselectAllIndexesWithAWholeSelection [ | s | - s := ToBasicListSelectionModel new itemCountGetter: 10. + s := ToListSelectionModel new itemCountGetter: 10. s selectAll. " item count that is necessary in that case " s deselectIndexes: { 2. 4. 6 }. @@ -81,7 +81,7 @@ ToBasicListSelectionModelTest >> testDeselectAllIndexesWithAWholeSelection [ ToBasicListSelectionModelTest >> testDeselectAllIndexesWithAWholeSelection2 [ | s | - s := ToBasicListSelectionModel new. + s := ToListSelectionModel new. " no way to get item count that is necessary in that case -> Error" self should: [s selectAll] raise: Error. s deselectIndexes: { 2. 4. 6 }. @@ -93,7 +93,7 @@ ToBasicListSelectionModelTest >> testDeselectAllIndexesWithAWholeSelection2 [ ToBasicListSelectionModelTest >> testDeselectIndex [ | s | - s := ToBasicListSelectionModel new itemCountGetter: 100. + s := ToListSelectionModel new itemCountGetter: 100. s selectIndexes: { 1. 5. 6 }. self assert: s selectedIndexes asSet equals: { 1. 5. 6 } asSet. s deselectIndex: 10. @@ -107,7 +107,7 @@ ToBasicListSelectionModelTest >> testDeselectIndex [ ToBasicListSelectionModelTest >> testDeselectIndexTo [ | s | - s := ToBasicListSelectionModel new itemCountGetter: 100. + s := ToListSelectionModel new itemCountGetter: 100. s selectIndex: 5 to: 15. s deselectIndex: 8 to: 12. self assert: s selectedIndexes equals: { 5. 6. 7. 13. 14. 15 }. @@ -121,7 +121,7 @@ ToBasicListSelectionModelTest >> testDeselectIndexTo [ ToBasicListSelectionModelTest >> testDeselectIndexes [ | s | - s := ToBasicListSelectionModel new itemCountGetter: 100. + s := ToListSelectionModel new itemCountGetter: 100. s selectIndexes: { 1. 5. 6 }. self assert: s selectedIndexes asSet equals: { 1. 5. 6 } asSet. s deselectIndexes: { 10. 50. 60 }. @@ -134,8 +134,8 @@ ToBasicListSelectionModelTest >> testDeselectIndexes [ ToBasicListSelectionModelTest >> testEquals [ | s | - s := ToBasicListSelectionModel new. - self assert: s equals: ToBasicListSelectionModel new. + s := ToListSelectionModel new. + self assert: s equals: ToListSelectionModel new. ] @@ -143,7 +143,7 @@ ToBasicListSelectionModelTest >> testEquals [ ToBasicListSelectionModelTest >> testFirstIndex [ | s | - s := ToBasicListSelectionModel new. + s := ToListSelectionModel new. self assert: s firstIndex equals: 0. s itemCountGetter: [ 100 ]. self assert: s firstIndex equals: 0. @@ -160,7 +160,7 @@ ToBasicListSelectionModelTest >> testFirstIndex [ ToBasicListSelectionModelTest >> testInitialize [ | s | - s := ToBasicListSelectionModel new. + s := ToListSelectionModel new. self assert: s isEmpty. self assert: (s underlyingModel isKindOf: BlCompositeSelection ). ] @@ -169,7 +169,7 @@ ToBasicListSelectionModelTest >> testInitialize [ ToBasicListSelectionModelTest >> testIsEmpty [ | s | - s := ToBasicListSelectionModel new. + s := ToListSelectionModel new. self assert: s isEmpty ] @@ -178,7 +178,7 @@ ToBasicListSelectionModelTest >> testIsEmpty [ ToBasicListSelectionModelTest >> testItemCount [ | s | - s := ToBasicListSelectionModel new onInstalledIn: self. + s := ToListSelectionModel new onInstalledIn: self. self assert: s itemCount equals: self itemCount. s underlyingModel selectIndex: 1. s assert: (s containsIndex: 1) @@ -188,7 +188,7 @@ ToBasicListSelectionModelTest >> testItemCount [ ToBasicListSelectionModelTest >> testItemCountGetter [ | s | - s := ToBasicListSelectionModel new onInstalledIn: self. + s := ToListSelectionModel new onInstalledIn: self. self assert: s itemCount equals: s itemCountGetter value. s itemCountGetter: [ 1000 ]. self assert: s itemCount equals: 1000. @@ -200,7 +200,7 @@ ToBasicListSelectionModelTest >> testItemCountGetter [ ToBasicListSelectionModelTest >> testLastIndex [ | s | - s := ToBasicListSelectionModel new. + s := ToListSelectionModel new. self assert: s lastIndex equals: 0. s itemCountGetter: [ 100 ]. self assert: s lastIndex equals: 0. @@ -214,7 +214,7 @@ ToBasicListSelectionModelTest >> testLastIndex [ ToBasicListSelectionModelTest >> testOnInstalledIn [ | s | - s := ToBasicListSelectionModel new. + s := ToListSelectionModel new. s onInstalledIn: self. self assert: s itemCountGetter notNil. self assert: s itemCountGetter value equals: self itemCount @@ -224,7 +224,7 @@ ToBasicListSelectionModelTest >> testOnInstalledIn [ ToBasicListSelectionModelTest >> testOnUninstalledIn [ | s | - s := ToBasicListSelectionModel new. + s := ToListSelectionModel new. s onInstalledIn: self. s onUninstalledIn: self. self should: [ s itemCountGetter ] raise: Error. @@ -235,7 +235,7 @@ ToBasicListSelectionModelTest >> testOnUninstalledIn [ ToBasicListSelectionModelTest >> testSelectAll [ | s | - s := ToBasicListSelectionModel new itemCountGetter: 100. + s := ToListSelectionModel new itemCountGetter: 100. s selectAll. self assert: s lastIndex equals: 100. s selectIndex: 10. @@ -248,7 +248,7 @@ ToBasicListSelectionModelTest >> testSelectAll [ ToBasicListSelectionModelTest >> testSelectIndex [ | s | - s := ToBasicListSelectionModel new itemCountGetter: 100. + s := ToListSelectionModel new itemCountGetter: 100. s selectIndex: 1. s selectIndex: 5. s selectIndex: 6. @@ -263,7 +263,7 @@ ToBasicListSelectionModelTest >> testSelectIndex [ ToBasicListSelectionModelTest >> testSelectIndexTo [ | s | - s := ToBasicListSelectionModel new itemCountGetter: 100. + s := ToListSelectionModel new itemCountGetter: 100. s selectIndex: 5 to: 9. self assert: s selectedIndexes equals: { 5. 6. 7. 8. 9 }. s selectIndex: 15 to: 10. @@ -274,7 +274,7 @@ ToBasicListSelectionModelTest >> testSelectIndexTo [ ToBasicListSelectionModelTest >> testSelectIndexes [ | s | - s := ToBasicListSelectionModel new itemCountGetter: 100. + s := ToListSelectionModel new itemCountGetter: 100. s selectIndexes: { 1. 5. 6 }. self assert: s selectedIndexes equals: { 1. 5. 6 }. s selectIndexes: { 10. 50. 60 }. @@ -285,7 +285,7 @@ ToBasicListSelectionModelTest >> testSelectIndexes [ ToBasicListSelectionModelTest >> testSelectedIndexesCollect [ | s collected | - s := ToBasicListSelectionModel new. + s := ToListSelectionModel new. s itemCountGetter: [ 100 ]. collected := s selectedIndexesCollect: [ :idx | idx ]. self assert: collected equals: #( ). @@ -305,7 +305,7 @@ ToBasicListSelectionModelTest >> testSelectedIndexesCollect [ ToBasicListSelectionModelTest >> testSelectedIndexesCount [ | s | - s := ToBasicListSelectionModel new. + s := ToListSelectionModel new. s itemCountGetter: [ 100 ]. self assert: s selectedIndexesCount equals: 0. s selectIndexes: #( 4 6 8 ). @@ -320,7 +320,7 @@ ToBasicListSelectionModelTest >> testSelectedIndexesCount [ ToBasicListSelectionModelTest >> testSelectedIndexesDo [ | s count | - s := ToBasicListSelectionModel new. + s := ToListSelectionModel new. s itemCountGetter: [ 100 ]. count := 0. s selectedIndexesDo: [ :idx | count := count + 1 ]. @@ -344,7 +344,7 @@ ToBasicListSelectionModelTest >> testSelectedIndexesDo [ ToBasicListSelectionModelTest >> testSelectedItemCount [ | s | - s := ToBasicListSelectionModel new onInstalledIn: self. + s := ToListSelectionModel new onInstalledIn: self. self assert: s selectedIndexesCount equals: 0. s selectIndex: 1. self assert: s selectedIndexesCount equals: 1. @@ -356,7 +356,7 @@ ToBasicListSelectionModelTest >> testSelectedItemCount [ ToBasicListSelectionModelTest >> testShiftFrom [ | s | - s := ToBasicListSelectionModel new itemCountGetter: 100. + s := ToListSelectionModel new itemCountGetter: 100. s selectIndexes: { 1. 5. 6 }. self assert: s selectedIndexes equals: { 1. 5. 6 }. s shift: 1 from: 1. @@ -370,7 +370,7 @@ ToBasicListSelectionModelTest >> testShiftFrom [ ToBasicListSelectionModelTest >> testShiftFrom10 [ | s | - s := ToBasicListSelectionModel new itemCountGetter: 200. + s := ToListSelectionModel new itemCountGetter: 200. s selectIndexes: { 4. 5. 7. 8. 10. 11 }. { 4. 5. 7. 8. 10. 11 } do: [ :idx | s shift: -1 from: idx ]. self assert: s selectedIndexes equals: { 3. 4. 5. 6. 7 } @@ -380,7 +380,7 @@ ToBasicListSelectionModelTest >> testShiftFrom10 [ ToBasicListSelectionModelTest >> testShiftFrom2 [ | s | - s := ToBasicListSelectionModel new itemCountGetter: 100. + s := ToListSelectionModel new itemCountGetter: 100. s selectIndexes: { 1. 5. 6 }. self assert: s selectedIndexes equals: { 1. 5. 6 }. s shift: 3 from: 5. @@ -397,7 +397,7 @@ ToBasicListSelectionModelTest >> testShiftFrom2 [ ToBasicListSelectionModelTest >> testShiftFrom3 [ | s | - s := ToBasicListSelectionModel new itemCountGetter: 100. + s := ToListSelectionModel new itemCountGetter: 100. s selectIndexes: { 2. 3 }. s shift: -2 from: 3. self assert: s selectedIndexes equals: { 1 }. @@ -414,7 +414,7 @@ ToBasicListSelectionModelTest >> testShiftFrom3 [ ToBasicListSelectionModelTest >> testShiftFrom4 [ | s | - s := ToBasicListSelectionModel new itemCountGetter: 100. + s := ToListSelectionModel new itemCountGetter: 100. s selectIndexes: { 1. 5. 6 }. self assert: s selectedIndexes equals: { 1. 5. 6 }. s shift: 1 from: 1. @@ -426,7 +426,7 @@ ToBasicListSelectionModelTest >> testShiftFrom4 [ ToBasicListSelectionModelTest >> testShiftFrom5 [ | s | - s := ToBasicListSelectionModel new itemCountGetter: 100. + s := ToListSelectionModel new itemCountGetter: 100. s selectIndexes: { 2. 6. 7 }. s shift: 1 from: 6. self assert: s selectedIndexes equals: { 2. 7. 8 } @@ -436,7 +436,7 @@ ToBasicListSelectionModelTest >> testShiftFrom5 [ ToBasicListSelectionModelTest >> testShiftFrom6 [ | s | - s := ToBasicListSelectionModel new itemCountGetter: 2. + s := ToListSelectionModel new itemCountGetter: 2. s selectIndexes: { 1 }. s shift: -1 from: 2. self assert: s selectedIndexes equals: { 1 } @@ -446,7 +446,7 @@ ToBasicListSelectionModelTest >> testShiftFrom6 [ ToBasicListSelectionModelTest >> testShiftFrom7 [ | s | - s := ToBasicListSelectionModel new itemCountGetter: 200. + s := ToListSelectionModel new itemCountGetter: 200. s selectIndexes: { 3 }. s shift: -1 from: 4. self assert: s selectedIndexes equals: { 3 } @@ -456,7 +456,7 @@ ToBasicListSelectionModelTest >> testShiftFrom7 [ ToBasicListSelectionModelTest >> testShiftFrom8 [ | s | - s := ToBasicListSelectionModel new itemCountGetter: 200. + s := ToListSelectionModel new itemCountGetter: 200. s selectIndexes: { 3 }. s shift: 1 from: 1. self assert: s selectedIndexes equals: { 4 } @@ -466,7 +466,7 @@ ToBasicListSelectionModelTest >> testShiftFrom8 [ ToBasicListSelectionModelTest >> testShiftFrom9 [ | s | - s := ToBasicListSelectionModel new itemCountGetter: 200. + s := ToListSelectionModel new itemCountGetter: 200. s selectIndexes: { 4. 5. 7. 8. 10. 11 }. s shift: -1 from: 4. self assert: s selectedIndexes equals: { 3. 4. 6. 7. 9. 10 }. @@ -486,7 +486,7 @@ ToBasicListSelectionModelTest >> testShiftFrom9 [ ToBasicListSelectionModelTest >> testShiftFrom9bis [ | s | - s := ToBasicListSelectionModel new itemCountGetter: 200. + s := ToListSelectionModel new itemCountGetter: 200. s selectIndexes: { 3. 4. 5. 6. 7. 8 }. s shift: -1 from: 8. self assert: s selectedIndexes equals: { 3. 4. 5. 6. 7 }. @@ -500,7 +500,7 @@ ToBasicListSelectionModelTest >> testShiftFrom9bis [ ToBasicListSelectionModelTest >> testShiftFrom9bis2 [ | s | - s := ToBasicListSelectionModel new itemCountGetter: 200. + s := ToListSelectionModel new itemCountGetter: 200. s selectIndexes: { 4. 5. 7}. s shift: -1 from: 4. self assert: s selectedIndexes equals: { 3. 4. 6}. @@ -510,7 +510,7 @@ ToBasicListSelectionModelTest >> testShiftFrom9bis2 [ ToBasicListSelectionModelTest >> testUnderlyingModel [ | s | - s := ToBasicListSelectionModel new. + s := ToListSelectionModel new. self assert: (s underlyingModel isKindOf: BlCompositeSelection) ] @@ -518,7 +518,7 @@ ToBasicListSelectionModelTest >> testUnderlyingModel [ ToBasicListSelectionModelTest >> testselectedIndexes [ | s | - s := ToBasicListSelectionModel new itemCountGetter: 100. + s := ToListSelectionModel new itemCountGetter: 100. self assert: s selectedIndexes equals: #( ). s selectAll. self assert: s selectedIndexes equals: (1 to: 100) diff --git a/src/Toplo-Widget-List-Tests/ToSelectionModelHolderForTest.class.st b/src/Toplo-Widget-List-Tests/ToSelectionModelHolderForTest.class.st index 2e7ec650..e7fd3e2e 100644 --- a/src/Toplo-Widget-List-Tests/ToSelectionModelHolderForTest.class.st +++ b/src/Toplo-Widget-List-Tests/ToSelectionModelHolderForTest.class.st @@ -38,7 +38,7 @@ ToSelectionModelHolderForTest >> dataSource: aDataSource [ { #category : #initialization } ToSelectionModelHolderForTest >> defaultSelectionModel [ - ^ ToBasicListSelectionModel new + ^ ToListSelectionModel new ] { #category : #'event management accessing' } diff --git a/src/Toplo-Widget-List/ToAbstractListElement.class.st b/src/Toplo-Widget-List/ToAbstractListElement.class.st index f702955e..a3d5dc50 100644 --- a/src/Toplo-Widget-List/ToAbstractListElement.class.st +++ b/src/Toplo-Widget-List/ToAbstractListElement.class.st @@ -122,6 +122,12 @@ ToAbstractListElement >> defaultNodeHolderFactory [ ^ self subclassResponsibility ] +{ #category : #initialization } +ToAbstractListElement >> defaultNodeHolderReleaser [ + + ^ self subclassResponsibility +] + { #category : #initialization } ToAbstractListElement >> defaultNodeReleaser [ @@ -273,6 +279,14 @@ ToAbstractListElement >> nodeHolderBuilder [ ^ self subclassResponsibility ] +{ #category : #accessing } +ToAbstractListElement >> nodeHolderReleaser [ + + "aValuable takes 1 arg: the holder to build and second " + + ^ self subclassResponsibility +] + { #category : #accessing } ToAbstractListElement >> nodeReleaser [ "aValuable takes 2 args: first, the ToNode to release and second, its holder in the list element " diff --git a/src/Toplo-Widget-List/ToBasicListElement.class.st b/src/Toplo-Widget-List/ToBasicListElement.class.st index 080c812a..e1d896bf 100644 --- a/src/Toplo-Widget-List/ToBasicListElement.class.st +++ b/src/Toplo-Widget-List/ToBasicListElement.class.st @@ -5,7 +5,8 @@ Class { 'nodeFactory', 'nodeBuilder', 'nodeReleaser', - 'nodeHolderBuilder' + 'nodeHolderBuilder', + 'nodeHolderReleaser' ], #category : #'Toplo-Widget-List-Core' } @@ -59,6 +60,12 @@ ToBasicListElement >> defaultNodeHolderFactory [ ^ [ ToBasicNodeHolder new ] ] +{ #category : #initialization } +ToBasicListElement >> defaultNodeHolderReleaser [ + + ^ [ :theHolder | theHolder dataItem: nil ] +] + { #category : #initialization } ToBasicListElement >> defaultNodeReleaser [ @@ -79,6 +86,7 @@ ToBasicListElement >> initialize [ super initialize. nodeFactory := self defaultNodeFactory. nodeHolderBuilder := self defaultNodeHolderBuilder. + nodeHolderReleaser := self defaultNodeHolderReleaser. nodeBuilder := self defaultNodeBuilder. nodeReleaser := self defaultNodeReleaser ] @@ -92,7 +100,7 @@ ToBasicListElement >> newPrimarySelectionModel [ { #category : #'instance creation' } ToBasicListElement >> newSelectionModel [ - ^ ToBasicListSelectionModel new + ^ ToListSelectionModel new itemCountGetter: [ self dataSource itemCount ]; yourself ] @@ -141,6 +149,20 @@ ToBasicListElement >> nodeHolderBuilder: aBuilder [ nodeHolderBuilder := aBuilder ] +{ #category : #accessing } +ToBasicListElement >> nodeHolderReleaser [ + "aValuable takes 1 arg: the holder to release " + + ^ nodeHolderReleaser +] + +{ #category : #accessing } +ToBasicListElement >> nodeHolderReleaser: aValuable [ + "aValuable takes 1 arg: the holder to release " + + nodeHolderReleaser := aValuable +] + { #category : #accessing } ToBasicListElement >> nodeReleaser [ "aValuable takes 2 args: first, the ToNode to release and second, its holder in the list element " diff --git a/src/Toplo-Widget-List/ToBasicListElementEventHandler.class.st b/src/Toplo-Widget-List/ToBasicListElementEventHandler.class.st index 7eff9e8b..8f88e90b 100644 --- a/src/Toplo-Widget-List/ToBasicListElementEventHandler.class.st +++ b/src/Toplo-Widget-List/ToBasicListElementEventHandler.class.st @@ -105,7 +105,7 @@ ToBasicListElementEventHandler >> infiniteElementDetachedEvent: anEvent [ node := anEvent element. listElement := anEvent currentTarget. listElement selectionMode onRemovedNode: node. - listElement nodeReleaser cull: node cull: node holder. + node holder unbindDataItem. ] { #category : #'infinite event handling' } diff --git a/src/Toplo-Widget-List/ToBasicListSelectionModel.class.st b/src/Toplo-Widget-List/ToBasicListSelectionModel.class.st deleted file mode 100644 index c62c68ee..00000000 --- a/src/Toplo-Widget-List/ToBasicListSelectionModel.class.st +++ /dev/null @@ -1,350 +0,0 @@ -Class { - #name : #ToBasicListSelectionModel, - #superclass : #Object, - #instVars : [ - 'underlyingModel', - 'itemCountGetter', - 'monitor' - ], - #category : #'Toplo-Widget-List-Selection-Model' -} - -{ #category : #comparing } -ToBasicListSelectionModel >> = anObject [ - - self == anObject ifTrue: [ ^ true ]. - self class = anObject class ifFalse: [ ^ false ]. - - self underlyingModelDo: [ :ulm | - anObject underlyingModelDo: [ :ulm2 | ^ ulm = ulm2 ] ] -] - -{ #category : #'api - testing' } -ToBasicListSelectionModel >> containsIndex: anIndex [ - - self underlyingModelDo: [ :ulm | ^ ulm containsIndex: anIndex ] -] - -{ #category : #copying } -ToBasicListSelectionModel >> copySelectionFrom: anotherSelectionModel [ - - anotherSelectionModel underlyingModelDo: [ :ulm | underlyingModel := ulm copy ] -] - -{ #category : #updating } -ToBasicListSelectionModel >> deselectAll [ - - self underlyingModelDo: [ :ulm | ulm removeAll ] -] - -{ #category : #updating } -ToBasicListSelectionModel >> deselectIndex: anIndex [ - - self underlyingModelDo: [ :ulm | ulm deselectIndex: anIndex ] -] - -{ #category : #updating } -ToBasicListSelectionModel >> deselectIndex: aFirstIndex to: aSecondIndex [ - - self underlyingModelDo: [ :ulm | - | from to | - from := aFirstIndex min: aSecondIndex. - to := aFirstIndex max: aSecondIndex. - (from <= to and: [ from > 0 and: [ to >= 0 ] ]) ifFalse: [ ^ self ]. - ulm deselect: from - 1 to: to ] -] - -{ #category : #updating } -ToBasicListSelectionModel >> deselectIndexes: anArray [ - - self underlyingModelDo: [ :ulm | - anArray do: [ :idx | self deselectIndex: idx ] ] -] - -{ #category : #accessing } -ToBasicListSelectionModel >> firstIndex [ - - self underlyingModelDo: [ :ulm | - self ifEmpty: [ ^ 0 ]. - ^ ulm from + 1 ] -] - -{ #category : #comparing } -ToBasicListSelectionModel >> hash [ - - self underlyingModelDo: [ :ulm | ^ self class hash bitXor: ulm hash ] -] - -{ #category : #testing } -ToBasicListSelectionModel >> ifEmpty: aBlock [ - - self underlyingModelDo: [ :ulm | - self isEmpty ifFalse: [ ^ self ]. - aBlock value ] -] - -{ #category : #testing } -ToBasicListSelectionModel >> ifNotEmpty: aBlock [ - - self underlyingModelDo: [ :ulm | - self isEmpty ifTrue: [ ^ self ]. - aBlock cull: self ] -] - -{ #category : #initialization } -ToBasicListSelectionModel >> initialize [ - - super initialize. - underlyingModel := BlCompositeSelection new. - monitor := Monitor new. -] - -{ #category : #testing } -ToBasicListSelectionModel >> isEmpty [ - - self underlyingModelDo: [ :ulm | ^ ulm isEmpty ] -] - -{ #category : #testing } -ToBasicListSelectionModel >> isNotEmpty [ - - ^ self isEmpty not -] - -{ #category : #testing } -ToBasicListSelectionModel >> isUnselectableIndex: anIndex [ - - ^ false -] - -{ #category : #accessing } -ToBasicListSelectionModel >> itemCount [ - - - ^ self itemCountGetter value -] - -{ #category : #accessing } -ToBasicListSelectionModel >> itemCountGetter [ - - itemCountGetter ifNil: [ Error signal: 'A selection model must have an initalized itemCountGetter' ]. - ^ itemCountGetter -] - -{ #category : #accessing } -ToBasicListSelectionModel >> itemCountGetter: aValuable [ - - " aValuable takes no args and return the number of items (typically, a datasource items count) " - itemCountGetter := aValuable -] - -{ #category : #accessing } -ToBasicListSelectionModel >> lastIndex [ - - self underlyingModelDo: [ :ulm | - self ifEmpty: [ ^ 0 ]. - ^ ulm to ] -] - -{ #category : #accessing } -ToBasicListSelectionModel >> nextSelectableIndexStartingAt: anIndex [ - - anIndex < self itemCount ifTrue: [ ^ anIndex ]. - ^ 0 -] - -{ #category : #'api - hooks' } -ToBasicListSelectionModel >> onInstalledIn: anElement [ - - itemCountGetter := [ anElement itemCount ] -] - -{ #category : #'api - hooks' } -ToBasicListSelectionModel >> onUninstalledIn: anElement [ - - itemCountGetter := nil -] - -{ #category : #copying } -ToBasicListSelectionModel >> postCopy [ - - super postCopy. - self underlyingModelDo: [ :ulm | underlyingModel := ulm copy ]. - monitor := Monitor new. -] - -{ #category : #accessing } -ToBasicListSelectionModel >> previousSelectableIndexStartingAt: anIndex [ - - anIndex > 0 ifTrue: [ ^ anIndex ]. - ^ 0 -] - -{ #category : #updating } -ToBasicListSelectionModel >> selectAll [ - - self underlyingModelDo: [ :ulm | - ulm removeAll. - self selectIndex: 1 to: self itemCount ] -] - -{ #category : #updating } -ToBasicListSelectionModel >> selectIndex: anIndex [ - - self underlyingModelDo: [ :ulm | ulm selectIndex: anIndex ] -] - -{ #category : #updating } -ToBasicListSelectionModel >> selectIndex: aFirstIndex to: aSecondIndex [ - - self underlyingModelDo: [ :ulm | - | from to | - from := aFirstIndex min: aSecondIndex. - to := aFirstIndex max: aSecondIndex. - ulm select: from - 1 to: to ] -] - -{ #category : #updating } -ToBasicListSelectionModel >> selectIndexes: anArray [ - - self underlyingModelDo: [ :ulm | - anArray ifEmpty: [ ^ self ]. - anArray do: [ :idx | self selectIndex: idx ] ] -] - -{ #category : #accessing } -ToBasicListSelectionModel >> selectedIndexes [ - - self underlyingModelDo: [ :ulm | ^ ulm indices ] -] - -{ #category : #enumerating } -ToBasicListSelectionModel >> selectedIndexesCollect: aBlock [ - - self underlyingModelDo: [ :ulm | ^ ulm indicesCollect: aBlock ] -] - -{ #category : #accessing } -ToBasicListSelectionModel >> selectedIndexesCount [ - - | count | - count := 0. - self underlyingModelDo: [ :ulm | ulm do: [ :s | count := count + s interval size - 1 ] ]. - ^ count -] - -{ #category : #enumerating } -ToBasicListSelectionModel >> selectedIndexesDo: aBlock [ - - self underlyingModelDo: [ :ulm | ^ ulm indicesDo: aBlock ] -] - -{ #category : #accessing } -ToBasicListSelectionModel >> selectedIndexesIntervals [ - " return an array of intervals #( 2 3 4 6 7 8 ) -> { 2 to: 4. 6 to: 8 } " - - self underlyingModelDo: [ :ulm | - ^ Array streamContents: [ :stream | - self selectedIndexesIntervalsDo: [ :interval | - stream nextPut: interval ] ] ] -] - -{ #category : #enumerating } -ToBasicListSelectionModel >> selectedIndexesIntervalsDo: aBlock [ - " aBlock has one interval argument " - - self underlyingModelDo: [ :ulm | - | prev g | - g := nil. - prev := nil. - self selectedIndexesDo: [ :idx | - prev ifNil: [ g := idx to: idx ] ifNotNil: [ - prev + 1 = idx - ifTrue: [ g := g first to: idx ] - ifFalse: [ - aBlock value: g. - g := idx to: idx ] ]. - prev := idx ]. - g ifNotNil: [ aBlock value: g ] ] -] - -{ #category : #updating } -ToBasicListSelectionModel >> shift: aGap from: aStartIndex [ - - self shift: aGap from: aStartIndex for: nil -] - -{ #category : #updating } -ToBasicListSelectionModel >> shift: aGap from: aStartIndex for: anEventTarget [ - - | from to prevIntervals high | - aGap isZero ifTrue: [ ^ self ]. - - self underlyingModelDo: [ :ulm | - - self isEmpty ifTrue: [ ^ self ]. - - " 1 - keep selected intervals to reselect them accordingly at 2" - prevIntervals := self selectedIndexesIntervals. - high := self underlyingModel to. - - " deselect according to start index and gap " - aGap <= 0 - ifTrue: [ - from := aStartIndex + aGap. - to := aStartIndex. - (high >= 0 and: [ from <= high ]) ifTrue: [ - ulm selections delete: - (BlMonotoneSelection from: (from max: 0) to: high) ] ] - ifFalse: [ - from := aStartIndex. - to := aStartIndex + aGap min: high. - - from <= high ifTrue: [ - ulm selections delete: - (BlMonotoneSelection from: (from - 1 max: 0) to: high) ] ]. - - " 2 - reselect " - prevIntervals do: [ :interval | - | first last | - (interval last >= aStartIndex and: [ interval last + aGap > 0 ]) - ifTrue: [ - first := interval first max: aStartIndex. - last := interval last. - - ulm select: first + aGap - 1 to: last + aGap ] ] ] -] - -{ #category : #accessing } -ToBasicListSelectionModel >> sideIdx: aGap startingAt: anIndex [ - - self underlyingModelDo: [ :ulm | - | nextIdx | - nextIdx := anIndex. - (self containsIndex: nextIdx) ifFalse: [ - ^ aGap < 0 - ifTrue: [ self previousSelectableIndexStartingAt: nextIdx ] - ifFalse: [ self nextSelectableIndexStartingAt: nextIdx ] ]. - [ - (nextIdx between: 1 and: self itemCount) and: [ - (self containsIndex: nextIdx) or: [ - self isUnselectableIndex: nextIdx ] ] ] whileTrue: [ - nextIdx := nextIdx + aGap ]. - nextIdx := (nextIdx max: 1) min: self itemCount. - - ^ (self isUnselectableIndex: nextIdx) - ifTrue: [ 0 ] - ifFalse: [ nextIdx ] ] -] - -{ #category : #accessing } -ToBasicListSelectionModel >> underlyingModel [ - - ^ underlyingModel -] - -{ #category : #updating } -ToBasicListSelectionModel >> underlyingModelDo: aBlock [ - - monitor critical: [ aBlock value: underlyingModel ] -] diff --git a/src/Toplo-Widget-List/ToBasicNodeHolder.class.st b/src/Toplo-Widget-List/ToBasicNodeHolder.class.st index 8c9d138f..5e4534c6 100644 --- a/src/Toplo-Widget-List/ToBasicNodeHolder.class.st +++ b/src/Toplo-Widget-List/ToBasicNodeHolder.class.st @@ -63,3 +63,10 @@ ToBasicNodeHolder >> node: aNode [ itemElement := aNode ] + +{ #category : #accessing } +ToBasicNodeHolder >> unbindDataItem [ + + self listElement nodeReleaser cull: self node cull: self. + self listElement nodeHolderReleaser value: self +] diff --git a/src/Toplo-Widget-List/ToCommandOperator.class.st b/src/Toplo-Widget-List/ToCommandOperator.class.st index 401c703a..f8a5971a 100644 --- a/src/Toplo-Widget-List/ToCommandOperator.class.st +++ b/src/Toplo-Widget-List/ToCommandOperator.class.st @@ -39,11 +39,6 @@ ToCommandOperator >> initialize [ eventDispatcher := BlDirectEventDispatcher on: self ] -{ #category : #'command operations' } -ToCommandOperator >> listScrollCommand: aCommand in: aTarget [ - -] - { #category : #'api - hooks' } ToCommandOperator >> onInstalledIn: anEventTarget [ diff --git a/src/Toplo-Widget-List/ToListElement.class.st b/src/Toplo-Widget-List/ToListElement.class.st index 5a3cfa2c..f995027d 100644 --- a/src/Toplo-Widget-List/ToListElement.class.st +++ b/src/Toplo-Widget-List/ToListElement.class.st @@ -2,11 +2,8 @@ Class { #name : #ToListElement, #superclass : #ToBasicListElement, #instVars : [ - 'disabledSelecter', - 'unselectableSelecter', 'secondarySelectionModel', - 'secondarySelectionMode', - 'hiddenSelecter' + 'secondarySelectionMode' ], #category : #'Toplo-Widget-List-Core' } @@ -51,7 +48,7 @@ ToListElement >> defaultSecondarySelectionMode [ { #category : #accessing } ToListElement >> disabledSelecter [ - ^ disabledSelecter + ^ self selectionModel disabledSelecter ] { #category : #accessing } @@ -63,7 +60,7 @@ ToListElement >> disabledSelectionModel [ { #category : #accessing } ToListElement >> hiddenSelecter [ - ^ hiddenSelecter + ^ self selectionModel hiddenSelecter ] { #category : #accessing } @@ -81,18 +78,10 @@ ToListElement >> infiniteSharedEvents [ { #category : #initialization } ToListElement >> initializeSelectionModel [ - unselectableSelecter := self installSelecterForEventClass: - ToListUnselectableSelectionChangedEvent. - disabledSelecter := self installSelecterForEventClass: - ToListDisabledSelectionChangedEvent. - hiddenSelecter := self installSelecterForEventClass: - ToListHiddenSelectionChangedEvent. - + super initializeSelectionModel. self secondarySelectionModel: self newSecondarySelectionModel. self secondarySelectionMode: self defaultSecondarySelectionMode. - self addEventHandler: self defaultSecondarySelectionEventHandler. - - super initializeSelectionModel + self addEventHandler: self defaultSecondarySelectionEventHandler ] { #category : #initialization } @@ -115,7 +104,7 @@ ToListElement >> installSelecterForEventClass: anEventClass [ { #category : #'instance creation' } ToListElement >> newPrimarySelectionModel [ - ^ ToListSelectionModel new + ^ ToListPrimarySelectionModel new ] { #category : #skin } @@ -127,7 +116,7 @@ ToListElement >> newRawSkin [ { #category : #'instance creation' } ToListElement >> newSecondarySelectionModel [ - ^ ToListSelectionModel new + ^ ToListSecondarySelectionModel new ] { #category : #accessing } @@ -168,7 +157,7 @@ ToListElement >> secondarySelectionModel: aSelectionModel [ { #category : #accessing } ToListElement >> unselectableSelecter [ - ^ unselectableSelecter + ^ self selectionModel unselectableSelecter ] { #category : #accessing } diff --git a/src/Toplo-Widget-List/ToListElementSieve2.class.st b/src/Toplo-Widget-List/ToListElementSieve2.class.st deleted file mode 100644 index 9d625d1a..00000000 --- a/src/Toplo-Widget-List/ToListElementSieve2.class.st +++ /dev/null @@ -1,128 +0,0 @@ -Class { - #name : #ToListElementSieve2, - #superclass : #Object, - #instVars : [ - 'queryRunner', - 'originalData', - 'currentData', - 'selectionHandler', - 'sharedHandler', - 'dataPositionIndex' - ], - #category : #'Toplo-Widget-List-Sieve' -} - -{ #category : #accessing } -ToListElementSieve2 >> currentData [ - - ^ currentData -] - -{ #category : #enumerating } -ToListElementSieve2 >> currentDataWithIndexDo: aBlock [ - " aBlock takes a data an its index as arguments " - - self currentData do: [ :d | - | idx | - idx := self dataPositionIndex at: d. - aBlock value: d value: idx ] -] - -{ #category : #enumerating } -ToListElementSieve2 >> currentIndexesDo: aBlock [ - " aBlock takes an index as argument " - - self currentData do: [ :d | - | idx | - idx := self dataPositionIndex at: d. - aBlock value: idx ] -] - -{ #category : #accessing } -ToListElementSieve2 >> dataFilter: aValuable [ - " filter takes a data and a pattern as argument " - - queryRunner dataFilter: [ :item :pattern | - aValuable value: item value: pattern ] -] - -{ #category : #accessing } -ToListElementSieve2 >> dataPositionIndex [ - - ^ dataPositionIndex -] - -{ #category : #accessing } -ToListElementSieve2 >> isInstalled [ - - ^ originalData notNil -] - -{ #category : #'api - hooks' } -ToListElementSieve2 >> onInstalledIn: aListElement [ - " install the sieve on the listElement " - - originalData ifNotNil: [ - ^ (BlImmutableObjectChangeError object: self) signal ]. - dataPositionIndex := IdentityDictionary new. - originalData := aListElement dataAccessor newMirror. - queryRunner := ToObservableCollectionFilter new. - queryRunner onInstalledIn: originalData. - - " initialization of the current result with the current pattern " - self updateCurrentData. - sharedHandler := BlSharedEventDistributor new. - sharedHandler shareEvents: { ToObservableCollectionFilterResultEvent }. - originalData addEventHandler: sharedHandler. - aListElement addEventHandler: sharedHandler. - - selectionHandler := ToSievedListElementEventHandler2 new. - selectionHandler sieve: self. - aListElement addEventHandler: selectionHandler -] - -{ #category : #'api - hooks' } -ToListElementSieve2 >> onUninstalledIn: aListElement [ - " uninstall list element handlers and the queyrunner properly " - - aListElement removeEventHandler: selectionHandler. - queryRunner onUninstalledIn: originalData. - originalData removeEventHandler: sharedHandler. - aListElement removeEventHandler: sharedHandler. - sharedHandler := nil. - originalData unmirrored. - originalData := nil. - currentData := nil. - queryRunner := nil -] - -{ #category : #accessing } -ToListElementSieve2 >> originalData [ - - ^ originalData -] - -{ #category : #accessing } -ToListElementSieve2 >> pattern [ - - ^ queryRunner pattern -] - -{ #category : #accessing } -ToListElementSieve2 >> pattern: aPattern [ - - queryRunner - pattern: aPattern -] - -{ #category : #private } -ToListElementSieve2 >> updateCurrentData [ - - " get the filtered data " - currentData := queryRunner pattern - ifEmpty: [ originalData ] - ifNotEmpty: [ - queryRunner selectedIndexes collect: [ :idx | - originalData at: idx ] ]. - -] diff --git a/src/Toplo-Widget-List/ToListPrimarySelectionModel.class.st b/src/Toplo-Widget-List/ToListPrimarySelectionModel.class.st new file mode 100644 index 00000000..db4d66aa --- /dev/null +++ b/src/Toplo-Widget-List/ToListPrimarySelectionModel.class.st @@ -0,0 +1,152 @@ +Class { + #name : #ToListPrimarySelectionModel, + #superclass : #ToListStandardSelectionModel, + #instVars : [ + 'listElement' + ], + #category : #'Toplo-Widget-List-Selection-Model' +} + +{ #category : #copying } +ToListPrimarySelectionModel >> copySelectionFrom: anotherSelectionModel [ + + super copySelectionFrom: anotherSelectionModel. + self unselectableSelectionModel copySelectionFrom: anotherSelectionModel unselectableSelectionModel. + self disabledSelectionModel copySelectionFrom: anotherSelectionModel disabledSelectionModel. + self hiddenSelectionModel copySelectionFrom: anotherSelectionModel hiddenSelectionModel +] + +{ #category : #updating } +ToListPrimarySelectionModel >> disableIndex: anIndex [ + + self disabledSelecter selectIndex: anIndex +] + +{ #category : #updating } +ToListPrimarySelectionModel >> enableIndex: anIndex [ + + self disabledSelecter deselectIndex: anIndex +] + +{ #category : #updating } +ToListPrimarySelectionModel >> hideIndex: anIndex [ + + self hiddenSelecter selectIndex: anIndex +] + +{ #category : #updating } +ToListPrimarySelectionModel >> hideOnlyIndexes: aCollection [ + + self hiddenSelecter selectOnlyIndexes: aCollection +] + +{ #category : #'private - initialization' } +ToListPrimarySelectionModel >> installSelecterForEventClass: anEventClass in: aListElement [ + + ^ self + installSelecterForEventClass: anEventClass + in: aListElement + withSelectionModel: aListElement newSelectionModel +] + +{ #category : #'private - initialization' } +ToListPrimarySelectionModel >> installSelecterForEventClass: anEventClass in: aListElement withSelectionModel: aSelectionModel [ + + | newSelecter operator | + operator := ToAdditionalSelectionModelOperator eventClass: + anEventClass. + aSelectionModel onInstalledIn: aListElement. + newSelecter := ToMultiSelectionModelSelecter new. + operator selectionModel: aSelectionModel. + operator onInstalledIn: aListElement. + newSelecter operator: operator. + newSelecter onInstalledIn: aListElement. + + ^ newSelecter +] + +{ #category : #'api - hooks' } +ToListPrimarySelectionModel >> onInstalledIn: aListElement [ + + super onInstalledIn: aListElement. + listElement := aListElement. + unselectableSelecter := self installSelecterForEventClass: + ToListUnselectableSelectionChangedEvent in: aListElement. + disabledSelecter := self installSelecterForEventClass: + ToListDisabledSelectionChangedEvent in: aListElement. + hiddenSelecter := self installSelecterForEventClass: + ToListHiddenSelectionChangedEvent in: aListElement. + + +] + +{ #category : #'api - hooks' } +ToListPrimarySelectionModel >> onUninstalledIn: aListElement [ + + unselectableSelecter onInstalledIn: aListElement. + disabledSelecter onInstalledIn: aListElement. + hiddenSelecter onInstalledIn: aListElement. + super onUninstalledIn: aListElement +] + +{ #category : #copying } +ToListPrimarySelectionModel >> postCopy [ + + super postCopy. + + unselectableSelecter := self + installSelecterForEventClass: + ToListUnselectableSelectionChangedEvent + in: listElement + withSelectionModel: + self unselectableSelectionModel copy. + disabledSelecter := self + installSelecterForEventClass: + ToListDisabledSelectionChangedEvent + in: listElement + withSelectionModel: + self disabledSelectionModel copy. + hiddenSelecter := self + installSelecterForEventClass: + ToListHiddenSelectionChangedEvent + in: listElement + withSelectionModel: self hiddenSelectionModel copy +] + +{ #category : #updating } +ToListPrimarySelectionModel >> selectableIndex: anIndex [ + + self unselectableSelecter deselectIndex: anIndex +] + +{ #category : #updating } +ToListPrimarySelectionModel >> transferIndex: anIndex from: anotherPrimarySelectionModel as: targetIndex [ + + (anotherPrimarySelectionModel containsIndex: anIndex) + ifTrue: [ self selectIndex: targetIndex ]. + (self disabledSelectionModel containsIndex: anIndex) + ifTrue: [ self disabledSelectionModel selectIndex: targetIndex ]. + (self unselectableSelectionModel containsIndex: anIndex) + ifTrue: [ self unselectableSelectionModel selectIndex: targetIndex ]. + (self hiddenSelectionModel containsIndex: anIndex) + ifTrue: [ self hiddenSelectionModel selectIndex: targetIndex ]. + +] + +{ #category : #updating } +ToListPrimarySelectionModel >> unhideAll [ + + self hiddenSelecter deselectAll +] + +{ #category : #updating } +ToListPrimarySelectionModel >> unhideIndex: anIndex [ + + self hiddenSelecter deselectIndex: anIndex +] + +{ #category : #updating } +ToListPrimarySelectionModel >> unselectableIndex: anIndex [ + + self unselectableSelecter selectIndex: anIndex +] diff --git a/src/Toplo-Widget-List/ToListSecondarySelectionModel.class.st b/src/Toplo-Widget-List/ToListSecondarySelectionModel.class.st new file mode 100644 index 00000000..f071e3dd --- /dev/null +++ b/src/Toplo-Widget-List/ToListSecondarySelectionModel.class.st @@ -0,0 +1,28 @@ +Class { + #name : #ToListSecondarySelectionModel, + #superclass : #ToListStandardSelectionModel, + #category : #'Toplo-Widget-List-Selection-Model' +} + +{ #category : #'api - hooks' } +ToListSecondarySelectionModel >> onInstalledIn: aListElement [ + + super onInstalledIn: aListElement. + unselectableSelecter := aListElement unselectableSelecter. + disabledSelecter := aListElement disabledSelecter. + hiddenSelecter := aListElement hiddenSelecter. + + +] + +{ #category : #'api - hooks' } +ToListSecondarySelectionModel >> onUninstalledIn: aListElement [ + + unselectableSelecter := nil. + disabledSelecter := nil. + hiddenSelecter := nil. + super onInstalledIn: aListElement. + + + +] diff --git a/src/Toplo-Widget-List/ToListSelectionModel.class.st b/src/Toplo-Widget-List/ToListSelectionModel.class.st index 750ade12..85f44c33 100644 --- a/src/Toplo-Widget-List/ToListSelectionModel.class.st +++ b/src/Toplo-Widget-List/ToListSelectionModel.class.st @@ -1,114 +1,350 @@ Class { #name : #ToListSelectionModel, - #superclass : #ToBasicListSelectionModel, + #superclass : #Object, #instVars : [ - 'listElement' + 'underlyingModel', + 'itemCountGetter', + 'monitor' ], #category : #'Toplo-Widget-List-Selection-Model' } +{ #category : #comparing } +ToListSelectionModel >> = anObject [ + + self == anObject ifTrue: [ ^ true ]. + self class = anObject class ifFalse: [ ^ false ]. + + self underlyingModelDo: [ :ulm | + anObject underlyingModelDo: [ :ulm2 | ^ ulm = ulm2 ] ] +] + +{ #category : #'api - testing' } +ToListSelectionModel >> containsIndex: anIndex [ + + self underlyingModelDo: [ :ulm | ^ ulm containsIndex: anIndex ] +] + +{ #category : #copying } +ToListSelectionModel >> copySelectionFrom: anotherSelectionModel [ + + anotherSelectionModel underlyingModelDo: [ :ulm | underlyingModel := ulm copy ] +] + +{ #category : #updating } +ToListSelectionModel >> deselectAll [ + + self underlyingModelDo: [ :ulm | ulm removeAll ] +] + +{ #category : #updating } +ToListSelectionModel >> deselectIndex: anIndex [ + + self underlyingModelDo: [ :ulm | ulm deselectIndex: anIndex ] +] + +{ #category : #updating } +ToListSelectionModel >> deselectIndex: aFirstIndex to: aSecondIndex [ + + self underlyingModelDo: [ :ulm | + | from to | + from := aFirstIndex min: aSecondIndex. + to := aFirstIndex max: aSecondIndex. + (from <= to and: [ from > 0 and: [ to >= 0 ] ]) ifFalse: [ ^ self ]. + ulm deselect: from - 1 to: to ] +] + +{ #category : #updating } +ToListSelectionModel >> deselectIndexes: anArray [ + + self underlyingModelDo: [ :ulm | + anArray do: [ :idx | self deselectIndex: idx ] ] +] + { #category : #accessing } -ToListSelectionModel >> disabledSelectionModel [ +ToListSelectionModel >> firstIndex [ + + self underlyingModelDo: [ :ulm | + self ifEmpty: [ ^ 0 ]. + ^ ulm from + 1 ] +] + +{ #category : #comparing } +ToListSelectionModel >> hash [ - ^ listElement disabledSelectionModel + self underlyingModelDo: [ :ulm | ^ self class hash bitXor: ulm hash ] ] { #category : #testing } -ToListSelectionModel >> hasUnselectableInInterval: anInterval [ +ToListSelectionModel >> ifEmpty: aBlock [ - ^ anInterval anySatisfy: [ :idx | self unselectableSelectionModel containsIndex: idx ] + self underlyingModelDo: [ :ulm | + self isEmpty ifFalse: [ ^ self ]. + aBlock value ] +] +{ #category : #testing } +ToListSelectionModel >> ifNotEmpty: aBlock [ + + self underlyingModelDo: [ :ulm | + self isEmpty ifTrue: [ ^ self ]. + aBlock cull: self ] ] -{ #category : #accessing } -ToListSelectionModel >> hiddenSelectionModel [ +{ #category : #initialization } +ToListSelectionModel >> initialize [ + + super initialize. + underlyingModel := BlCompositeSelection new. + monitor := Monitor new. +] + +{ #category : #testing } +ToListSelectionModel >> isEmpty [ + + self underlyingModelDo: [ :ulm | ^ ulm isEmpty ] +] + +{ #category : #testing } +ToListSelectionModel >> isNotEmpty [ - ^ listElement hiddenSelectionModel + ^ self isEmpty not ] { #category : #testing } ToListSelectionModel >> isUnselectableIndex: anIndex [ - ^ (self unselectableSelectionModel containsIndex: anIndex) or: [ - self hiddenSelectionModel containsIndex: anIndex ] + ^ false ] { #category : #accessing } -ToListSelectionModel >> nextSelectableIndexStartingAt: anIndex [ +ToListSelectionModel >> itemCount [ + + + ^ self itemCountGetter value +] - (self unselectableSelectionModel isEmpty and: [ - self hiddenSelectionModel isEmpty ]) ifTrue: [ - ^ super nextSelectableIndexStartingAt: anIndex ]. +{ #category : #accessing } +ToListSelectionModel >> itemCountGetter [ - anIndex to: self itemCount do: [ :idx | - ((self unselectableSelectionModel containsIndex: idx) or: [ - self hiddenSelectionModel containsIndex: idx ]) ifFalse: [ ^ idx ] ]. + itemCountGetter ifNil: [ Error signal: 'A selection model must have an initalized itemCountGetter' ]. + ^ itemCountGetter +] + +{ #category : #accessing } +ToListSelectionModel >> itemCountGetter: aValuable [ + + " aValuable takes no args and return the number of items (typically, a datasource items count) " + itemCountGetter := aValuable +] + +{ #category : #accessing } +ToListSelectionModel >> lastIndex [ + + self underlyingModelDo: [ :ulm | + self ifEmpty: [ ^ 0 ]. + ^ ulm to ] +] + +{ #category : #accessing } +ToListSelectionModel >> nextSelectableIndexStartingAt: anIndex [ + + anIndex < self itemCount ifTrue: [ ^ anIndex ]. ^ 0 ] { #category : #'api - hooks' } -ToListSelectionModel >> onInstalledIn: aListElement [ +ToListSelectionModel >> onInstalledIn: anElement [ - super onInstalledIn: aListElement. - listElement := aListElement + itemCountGetter := [ anElement itemCount ] ] { #category : #'api - hooks' } -ToListSelectionModel >> onUninstalledIn: aListElement [ +ToListSelectionModel >> onUninstalledIn: anElement [ - listElement := nil. - super onUninstalledIn: aListElement. + itemCountGetter := nil +] + +{ #category : #copying } +ToListSelectionModel >> postCopy [ + super postCopy. + self underlyingModelDo: [ :ulm | underlyingModel := ulm copy ]. + monitor := Monitor new. ] { #category : #accessing } ToListSelectionModel >> previousSelectableIndexStartingAt: anIndex [ - (self unselectableSelectionModel isEmpty and: [ - self hiddenSelectionModel isEmpty ]) ifTrue: [ - ^ super previousSelectableIndexStartingAt: anIndex ]. - - anIndex to: 1 by: -1 do: [ :idx | - ((self unselectableSelectionModel containsIndex: idx) or: [ - self hiddenSelectionModel containsIndex: idx ]) ifFalse: [ ^ idx ] ]. + anIndex > 0 ifTrue: [ ^ anIndex ]. ^ 0 ] +{ #category : #updating } +ToListSelectionModel >> selectAll [ + + self underlyingModelDo: [ :ulm | + ulm removeAll. + self selectIndex: 1 to: self itemCount ] +] + { #category : #updating } ToListSelectionModel >> selectIndex: anIndex [ - (self unselectableSelectionModel containsIndex: anIndex) ifTrue: [ ^ self ]. - super selectIndex: anIndex + self underlyingModelDo: [ :ulm | ulm selectIndex: anIndex ] ] { #category : #updating } ToListSelectionModel >> selectIndex: aFirstIndex to: aSecondIndex [ - super selectIndex: aFirstIndex to: aSecondIndex. - aFirstIndex to: aSecondIndex do: [ :idx | - (self unselectableSelectionModel containsIndex: idx) ifTrue: [ - self deselectIndex: idx ] ] + self underlyingModelDo: [ :ulm | + | from to | + from := aFirstIndex min: aSecondIndex. + to := aFirstIndex max: aSecondIndex. + ulm select: from - 1 to: to ] +] + +{ #category : #updating } +ToListSelectionModel >> selectIndexes: anArray [ + + self underlyingModelDo: [ :ulm | + anArray ifEmpty: [ ^ self ]. + anArray do: [ :idx | self selectIndex: idx ] ] +] + +{ #category : #accessing } +ToListSelectionModel >> selectedIndexes [ + + self underlyingModelDo: [ :ulm | ^ ulm indices ] +] + +{ #category : #enumerating } +ToListSelectionModel >> selectedIndexesCollect: aBlock [ + + self underlyingModelDo: [ :ulm | ^ ulm indicesCollect: aBlock ] +] + +{ #category : #accessing } +ToListSelectionModel >> selectedIndexesCount [ + + | count | + count := 0. + self underlyingModelDo: [ :ulm | ulm do: [ :s | count := count + s interval size - 1 ] ]. + ^ count min: self itemCount +] + +{ #category : #enumerating } +ToListSelectionModel >> selectedIndexesDo: aBlock [ + + self underlyingModelDo: [ :ulm | ^ ulm indicesDo: aBlock ] +] + +{ #category : #accessing } +ToListSelectionModel >> selectedIndexesIntervals [ + " return an array of intervals #( 2 3 4 6 7 8 ) -> { 2 to: 4. 6 to: 8 } " + + self underlyingModelDo: [ :ulm | + ^ Array streamContents: [ :stream | + self selectedIndexesIntervalsDo: [ :interval | + stream nextPut: interval ] ] ] +] + +{ #category : #enumerating } +ToListSelectionModel >> selectedIndexesIntervalsDo: aBlock [ + " aBlock has one interval argument " + + self underlyingModelDo: [ :ulm | + | prev g | + g := nil. + prev := nil. + self selectedIndexesDo: [ :idx | + prev ifNil: [ g := idx to: idx ] ifNotNil: [ + prev + 1 = idx + ifTrue: [ g := g first to: idx ] + ifFalse: [ + aBlock value: g. + g := idx to: idx ] ]. + prev := idx ]. + g ifNotNil: [ aBlock value: g ] ] +] + +{ #category : #updating } +ToListSelectionModel >> shift: aGap from: aStartIndex [ + + self shift: aGap from: aStartIndex for: nil ] { #category : #updating } ToListSelectionModel >> shift: aGap from: aStartIndex for: anEventTarget [ - (aGap < 0 and: [ self itemCount >= aStartIndex ]) ifTrue: [ - | count | - count := aGap abs. - "self disabledSelectionModel - deselectIndex: aStartIndex - to: aStartIndex + count - 1." - self deselectIndex: aStartIndex to: aStartIndex + count - 1 ]. - self unselectableSelectionModel shift: aGap from: aStartIndex. - self disabledSelectionModel shift: aGap from: aStartIndex. + | from to prevIntervals high | + aGap isZero ifTrue: [ ^ self ]. + + self underlyingModelDo: [ :ulm | + + self isEmpty ifTrue: [ ^ self ]. - " ** super send after **" - super shift: aGap from: aStartIndex for: anEventTarget + " 1 - keep selected intervals to reselect them accordingly at 2" + prevIntervals := self selectedIndexesIntervals. + high := self underlyingModel to. + + " deselect according to start index and gap " + aGap <= 0 + ifTrue: [ + from := aStartIndex + aGap. + to := aStartIndex. + (high >= 0 and: [ from <= high ]) ifTrue: [ + ulm selections delete: + (BlMonotoneSelection from: (from max: 0) to: high) ] ] + ifFalse: [ + from := aStartIndex. + to := aStartIndex + aGap min: high. + + from <= high ifTrue: [ + ulm selections delete: + (BlMonotoneSelection from: (from - 1 max: 0) to: high) ] ]. + + " 2 - reselect " + prevIntervals do: [ :interval | + | first last | + (interval last >= aStartIndex and: [ interval last + aGap > 0 ]) + ifTrue: [ + first := interval first max: aStartIndex. + last := interval last. + + ulm select: first + aGap - 1 to: last + aGap ] ] ] ] { #category : #accessing } -ToListSelectionModel >> unselectableSelectionModel [ +ToListSelectionModel >> sideIdx: aGap startingAt: anIndex [ + + self underlyingModelDo: [ :ulm | + | nextIdx | + nextIdx := anIndex. + (self containsIndex: nextIdx) ifFalse: [ + ^ aGap < 0 + ifTrue: [ self previousSelectableIndexStartingAt: nextIdx ] + ifFalse: [ self nextSelectableIndexStartingAt: nextIdx ] ]. + [ + (nextIdx between: 1 and: self itemCount) and: [ + (self containsIndex: nextIdx) or: [ + self isUnselectableIndex: nextIdx ] ] ] whileTrue: [ + nextIdx := nextIdx + aGap ]. + nextIdx := (nextIdx max: 1) min: self itemCount. + + ^ (self isUnselectableIndex: nextIdx) + ifTrue: [ 0 ] + ifFalse: [ nextIdx ] ] +] + +{ #category : #accessing } +ToListSelectionModel >> underlyingModel [ + + ^ underlyingModel +] + +{ #category : #updating } +ToListSelectionModel >> underlyingModelDo: aBlock [ - ^ listElement unselectableSelectionModel + monitor critical: [ aBlock value: underlyingModel ] ] diff --git a/src/Toplo-Widget-List/ToListStandardSelectionModel.class.st b/src/Toplo-Widget-List/ToListStandardSelectionModel.class.st new file mode 100644 index 00000000..37af6fce --- /dev/null +++ b/src/Toplo-Widget-List/ToListStandardSelectionModel.class.st @@ -0,0 +1,112 @@ +Class { + #name : #ToListStandardSelectionModel, + #superclass : #ToListSelectionModel, + #instVars : [ + 'unselectableSelecter', + 'disabledSelecter', + 'hiddenSelecter' + ], + #category : #'Toplo-Widget-List-Selection-Model' +} + +{ #category : #accessing } +ToListStandardSelectionModel >> disabledSelecter [ + + ^ disabledSelecter +] + +{ #category : #accessing } +ToListStandardSelectionModel >> disabledSelectionModel [ + + ^ self disabledSelecter selectionModel +] + +{ #category : #accessing } +ToListStandardSelectionModel >> hiddenSelecter [ + + ^ hiddenSelecter +] + +{ #category : #accessing } +ToListStandardSelectionModel >> hiddenSelectionModel [ + + ^ self hiddenSelecter selectionModel +] + +{ #category : #testing } +ToListStandardSelectionModel >> isUnselectableIndex: anIndex [ + + ^ (self unselectableSelectionModel containsIndex: anIndex) or: [ + self hiddenSelectionModel containsIndex: anIndex ] +] + +{ #category : #accessing } +ToListStandardSelectionModel >> nextSelectableIndexStartingAt: anIndex [ + + (self unselectableSelectionModel isEmpty and: [ + self hiddenSelectionModel isEmpty ]) ifTrue: [ + ^ super nextSelectableIndexStartingAt: anIndex ]. + + anIndex to: self itemCount do: [ :idx | + ((self unselectableSelectionModel containsIndex: idx) or: [ + self hiddenSelectionModel containsIndex: idx ]) ifFalse: [ ^ idx ] ]. + ^ 0 +] + +{ #category : #accessing } +ToListStandardSelectionModel >> previousSelectableIndexStartingAt: anIndex [ + + (self unselectableSelectionModel isEmpty and: [ + self hiddenSelectionModel isEmpty ]) ifTrue: [ + ^ super previousSelectableIndexStartingAt: anIndex ]. + + anIndex to: 1 by: -1 do: [ :idx | + ((self unselectableSelectionModel containsIndex: idx) or: [ + self hiddenSelectionModel containsIndex: idx ]) ifFalse: [ ^ idx ] ]. + ^ 0 +] + +{ #category : #updating } +ToListStandardSelectionModel >> selectIndex: anIndex [ + + (self unselectableSelectionModel containsIndex: anIndex) ifTrue: [ ^ self ]. + super selectIndex: anIndex +] + +{ #category : #updating } +ToListStandardSelectionModel >> selectIndex: aFirstIndex to: aSecondIndex [ + + super selectIndex: aFirstIndex to: aSecondIndex. + aFirstIndex to: aSecondIndex do: [ :idx | + (self unselectableSelectionModel containsIndex: idx) ifTrue: [ + self deselectIndex: idx ] ] +] + +{ #category : #updating } +ToListStandardSelectionModel >> shift: aGap from: aStartIndex for: anEventTarget [ + + (aGap < 0 and: [ self itemCount >= aStartIndex ]) ifTrue: [ + | count | + count := aGap abs. + "self disabledSelectionModel + deselectIndex: aStartIndex + to: aStartIndex + count - 1." + self deselectIndex: aStartIndex to: aStartIndex + count - 1 ]. + self unselectableSelectionModel shift: aGap from: aStartIndex. + self disabledSelectionModel shift: aGap from: aStartIndex. + + " ** super send after **" + super shift: aGap from: aStartIndex for: anEventTarget +] + +{ #category : #accessing } +ToListStandardSelectionModel >> unselectableSelecter [ + + ^ unselectableSelecter +] + +{ #category : #accessing } +ToListStandardSelectionModel >> unselectableSelectionModel [ + + ^ self unselectableSelecter selectionModel +] diff --git a/src/Toplo-Widget-List/ToPrimarySelectionModelOperator.class.st b/src/Toplo-Widget-List/ToPrimarySelectionModelOperator.class.st index fcca4e54..98a460d4 100644 --- a/src/Toplo-Widget-List/ToPrimarySelectionModelOperator.class.st +++ b/src/Toplo-Widget-List/ToPrimarySelectionModelOperator.class.st @@ -4,12 +4,6 @@ Class { #category : #'Toplo-Widget-List-Command-Selection' } -{ #category : #'private command application' } -ToPrimarySelectionModelOperator >> listScrollCommand: aCommand in: aTarget [ - - aTarget scrollToIndex: aCommand index -] - { #category : #'private command application' } ToPrimarySelectionModelOperator >> notifySelectionChangedAfter: aCommand in: aTarget [ diff --git a/src/Toplo-Widget-List/ToSecondarySelectionModelOperator.class.st b/src/Toplo-Widget-List/ToSecondarySelectionModelOperator.class.st index 389a370b..5899a9be 100644 --- a/src/Toplo-Widget-List/ToSecondarySelectionModelOperator.class.st +++ b/src/Toplo-Widget-List/ToSecondarySelectionModelOperator.class.st @@ -15,7 +15,7 @@ ToSecondarySelectionModelOperator >> listScrollCommand: aCommand in: aTarget [ sp mouseProcessor lastMouseMoveEvent ifNotNil: [ :e | e consumed: true ] ]. - aTarget scrollToIndex: aCommand index + super listScrollCommand: aCommand in: aTarget ] { #category : #'private command application' } diff --git a/src/Toplo-Widget-List/ToSievedListElementEventHandler.class.st b/src/Toplo-Widget-List/ToSievedListElementEventHandler.class.st index 8905be6f..97fba57b 100644 --- a/src/Toplo-Widget-List/ToSievedListElementEventHandler.class.st +++ b/src/Toplo-Widget-List/ToSievedListElementEventHandler.class.st @@ -37,19 +37,21 @@ ToSievedListElementEventHandler >> buildIndexedDataFrom: aListElement [ ToSievedListElementEventHandler >> collectionFilteredEvent: anEvent [ " the list has been filtered - now deal with the selection " - | target selected | + | target | target := anEvent currentTarget. - selected := sieve pattern - ifNotEmpty: [ - Array streamContents: [ :stream | - target dataAccessor withIndexDo: [ :d :localIndex | - | originalIndex | - originalIndex := dataPositionIndex at: d. - (sieveSelectionModel containsIndex: originalIndex) - ifTrue: [ stream nextPut: localIndex ] ] ] ] - ifEmpty: [ sieveSelectionModel selectedIndexes ]. - target selecter selectOnlyIndexes: selected + sieve pattern + ifNotEmpty: [ + target dataAccessor withIndexDo: [ :d :localIndex | + | originalIndex | + originalIndex := dataPositionIndex at: d. + target selectionModel + transferIndex: originalIndex + from: sieveSelectionModel + as: localIndex ] ] + ifEmpty: [ + self flag: 'Should use copySelectionFrom: with a command '. + target selecter selectOnlyIndexes: sieveSelectionModel selectedIndexes ] ] { #category : #accessing } @@ -145,12 +147,13 @@ ToSievedListElementEventHandler >> listPrimarySelectionChangePreNotificationEven ifEmpty: [ sieveSelectionModel copySelectionFrom: listElement selectionModel ] ifNotEmpty: [ - listElement dataAccessor withIndexDo: [ :d :localIdx | + listElement dataAccessor withIndexDo: [ :d :localIndex | | originalIndex | originalIndex := dataPositionIndex at: d. - (listSelModel containsIndex: localIdx) - ifTrue: [ sieveSelectionModel selectIndex: originalIndex ] - ifFalse: [ sieveSelectionModel deselectIndex: originalIndex ] ] ]. + sieveSelectionModel + transferIndex: localIndex + from: listSelModel + as: originalIndex ] ]. " dispatch a specific, different from the primary selection change event that will be sent after. It is useful for sieve list user that relies on the sieve internal selection to adapt themeself according diff --git a/src/Toplo-Widget-List/ToSievedListElementEventHandler2.class.st b/src/Toplo-Widget-List/ToSievedListElementEventHandler2.class.st deleted file mode 100644 index b970778c..00000000 --- a/src/Toplo-Widget-List/ToSievedListElementEventHandler2.class.st +++ /dev/null @@ -1,228 +0,0 @@ -Class { - #name : #ToSievedListElementEventHandler2, - #superclass : #BlCustomEventHandler, - #instVars : [ - 'sieve', - 'dataPositionIndex', - 'sieveSelectionModel', - 'queryApplicationTask' - ], - #category : #'Toplo-Widget-List-Sieve' -} - -{ #category : #'element handlers' } -ToSievedListElementEventHandler2 >> applyQueryAppliedEvent: anEvent [ - - | listElement | - listElement := anEvent currentTarget. - " a query has occured (because the query pattern has changed), update the list element accordingly " - sieve updateCurrentData. - " update the list element but not the selection " - " *** note that it is required to deselect all here - - the selection is managed after (see #collectionFilteredEvent: ) *** " - listElement selectionModel deselectAll. - listElement dataAccessor filterResult: sieve currentData -] - -{ #category : #'api - hooks' } -ToSievedListElementEventHandler2 >> buildIndexesFrom: aListElement [ - - - dataPositionIndex removeAll. - aListElement dataAccessor withIndexDo: [ :aData :idx | - dataPositionIndex at: aData put: idx ] -] - -{ #category : #'element handlers' } -ToSievedListElementEventHandler2 >> collectionFilteredEvent: anEvent [ - " the list has been filtered - now deal with the selection " - - | target selected | - target := anEvent currentTarget. - - selected := sieve pattern - ifNotEmpty: [ - Array streamContents: [ :stream | - target dataAccessor withIndexDo: [ :d :localIndex | - | originalIndex | - originalIndex := dataPositionIndex at: d. - (sieveSelectionModel containsIndex: originalIndex) - ifTrue: [ stream nextPut: localIndex ] ] ] ] - ifEmpty: [ sieveSelectionModel selectedIndexes ]. - target selecter selectOnlyIndexes: selected -] - -{ #category : #accessing } -ToSievedListElementEventHandler2 >> dataPositionIndex [ - - ^ dataPositionIndex -] - -{ #category : #accessing } -ToSievedListElementEventHandler2 >> dataPositionIndex: aDictionary [ - - dataPositionIndex := aDictionary -] - -{ #category : #'api - accessing' } -ToSievedListElementEventHandler2 >> eventsToHandle [ - - ^ { - ToObservableCollectionFilterResultEvent. - BlInfiniteDataSourceEvent. - ToListChangePreNotificationEvent. - ToCollectionFilteredEvent } -] - -{ #category : #'data events handling' } -ToSievedListElementEventHandler2 >> infiniteDataSourceChanged: anEvent [ - - sieve pattern ifNotEmpty: [ ^ self ]. - self buildIndexesFrom: anEvent currentTarget -] - -{ #category : #'data events handling' } -ToSievedListElementEventHandler2 >> infiniteDataSourceItemRangeChanged: anEvent [ - - sieve pattern ifNotEmpty: [ ^ self ]. - self buildIndexesFrom: anEvent currentTarget -] - -{ #category : #'data events handling' } -ToSievedListElementEventHandler2 >> infiniteDataSourceItemRangeEvent: anEvent [ - - sieve pattern ifNotEmpty: [ ^ self ]. - self buildIndexesFrom: anEvent currentTarget -] - -{ #category : #'data events handling' } -ToSievedListElementEventHandler2 >> infiniteDataSourceItemRangeInserted: anEvent [ - - sieve pattern ifNotEmpty: [ ^ self ]. - self buildIndexesFrom: anEvent currentTarget -] - -{ #category : #'data events handling' } -ToSievedListElementEventHandler2 >> infiniteDataSourceItemRangeRemoved: anEvent [ - - " no need to update dataPositionIndex here " -] - -{ #category : #'element handlers' } -ToSievedListElementEventHandler2 >> listClickOnNodePreNotificationEvent: anEvent [ - -] - -{ #category : #'element handlers' } -ToSievedListElementEventHandler2 >> listDataSourceItemsChangePreNotificationEvent: aPreNotification [ - " don't send the data source add/remove change event if the sieve is filtering" - - sieve pattern ifEmpty: [ - ^ self ]. - " the data source event should not be sent. this is why the source event is changed with nil " - aPreNotification sourceEvent: nil -] - -{ #category : #'element handlers' } -ToSievedListElementEventHandler2 >> listPrimarySelectionChangePreNotificationEvent: aPreNotification [ - " the list selection change event is about to be dispatched. - I take care of the sieve internal selectionSet according to the list element selection model" - - | primSelChangedEvent listElement listSelModel | - listElement := aPreNotification currentTarget. - - " reset the selection in case of single selection mode " - aPreNotification currentTarget isMultipleSelection ifFalse: [ - sieveSelectionModel deselectAll ]. - - primSelChangedEvent := aPreNotification sourceEvent. - listSelModel := primSelChangedEvent selectionModel. - - " the selection set is updated according to the pattern: - - if empty, the whole selection set is set from the whole list element selection model - - if not empty, the selection set is computed according to the current list node list " - sieve pattern - ifEmpty: [ - sieveSelectionModel copySelectionFrom: listElement selectionModel ] - ifNotEmpty: [ - listElement dataAccessor withIndexDo: [ :d :localIdx | - | originalIndex | - originalIndex := dataPositionIndex at: d. - (listSelModel containsIndex: localIdx) - ifTrue: [ sieveSelectionModel selectIndex: originalIndex ] - ifFalse: [ sieveSelectionModel deselectIndex: originalIndex ] ] ]. - - " dispatch a specific, different from the primary selection change event that will be sent after. - It is useful for sieve list user that relies on the sieve internal selection to adapt themeself according - to the sieve selection" - listElement dispatchEvent: (ToSieveSelectionChangedEvent new - selectionModel: sieveSelectionModel copy; - yourself) -] - -{ #category : #'element handlers' } -ToSievedListElementEventHandler2 >> observableCollectionFilterResultEvent: anEvent [ - - | listElement | - listElement := anEvent currentTarget. - - " a query has occured (becuse the query pattern has changed), - update the list element accordingly " - - queryApplicationTask ifNotNil: [ - listElement dequeueTask: queryApplicationTask. - queryApplicationTask := nil ]. - listElement isAttachedToSceneGraph ifFalse: [ - self applyQueryAppliedEvent: anEvent. - ^ self ]. - queryApplicationTask := BlTaskAction new. - queryApplicationTask action: [ - queryApplicationTask := nil. - self applyQueryAppliedEvent: anEvent ]. - listElement enqueueTask: queryApplicationTask -] - -{ #category : #'data events handling' } -ToSievedListElementEventHandler2 >> onChanged: anEvent [ - - self infiniteDataSourceChanged: anEvent -] - -{ #category : #'api - hooks' } -ToSievedListElementEventHandler2 >> onInstalledIn: aListElement [ - - super onInstalledIn: aListElement. - sieveSelectionModel := aListElement selectionModel copy. - self dataPositionIndex: sieve dataPositionIndex. - self buildIndexesFrom: aListElement -] - -{ #category : #'data events handling' } -ToSievedListElementEventHandler2 >> onItemsChanged: anEvent [ - - self infiniteDataSourceItemRangeChanged: anEvent -] - -{ #category : #'data events handling' } -ToSievedListElementEventHandler2 >> onItemsEvent: anEvent [ - - self infiniteDataSourceItemRangeEvent: anEvent -] - -{ #category : #'data events handling' } -ToSievedListElementEventHandler2 >> onItemsInserted: anEvent [ - - self infiniteDataSourceItemRangeInserted: anEvent -] - -{ #category : #'data events handling' } -ToSievedListElementEventHandler2 >> onItemsRemoved: anEvent [ - - self infiniteDataSourceItemRangeRemoved: anEvent -] - -{ #category : #accessing } -ToSievedListElementEventHandler2 >> sieve: aListElementSieve [ - - sieve := aListElementSieve -] diff --git a/src/Toplo-Widget-List/ToStandardSelectionModelOperator.class.st b/src/Toplo-Widget-List/ToStandardSelectionModelOperator.class.st index d1a02ab4..7df06821 100644 --- a/src/Toplo-Widget-List/ToStandardSelectionModelOperator.class.st +++ b/src/Toplo-Widget-List/ToStandardSelectionModelOperator.class.st @@ -3,3 +3,9 @@ Class { #superclass : #ToSelectionModelOperator, #category : #'Toplo-Widget-List-Command-Selection' } + +{ #category : #'command operations' } +ToStandardSelectionModelOperator >> listScrollCommand: aCommand in: aTarget [ + + aTarget scrollToIndex: aCommand index +]