From 4137e8e541352547ee63c3e4d05429438b916d1e Mon Sep 17 00:00:00 2001 From: Esteban Lorenzano Date: Wed, 23 Oct 2019 17:34:15 +0200 Subject: [PATCH 1/3] add not homogenous container morph and capabilities to FTTableMorph --- .../FTDataSource.class.st | 6 ++ .../FTExampleMethodListDataSource.class.st | 3 +- ...ethodNotHomogeneousListDataSource.class.st | 28 +++++++ .../FTExamples.class.st | 16 +++- .../FTTableContainerMorph.class.st | 76 +++++++++++-------- ...leContainerRowNotHomogeneousMorph.class.st | 34 +++++++++ .../FTTableMorph.class.st | 14 ++++ 7 files changed, 143 insertions(+), 34 deletions(-) create mode 100644 src/Morphic-Widgets-FastTable/FTExampleMethodNotHomogeneousListDataSource.class.st create mode 100644 src/Morphic-Widgets-FastTable/FTTableContainerRowNotHomogeneousMorph.class.st diff --git a/src/Morphic-Widgets-FastTable/FTDataSource.class.st b/src/Morphic-Widgets-FastTable/FTDataSource.class.st index 3ac69d9cea2..fca87064884 100644 --- a/src/Morphic-Widgets-FastTable/FTDataSource.class.st +++ b/src/Morphic-Widgets-FastTable/FTDataSource.class.st @@ -125,6 +125,12 @@ FTDataSource >> realElementAt: anIndex [ ^ self elementAt: anIndex ] +{ #category : #accessing } +FTDataSource >> rowHeight: roIndex [ + + ^ self table rowHeight +] + { #category : #accessing } FTDataSource >> searchText: aString [ "search a text and answers a list of elements indexes matching condition. diff --git a/src/Morphic-Widgets-FastTable/FTExampleMethodListDataSource.class.st b/src/Morphic-Widgets-FastTable/FTExampleMethodListDataSource.class.st index 5ba22d499ab..72fa5c82612 100644 --- a/src/Morphic-Widgets-FastTable/FTExampleMethodListDataSource.class.st +++ b/src/Morphic-Widgets-FastTable/FTExampleMethodListDataSource.class.st @@ -22,7 +22,8 @@ FTExampleMethodListDataSource class >> for: aClass [ ] { #category : #accessing } -FTExampleMethodListDataSource >> cellColumn: column row: rowIndex [ +FTExampleMethodListDataSource >> cellColumn: column row: rowIndex [ + ^ FTCellMorph new cellInset: 5; addMorphBack: (self iconFor: rowIndex) asMorph; diff --git a/src/Morphic-Widgets-FastTable/FTExampleMethodNotHomogeneousListDataSource.class.st b/src/Morphic-Widgets-FastTable/FTExampleMethodNotHomogeneousListDataSource.class.st new file mode 100644 index 00000000000..cd032d8b75c --- /dev/null +++ b/src/Morphic-Widgets-FastTable/FTExampleMethodNotHomogeneousListDataSource.class.st @@ -0,0 +1,28 @@ +Class { + #name : #FTExampleMethodNotHomogeneousListDataSource, + #superclass : #FTExampleMethodListDataSource, + #category : #'Morphic-Widgets-FastTable-Examples' +} + +{ #category : #accessing } +FTExampleMethodNotHomogeneousListDataSource >> cellColumn: column row: rowIndex [ + + ^ FTCellMorph new + cellInset: 5; + addMorphBack: (self iconFor: rowIndex) asMorph; + addMorphBack: (Morph new + changeTableLayout; + hResizing: #shrinkWrap; + listDirection: #topToBottom; + color: Color transparent; + addMorphBack: ((self elementAt: rowIndex) protocol asMorph emphasis: 2r10); + addMorphBack: (self elementAt: rowIndex) name asMorph; + yourself); + yourself +] + +{ #category : #accessing } +FTExampleMethodNotHomogeneousListDataSource >> rowHeight: rowIndex [ + + ^ 50 +] diff --git a/src/Morphic-Widgets-FastTable/FTExamples.class.st b/src/Morphic-Widgets-FastTable/FTExamples.class.st index 559a5d0db79..cb82a708d36 100644 --- a/src/Morphic-Widgets-FastTable/FTExamples.class.st +++ b/src/Morphic-Widgets-FastTable/FTExamples.class.st @@ -19,7 +19,6 @@ FTExamples class >> example1 [ sorted: [ :a :b | a name < b name])); yourself. list openInWindow - ] { #category : #examples } @@ -503,6 +502,21 @@ FTExamples class >> exampleOutline2 [ list openInWindow ] +{ #category : #examples } +FTExamples class >> exampleRowNotHomogeneousList1 [ + "Show a list with all Object methods" + + | list | + + list := FTTableMorph new + extent: 300@550; + beRowNotHomogeneous; + dataSource: (FTExampleMethodNotHomogeneousListDataSource for: Object); + yourself. + + ^ list openInWindow +] + { #category : #examples } FTExamples class >> exampleSortableList [ "Show a list with all Object methods with a header" diff --git a/src/Morphic-Widgets-FastTable/FTTableContainerMorph.class.st b/src/Morphic-Widgets-FastTable/FTTableContainerMorph.class.st index 63e8e1b7a65..614280c267a 100644 --- a/src/Morphic-Widgets-FastTable/FTTableContainerMorph.class.st +++ b/src/Morphic-Widgets-FastTable/FTTableContainerMorph.class.st @@ -115,17 +115,16 @@ FTTableContainerMorph >> calculateMinVisibleRows [ FTTableContainerMorph >> calculateStartIndexWhenShowing: visibleRows [ "Answer the first row to show when showing visibleRows rows. This works in case we are exceeding the available rows to show" - | currentIndex startIndex oldIndex | + currentIndex := self table showIndex. - currentIndex + visibleRows - 1 > self table numberOfRows ifTrue: [ - currentIndex := self table numberOfRows - visibleRows + 2]. + currentIndex + visibleRows - 1 > self table numberOfRows + ifTrue: [ currentIndex := self table numberOfRows - visibleRows + 2 ]. startIndex := currentIndex max: 1. oldIndex := self table showIndex. self table basicMoveShowIndexTo: startIndex. self table announceScrollChangedFrom: oldIndex to: self table showIndex. - ^startIndex - + ^ startIndex ] { #category : #private } @@ -179,15 +178,27 @@ FTTableContainerMorph >> defaultColor [ { #category : #drawing } FTTableContainerMorph >> drawOn: canvas [ - | x y cellWidth cellHeight rowsToDisplay rowSubviews highligtedIndexes primarySelectionIndex | + super drawOn: canvas. + self drawRowsOn: canvas +] + +{ #category : #drawing } +FTTableContainerMorph >> drawOnAthensCanvas: anAthensCanvas [ + self drawOnCanvasWrapperFor: anAthensCanvas +] + +{ #category : #drawing } +FTTableContainerMorph >> drawRowsOn: canvas [ + | x y cellWidth cellHeight rowsToDisplay rowSubviews highligtedIndexes primarySelectionIndex | + self canRefreshValues ifFalse: [ ^ self ]. "Nothing to update yet" x := self left + self class rowLeftMargin. y := self top. cellWidth := self width - self class rowLeftMargin. cellHeight := self table rowHeight rounded. - highligtedIndexes := self table selectedIndexes , self table highlightedIndexes. + highligtedIndexes := self table selectedIndexes, self table highlightedIndexes. primarySelectionIndex := self table selectedIndex. "For some superweird reason, calling #calculateExposedRows here instead in #changed (where @@ -198,47 +209,41 @@ FTTableContainerMorph >> drawOn: canvas [ rowsToDisplay := self exposedRows. rowSubviews := OrderedCollection new: rowsToDisplay size + 1. - headerRow - ifNotNil: [ headerRow bounds: (self left @ y extent: self width @ cellHeight). - y := y + cellHeight + self table intercellSpacing y. - rowSubviews add: headerRow ]. + headerRow ifNotNil: [ + headerRow bounds: (self left @ y extent: self width @ cellHeight). + y := y + cellHeight + self table intercellSpacing y. + rowSubviews add: headerRow ]. - rowsToDisplay - keysAndValuesDo: [ :rowIndex :row | - | visibleHeight | - visibleHeight := cellHeight min: self bottom - y. - row bounds: (x @ y extent: cellWidth @ visibleHeight). - y := y + visibleHeight + self table intercellSpacing y. + rowsToDisplay keysAndValuesDo: [ :rowIndex :row | + | visibleHeight | + visibleHeight := (self rowHeight: rowIndex default: cellHeight) min: self bottom - y. + row bounds: (x @ y extent: cellWidth @ visibleHeight). + y := y + visibleHeight + self table intercellSpacing y. - rowSubviews add: row. + rowSubviews add: row. - (self table selectionModeStrategy + (self table selectionModeStrategy selectablesToHighlightFromRow: row at: rowIndex withHighlightedIndexes: highligtedIndexes - andPrimaryIndex: primarySelectionIndex) keysAndValuesDo: [ :morph :isPrimary | morph selectionColor: (self table colorForSelection: isPrimary) ] ]. + andPrimaryIndex: primarySelectionIndex) + keysAndValuesDo: [ :morph :isPrimary | + morph selectionColor: (self table colorForSelection: isPrimary) ] ]. "We should notify existing rows about deletion and new rows about insertion. It is required to correctly manage stepping animation of cells" - submorphs - do: [ :each | - each - privateOwner: nil; - outOfWorld: self world ]. + submorphs do: [ :each | + each + privateOwner: nil; + outOfWorld: self world ]. submorphs := rowSubviews asArray. submorphs do: [ :each | each intoWorld: self world ]. self table isResizable ifTrue: [ self addResizeSplitters ]. - needsRefreshExposedRows := false ] -{ #category : #drawing } -FTTableContainerMorph >> drawOnAthensCanvas: anAthensCanvas [ - self drawOnCanvasWrapperFor: anAthensCanvas -] - { #category : #private } FTTableContainerMorph >> exposedRows [ "Answer a dictionary of rowIndex->row pairs" @@ -322,6 +327,12 @@ FTTableContainerMorph >> rowAndColumnIndexContainingPoint: aPoint [ ^ {nil. nil} ] +{ #category : #private } +FTTableContainerMorph >> rowHeight: rowIndex default: aNumber [ + + ^ aNumber +] + { #category : #accessing } FTTableContainerMorph >> rowIndexContainingPoint: aPoint [ self exposedRows keysAndValuesDo: [ :rowIndex :row | @@ -342,10 +353,11 @@ FTTableContainerMorph >> table [ { #category : #updating } FTTableContainerMorph >> updateAllRows [ + self table isShowColumnHeaders ifTrue: [ self updateHeaderRow ] ifFalse: [ headerRow := nil ]. - self updateExposedRows. + self updateExposedRows ] diff --git a/src/Morphic-Widgets-FastTable/FTTableContainerRowNotHomogeneousMorph.class.st b/src/Morphic-Widgets-FastTable/FTTableContainerRowNotHomogeneousMorph.class.st new file mode 100644 index 00000000000..de275548981 --- /dev/null +++ b/src/Morphic-Widgets-FastTable/FTTableContainerRowNotHomogeneousMorph.class.st @@ -0,0 +1,34 @@ +" +I contain table rows, but opposite to my parent, I calculate my row heights allowing users to display tables with rows of different height. +" +Class { + #name : #FTTableContainerRowNotHomogeneousMorph, + #superclass : #FTTableContainerMorph, + #category : #'Morphic-Widgets-FastTable' +} + +{ #category : #private } +FTTableContainerRowNotHomogeneousMorph >> calculateExactVisibleRows [ + "Answer the rows to show in list - with possible fraction" + | rowIndex maxHeight height | + + self table hasDataSource ifFalse: [ + ^ super calculateExactVisibleRows ]. + + rowIndex := self table showIndex. + height := 0. + maxHeight := self height. + headerRow ifNotNil: [ maxHeight := maxHeight - headerRow height ]. + + [ height < maxHeight ] whileTrue: [ + height := height + (self table dataSource rowHeight: rowIndex). + rowIndex := rowIndex + 1 ]. + + ^ rowIndex - self table showIndex +] + +{ #category : #drawing } +FTTableContainerRowNotHomogeneousMorph >> rowHeight: rowIndex default: aNumber [ + + ^ self table dataSource rowHeight: rowIndex +] diff --git a/src/Morphic-Widgets-FastTable/FTTableMorph.class.st b/src/Morphic-Widgets-FastTable/FTTableMorph.class.st index de3d74c19b5..c9850b6358d 100644 --- a/src/Morphic-Widgets-FastTable/FTTableMorph.class.st +++ b/src/Morphic-Widgets-FastTable/FTTableMorph.class.st @@ -192,6 +192,20 @@ FTTableMorph >> beResizable [ resizable := true ] +{ #category : #accessing } +FTTableMorph >> beRowNotHomogeneous [ + "by default, tables have homogeneous row heigths, taken from rowHeight variable. + We can switch to variable size by sending this message. + The resulting table will be less effcicient than the first, but probably not in a way users + can notice" + | oldContainer | + + oldContainer := container. + container := FTTableContainerRowNotHomogeneousMorph new. + self replaceSubmorph: oldContainer by: container. + self resizeAllSubviews +] + { #category : #accessing } FTTableMorph >> beRowSelection [ self selectionModeStrategy: (FTRowSelectionModeStrategy table: self) From 88959cf947031d5c96bf275a794167ac6d309825 Mon Sep 17 00:00:00 2001 From: Esteban Lorenzano Date: Thu, 24 Oct 2019 15:21:40 +0200 Subject: [PATCH 2/3] I forgot to check for row limit --- .../FTTableContainerRowNotHomogeneousMorph.class.st | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Morphic-Widgets-FastTable/FTTableContainerRowNotHomogeneousMorph.class.st b/src/Morphic-Widgets-FastTable/FTTableContainerRowNotHomogeneousMorph.class.st index de275548981..df53b07be55 100644 --- a/src/Morphic-Widgets-FastTable/FTTableContainerRowNotHomogeneousMorph.class.st +++ b/src/Morphic-Widgets-FastTable/FTTableContainerRowNotHomogeneousMorph.class.st @@ -20,7 +20,8 @@ FTTableContainerRowNotHomogeneousMorph >> calculateExactVisibleRows [ maxHeight := self height. headerRow ifNotNil: [ maxHeight := maxHeight - headerRow height ]. - [ height < maxHeight ] whileTrue: [ + [ (height < maxHeight) and: [ rowIndex <= self table dataSource numberOfRows ] ] + whileTrue: [ height := height + (self table dataSource rowHeight: rowIndex). rowIndex := rowIndex + 1 ]. From b718da99d47eb937c4bca474fdebf22383b15f4c Mon Sep 17 00:00:00 2001 From: Esteban Lorenzano Date: Thu, 24 Oct 2019 15:40:54 +0200 Subject: [PATCH 3/3] and we need to be sure showIndex is at least one --- .../FTTableContainerRowNotHomogeneousMorph.class.st | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Morphic-Widgets-FastTable/FTTableContainerRowNotHomogeneousMorph.class.st b/src/Morphic-Widgets-FastTable/FTTableContainerRowNotHomogeneousMorph.class.st index df53b07be55..1b12238206b 100644 --- a/src/Morphic-Widgets-FastTable/FTTableContainerRowNotHomogeneousMorph.class.st +++ b/src/Morphic-Widgets-FastTable/FTTableContainerRowNotHomogeneousMorph.class.st @@ -15,7 +15,7 @@ FTTableContainerRowNotHomogeneousMorph >> calculateExactVisibleRows [ self table hasDataSource ifFalse: [ ^ super calculateExactVisibleRows ]. - rowIndex := self table showIndex. + rowIndex := self table showIndex max: 1. height := 0. maxHeight := self height. headerRow ifNotNil: [ maxHeight := maxHeight - headerRow height ].