Marcel Taeumel uploaded a new version of Morphic to project The Trunk: http://source.squeak.org/trunk/Morphic-mt.2105.mcz
==================== Summary ====================
Name: Morphic-mt.2105 Author: mt Time: 17 April 2023, 11:10:21.029908 am UUID: 78d49dc0-9675-804f-85c7-fe3b06d397a2 Ancestors: Morphic-mt.2104
Adds #autoExpand feature to tree widgets where toggle-buttons are hidden, root-indent is 0, and the entire hierarchy is visible all the time. Only works for finite tree structures. Use #autoExpand to improve user experience through minimized input.
=============== Diff against Morphic-mt.2104 ===============
Item was changed: ----- Method: IndentingListItemMorph>>drawLineToggleToTextOn:lineColor:hasToggle: (in category 'drawing') ----- drawLineToggleToTextOn: aCanvas lineColor: lineColor hasToggle: hasToggle "If I am not the only item in my container, draw the line between: - my toggle (if any) or my left edge (if no toggle) - and my text left edge"
| myBounds myCenter hLineY hLineLeft | self isSoleItem ifTrue: [ ^self ]. + (self canExpand and: [container autoExpand == false]) ifTrue: [ ^self ]. - self canExpand ifTrue: [ ^self ]. myBounds := self toggleBounds. myCenter := myBounds center. hLineY := myCenter y. hLineLeft := myCenter x. "Draw line from toggle to text" aCanvas line: hLineLeft @ hLineY to: myBounds right @ hLineY width: 1 px color: lineColor!
Item was changed: ----- Method: IndentingListItemMorph>>drawToggleOn:in: (in category 'drawing') ----- drawToggleOn: aCanvas in: aRectangle
| aForm centeringOffset | self canExpand ifFalse: [^self]. + container autoExpand == true ifTrue: [^ self]. aForm := isExpanded ifTrue: [container expandedForm] ifFalse: [container notExpandedForm]. centeringOffset := (aRectangle extent - aForm extent) // 2. isExpanded ifFalse: [centeringOffset := centeringOffset + (1 px @ 0)]. ^aCanvas paintImage: aForm at: aRectangle topLeft + centeringOffset. !
Item was changed: ----- Method: IndentingListItemMorph>>toggleRectangle (in category 'private') ----- toggleRectangle
+ | h indent offset | - | h indent | h := bounds height. indent := 12 px. + offset := container autoExpand == true ifTrue: [-1] ifFalse: [0]. + ^(bounds left + self hMargin + (indent * (indentLevel+offset))) @ bounds top extent: indent@h! - ^(bounds left + self hMargin + (indent * indentLevel)) @ bounds top extent: indent@h!
Item was changed: ScrollPane subclass: #SimpleHierarchicalListMorph + instanceVariableNames: 'selectedMorph hoveredMorph getListSelector keystrokeActionSelector autoDeselect autoExpand autoExpandSelector columns columnsCache sortingSelector getSelectionSelector setSelectionSelector potentialDropMorph lineColor font textColor' - instanceVariableNames: 'selectedMorph hoveredMorph getListSelector keystrokeActionSelector autoDeselect columns columnsCache sortingSelector getSelectionSelector setSelectionSelector potentialDropMorph lineColor font textColor' classVariableNames: 'ExpandAllLimit ExpandedForm NotExpandedForm WrappedNavigation' poolDictionaries: '' category: 'Morphic-Explorer'!
!SimpleHierarchicalListMorph commentStamp: 'ls 3/1/2004 12:15' prior: 0! Display a hierarchical list of items. Each item should be wrapped with a ListItemWrapper.
For a simple example, look at submorphsExample. For beefier examples, look at ObjectExplorer or FileList2.!
Item was changed: ----- Method: SimpleHierarchicalListMorph>>arrowKey: (in category 'keyboard navigation') ----- arrowKey: asciiValue "Handle a keyboard navigation character. Answer true if handled, false if not." | keyEvent min max oldSelection nextSelection howManyItemsShowing keyHandled | keyHandled := false. keyEvent := asciiValue. max := self maximumSelection. min := self minimumSelection. nextSelection := oldSelection := self getSelectionIndex. keyEvent = 31 ifTrue:["down" self currentEvent shiftPressed ifTrue: [ self selectedMorph nextVisibleSibling ifNil: ["TODO: wrappedNavigation" ^ true] ifNotNil: [:m | self setSelectedMorph: m. ^ true]]. keyHandled := true. nextSelection :=oldSelection + 1. nextSelection > max ifTrue: [nextSelection := (self class wrappedNavigation ifTrue: [min] ifFalse: [^ true])]]. keyEvent = 30 ifTrue:["up" self currentEvent shiftPressed ifTrue: [ self selectedMorph previousVisibleSibling ifNil: ["TODO: wrappedNaviagtion" ^ true] ifNotNil: [:m | self setSelectedMorph: m. ^ true]]. keyHandled := true. nextSelection := oldSelection - 1. nextSelection < min ifTrue: [nextSelection := self class wrappedNavigation ifTrue: [max] ifFalse: [^ true]]]. keyEvent = 1 ifTrue: ["home" keyHandled := true. nextSelection := min]. keyEvent = 4 ifTrue: ["end" keyHandled := true. nextSelection := max]. howManyItemsShowing := self numSelectionsInView. keyEvent = 11 ifTrue: ["page up" keyHandled := true. nextSelection := min max: oldSelection - howManyItemsShowing]. keyEvent = 12 ifTrue: ["page down" keyHandled := true. nextSelection := oldSelection + howManyItemsShowing min: max].
(nextSelection ~= oldSelection or: [ keyHandled and: [ self class wrappedNavigation not ]]) ifTrue: [ self setSelectionIndex: nextSelection. ^ true]. keyEvent = 29 ifTrue:["right" + autoExpand == true ifTrue: [^ true]. selectedMorph ifNotNil:[ (selectedMorph canExpand and:[selectedMorph isExpanded not]) ifTrue:[self currentEvent shiftPressed ifTrue: [self expandAllSafely: selectedMorph] ifFalse: [self toggleExpandedState: selectedMorph]] ifFalse:[self setSelectionIndex: self getSelectionIndex+1]. ]. ^true]. keyEvent = 28 ifTrue:["left" + autoExpand == true ifTrue: [^ true]. selectedMorph ifNotNil:[ (selectedMorph isExpanded) ifTrue:[self toggleExpandedState: selectedMorph] ifFalse:[ self selectedParentMorph ifNil: [self setSelectionIndex: (self getSelectionIndex-1 max: 1)] ifNotNil: [:pm | self setSelectedMorph: pm]] ]. ^true]. ^false!
Item was added: + ----- Method: SimpleHierarchicalListMorph>>autoExpand (in category 'accessing') ----- + autoExpand + + ^ autoExpand == true!
Item was added: + ----- Method: SimpleHierarchicalListMorph>>autoExpand: (in category 'accessing') ----- + autoExpand: aBoolean + + autoExpand := aBoolean.!
Item was added: + ----- Method: SimpleHierarchicalListMorph>>autoExpandSelector (in category 'accessing') ----- + autoExpandSelector + + ^ autoExpandSelector!
Item was added: + ----- Method: SimpleHierarchicalListMorph>>autoExpandSelector: (in category 'accessing') ----- + autoExpandSelector: aSymbol + + autoExpandSelector := aSymbol.!
Item was added: + ----- Method: SimpleHierarchicalListMorph>>expandAllRoots (in category 'events') ----- + expandAllRoots + "Expand all, starting with the receiver's roots. Unlike #expandAll, which starts with the current selection." + + self roots do: [:ea | self expandAll: ea]. + self adjustSubmorphPositions.!
Item was changed: ----- Method: SimpleHierarchicalListMorph>>list: (in category 'initialization') ----- list: aCollection
| wereExpanded morphList | + wereExpanded := autoExpand == true + ifTrue: [#()] + ifFalse: [self currentlyExpanded]. - wereExpanded := self currentlyExpanded. scroller removeAllMorphs. (aCollection isNil or: [aCollection isEmpty]) ifTrue: [^ self selectedMorph: nil]. morphList := OrderedCollection new. self addMorphsTo: morphList from: aCollection allowSorting: false withExpandedItems: wereExpanded atLevel: 0. + self insertNewMorphs: morphList. + autoExpand == true ifTrue: [self expandAllRoots].! - self insertNewMorphs: morphList.!
Item was changed: ----- Method: SimpleHierarchicalListMorph>>toggleExpandedState:event: (in category 'events') ----- toggleExpandedState: aMorph event: aMouseEvent "Mouse navigation. Thus, avoid changing scroll position. See #toggleExpandedState: for keyboard navigation."
+ autoExpand == true ifTrue: [^ self]. aMorph toggleExpandedState. self adjustSubmorphPositions. !
Item was changed: ----- Method: SimpleHierarchicalListMorph>>update: (in category 'updating') ----- update: aSymbol aSymbol == getSelectionSelector ifTrue: [self updateSelection. ^self]. aSymbol == getListSelector ifTrue: [self list: self getList. ^self]. + aSymbol == autoExpandSelector + ifTrue: + [self updateAutoExpand. + ^self]. ((aSymbol isKindOf: Array) and: [aSymbol notEmpty and: [aSymbol first == #openPath]]) ifTrue: [^(scroller submorphs at: 1 ifAbsent: [^self]) openPath: aSymbol allButFirst]!
Item was added: + ----- Method: SimpleHierarchicalListMorph>>updateAutoExpand (in category 'updating') ----- + updateAutoExpand + + self autoExpand: (model perform: autoExpandSelector).!
squeak-dev@lists.squeakfoundation.org