[squeak-dev] The Trunk: Morphic-mt.1582.mcz
Chris Muller
asqueaker at gmail.com
Thu Oct 24 23:36:31 UTC 2019
Very nice, looking forward to trying it out.
Thanks!
On Wed, Oct 23, 2019 at 8:31 AM <commits at source.squeak.org> wrote:
> Marcel Taeumel uploaded a new version of Morphic to project The Trunk:
> http://source.squeak.org/trunk/Morphic-mt.1582.mcz
>
> ==================== Summary ====================
>
> Name: Morphic-mt.1582
> Author: mt
> Time: 23 October 2019, 3:31:24.67861 pm
> UUID: 82af72b9-4198-4bd2-8e7e-e8733d9018c7
> Ancestors: Morphic-mt.1581
>
> Adds things for column-specific list filtering:
>
> - backgroundColor for LazyListMorph
> - optional filter-term indication for LazyListMorph
> - column highlights for multi-column lists
> - Character tab to cycle between columns
>
> Note that I opted to not use the [space] key for column toggling because
> (a) we have to widget-focus cycling via [tab] at the moment and (b) the
> space character might be a valuable filter term.
>
> =============== Diff against Morphic-mt.1581 ===============
>
> Item was changed:
> Morph subclass: #LazyListMorph
> + instanceVariableNames: 'listItems listIcons listFilterOffsets font
> selectedRow selectedRows preSelectedRow listSource maxWidth columnIndex
> iconExtent backgroundColor showFilter'
> - instanceVariableNames: 'listItems listIcons listFilterOffsets font
> selectedRow selectedRows preSelectedRow listSource maxWidth columnIndex
> iconExtent'
> classVariableNames: ''
> poolDictionaries: ''
> category: 'Morphic-Widgets'!
>
> !LazyListMorph commentStamp: 'mt 10/13/2019 19:44' prior: 0!
> The morph that displays the list in a PluggableListMorph. It is "lazy"
> because it will only request the list items that it actually needs to
> display.
>
> I will cache the maximum width of my items in maxWidth to avoid this
> potentially expensive and frequent computation.
>
> The following layout properties are supported:
> - #cellPositioning: #leftCenter [default], #center, #rightCenter
> - #cellInset: [default: 3 at 0 corner: 3 at 0]!
>
> Item was added:
> + ----- Method: LazyListMorph>>backgroundColor (in category 'accessing')
> -----
> + backgroundColor
> + "Since #color is this morph's default text color, this extra
> property is used for the actual background color. Supports nil."
> +
> + ^ backgroundColor!
>
> Item was added:
> + ----- Method: LazyListMorph>>backgroundColor: (in category 'accessing')
> -----
> + backgroundColor: aColor
> +
> + backgroundColor = aColor ifTrue: [^ self].
> + backgroundColor := aColor.
> +
> + self changed.
> + "Invalidate owner because we want to fill the vertical axis in the
> viewport entirely."
> + self owner ifNotNil: [:o | o changed].!
>
> Item was changed:
> ----- Method: LazyListMorph>>displayFilterOn:for:in:font: (in category
> 'drawing') -----
> displayFilterOn: canvas for: row in: drawBounds font: font
> "Draw filter matches if any."
>
> | fillStyle fillHeight |
> + self showFilter ifFalse: [^ self].
> - listSource filterableList ifFalse: [^ self].
>
> fillHeight := font height.
> fillStyle := self filterColor isColor
> ifTrue: [SolidFillStyle color: self filterColor]
> ifFalse: [self filterColor].
> fillStyle isGradientFill ifTrue: [
> fillStyle origin: drawBounds topLeft.
> fillStyle direction: 0@ fillHeight].
>
> (self filterOffsets: row) do: [:offset |
> | highlightRectangle |
> highlightRectangle := ((drawBounds left + offset first
> first) @ drawBounds top
> corner: (drawBounds left + offset first last) @
> (drawBounds top + fillHeight)).
> canvas
> frameAndFillRoundRect: (highlightRectangle
> outsetBy: 1 at 0)
> radius: (3 * RealEstateAgent scaleFactor) truncated
> fillStyle: fillStyle
> borderWidth: (1 * RealEstateAgent scaleFactor)
> truncated
> borderColor: fillStyle asColor twiceDarker.
> canvas
> drawString: offset second
> in: highlightRectangle
> font: font
> color: self filterTextColor].!
>
> Item was changed:
> ----- Method: LazyListMorph>>drawOn: (in category 'drawing') -----
> drawOn: aCanvas
>
> | topRow bottomRow |
> + self backgroundColor ifNotNil: [:color |
> + aCanvas fillRectangle: (self topLeft corner: self right @
> ((self owner ifNil: [self]) bottom)) color: color].
> +
> self getListSize = 0 ifTrue: [ ^self ].
>
> self drawPreSelectionOn: aCanvas.
>
> topRow := self topVisibleRowForCanvas: aCanvas.
> bottomRow := self bottomVisibleRowForCanvas: aCanvas.
>
> "Draw multi-selection."
> self listSource hasMultiSelection ifTrue: [
> topRow to: bottomRow do: [ :row |
> (self listSource itemSelectedAmongMultiple: row)
> ifTrue: [
> self drawBackgroundForMulti: row on:
> aCanvas ] ] ].
> self drawSelectionOn: aCanvas.
>
> "Draw hovered row if preference enabled."
> PluggableListMorph highlightHoveredRow ifTrue: [
> self listSource hoverRow > 0 ifTrue: [
> self highlightHoverRow: listSource hoverRow on:
> aCanvas ] ].
>
> "Draw all visible rows."
> topRow to: bottomRow do: [ :row |
> self display: (self item: row) atRow: row on: aCanvas ].
>
> "Finally, highlight drop row for drag/drop operations.."
> self listSource potentialDropRow > 0 ifTrue: [
> self highlightPotentialDropRow: self listSource
> potentialDropRow on: aCanvas ].!
>
> Item was added:
> + ----- Method: LazyListMorph>>showFilter (in category 'accessing') -----
> + showFilter
> +
> + ^ (showFilter ~~ false and: [listSource filterableList])!
>
> Item was added:
> + ----- Method: LazyListMorph>>showFilter: (in category 'accessing') -----
> + showFilter: aBoolean
> +
> + showFilter = aBoolean ifTrue: [^ self].
> + showFilter := aBoolean.
> + self changed.!
>
> Item was added:
> + ----- Method: PluggableMultiColumnListMorph>>filterColumnColor (in
> category 'filtering') -----
> + filterColumnColor
> +
> + ^ (Color gray: 0.85) alpha: 0.4!
>
> Item was added:
> + ----- Method: PluggableMultiColumnListMorph>>filterColumnIndex (in
> category 'filtering') -----
> + filterColumnIndex
> + "Which column to apply the filter to?"
> +
> + | i |
> + i := 0.
> + self listMorphs
> + detect: [:m | i := i + 1. m backgroundColor notNil]
> + ifNone: [i := 0].
> + ^ i!
>
> Item was added:
> + ----- Method:
> PluggableMultiColumnListMorph>>filterList:columnIndex:matching: (in
> category 'filtering') -----
> + filterList: columns columnIndex: index matching: aPattern
> + "A matching row has a match in at least one column."
> +
> + | frontMatching substringMatching rowCount columnCount tmp |
> + aPattern ifEmpty: [^ columns].
> + columns ifEmpty: [^ columns].
> +
> + rowCount := columns first size.
> + rowCount = 0 ifTrue: [^ columns].
> + columnCount := columns size.
> +
> + frontMatching := Array new: columnCount.
> + 1 to: columnCount do: [:c | frontMatching at: c put:
> OrderedCollection new].
> + substringMatching := Array new: columnCount.
> + 1 to: columnCount do: [:c | substringMatching at: c put:
> OrderedCollection new].
> +
> + modelToView := Dictionary new.
> + viewToModel := Dictionary new.
> + tmp := OrderedCollection new.
> +
> + 1 to: rowCount do: [:rowIndex |
> + | match foundPos |
> + match := false.
> + foundPos := self
> + filterListItem: ((columns
> at: index) at: rowIndex)
> + matching: aPattern.
> + foundPos = 1
> + ifTrue: [
> + 1 to: columnCount do: [:colIndex |
> + (frontMatching at: colIndex) add:
> ((columns at: colIndex) at: rowIndex)].
> + modelToView at: rowIndex put:
> frontMatching first size.
> + viewToModel at: frontMatching first size
> put: rowIndex]
> + ifFalse: [foundPos > 1 ifTrue: [
> + 1 to: columnCount do: [:colIndex |
> + (substringMatching at: colIndex)
> add: ((columns at: colIndex) at: rowIndex)].
> + tmp add: rowIndex; add: substringMatching
> first size]]
> + ].
> +
> + tmp pairsDo: [:modelIndex :viewIndex |
> + modelToView at: modelIndex put: viewIndex + frontMatching
> first size.
> + viewToModel at: viewIndex + frontMatching first size put:
> modelIndex].
> +
> + ^ (1 to: columnCount) collect: [:colIndex |
> + (frontMatching at: colIndex), (substringMatching at:
> colIndex)]
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> +
> + !
>
> Item was changed:
> ----- Method: PluggableMultiColumnListMorph>>filterList:matching: (in
> category 'filtering') -----
> filterList: columns matching: aPattern
> "A matching row has a match in at least one column."
>
> | frontMatching substringMatching rowCount columnCount tmp |
> aPattern ifEmpty: [^ columns].
> columns ifEmpty: [^ columns].
>
> + "Enable column-specific filtering."
> + self filterColumnIndex in: [:index |
> + index > 0 ifTrue: [^ self filterList: columns columnIndex:
> index matching: aPattern]].
> +
> rowCount := columns first size.
> rowCount = 0 ifTrue: [^ columns].
> columnCount := columns size.
>
> frontMatching := Array new: columnCount.
> 1 to: columnCount do: [:c | frontMatching at: c put:
> OrderedCollection new].
> substringMatching := Array new: columnCount.
> 1 to: columnCount do: [:c | substringMatching at: c put:
> OrderedCollection new].
>
> modelToView := Dictionary new.
> viewToModel := Dictionary new.
> tmp := OrderedCollection new.
>
> 1 to: rowCount do: [:rowIndex |
> | match foundPos |
> match := false.
> foundPos := 0.
> 1 to: columnCount do: [:colIndex |
> match := match or: [(foundPos := (self
>
> filterListItem: ((columns at: colIndex) at: rowIndex)
>
> matching: aPattern)+colIndex) > colIndex]].
> match & (foundPos = 2) "means front match in first column"
> ifTrue: [
> 1 to: columnCount do: [:colIndex |
> (frontMatching at: colIndex) add:
> ((columns at: colIndex) at: rowIndex)].
> modelToView at: rowIndex put:
> frontMatching first size.
> viewToModel at: frontMatching first size
> put: rowIndex]
> ifFalse: [match ifTrue: [
> 1 to: columnCount do: [:colIndex |
> (substringMatching at: colIndex)
> add: ((columns at: colIndex) at: rowIndex)].
> tmp add: rowIndex; add: substringMatching
> first size]]
> ].
>
> tmp pairsDo: [:modelIndex :viewIndex |
> modelToView at: modelIndex put: viewIndex + frontMatching
> first size.
> viewToModel at: viewIndex + frontMatching first size put:
> modelIndex].
>
> ^ (1 to: columnCount) collect: [:colIndex |
> (frontMatching at: colIndex), (substringMatching at:
> colIndex)]
>
>
>
>
>
>
>
>
>
>
>
>
>
> !
>
> Item was added:
> + ----- Method: PluggableMultiColumnListMorph>>highlightNextColumn (in
> category 'filtering') -----
> + highlightNextColumn
> +
> + | i currentColumn nextColumn |
> + i := self filterColumnIndex.
> + i = 0 ifTrue: [self listMorphs do: [:m | m showFilter: false]].
> +
> + currentColumn := self listMorphs at: (i max: 1).
> + nextColumn := self listMorphs at: i \\ self listMorphs size + 1.
> +
> + currentColumn
> + showFilter: false;
> + backgroundColor: nil.
> +
> + nextColumn
> + showFilter: true;
> + backgroundColor: self filterColumnColor.!
>
> Item was added:
> + ----- Method: PluggableMultiColumnListMorph>>highlightNoColumn (in
> category 'filtering') -----
> + highlightNoColumn
> +
> + self listMorphs do: [:m |
> + m showFilter: true; backgroundColor: nil].!
>
> Item was added:
> + ----- Method: PluggableMultiColumnListMorph>>removeFilter (in category
> 'filtering') -----
> + removeFilter
> +
> + self highlightNoColumn.
> + super removeFilter.
> + !
>
> Item was added:
> + ----- Method: PluggableMultiColumnListMorph>>specialKeyPressed: (in
> category 'filtering') -----
> + specialKeyPressed: asciiValue
> + "Use the [Tab] key to filter specific columns."
> +
> + ^ asciiValue = Character tab asciiValue
> + ifTrue: [self highlightNextColumn]
> + ifFalse: [super specialKeyPressed: asciiValue].!
>
> Item was changed:
> ----- Method: PluggableMultiColumnListMorph>>updateColumns (in category
> 'updating') -----
> updateColumns
> "The number of columns must match the number of list morphs."
>
> | columnsChanged |
> columnsChanged := self columnCount ~= listMorphs size.
>
> [self columnCount < listMorphs size]
> whileTrue: [
> listMorphs removeLast delete].
>
> [self columnCount > listMorphs size]
> whileTrue: [
> listMorphs addLast: self createListMorph.
> self scroller addMorphBack: listMorphs last].
>
> listMorphs doWithIndex: [:listMorph :columnIndex |
> listMorph
> columnIndex: columnIndex;
> + color: self textColor;
> cellPositioning: (self cellPositioningAtColumn:
> columnIndex);
> cellInset: (self cellInsetAtColumn: columnIndex);
> hResizing: (self hResizingAtColumn: columnIndex);
> spaceFillWeight: (self spaceFillWeightAtColumn:
> columnIndex)].
>
> columnsChanged ifTrue: [self setListParameters].!
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20191024/fff5b12f/attachment.html>
More information about the Squeak-dev
mailing list
|