Marcel Taeumel uploaded a new version of Morphic to project The Trunk: http://source.squeak.org/trunk/Morphic-mt.2103.mcz
==================== Summary ====================
Name: Morphic-mt.2103 Author: mt Time: 6 April 2023, 11:21:51.373919 am UUID: d789fd49-b326-7044-97a8-fca46271212c Ancestors: Morphic-mt.2102
In tree widgets, add way to "expand all" via keyboard (SHIFT+RIGHT) or mouse (SHIFT+CLICK) navigation.
=============== Diff against Morphic-mt.2102 ===============
Item was changed: ScrollPane subclass: #SimpleHierarchicalListMorph instanceVariableNames: 'selectedMorph hoveredMorph getListSelector keystrokeActionSelector autoDeselect columns columnsCache sortingSelector getSelectionSelector setSelectionSelector potentialDropMorph lineColor font textColor' + classVariableNames: 'ExpandAllLimit ExpandedForm NotExpandedForm WrappedNavigation' - classVariableNames: '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 added: + ----- Method: SimpleHierarchicalListMorph class>>expandAllLimit (in category 'preferences') ----- + expandAllLimit + <preference: 'Maximum number of items for expand-all in trees' + category: 'Morphic' + description: 'When the number of items in a tree exceeds this limit, stop the expand-all operation, which is usually invoked via SHIFT+RIGHT.' + type: #Number> + ^ ExpandAllLimit ifNil: [ 5000 "Allow for expanding a full class tree from ProtoObject" ]!
Item was added: + ----- Method: SimpleHierarchicalListMorph class>>expandAllLimit: (in category 'preferences') ----- + expandAllLimit: booleanOrNil + + ExpandAllLimit := booleanOrNil.!
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" selectedMorph ifNotNil:[ (selectedMorph canExpand and:[selectedMorph isExpanded not]) + ifTrue:[self currentEvent shiftPressed + ifTrue: [self expandAllSafely: selectedMorph] + ifFalse: [self toggleExpandedState: selectedMorph]] - ifTrue:[self toggleExpandedState: selectedMorph] ifFalse:[self setSelectionIndex: self getSelectionIndex+1]. ]. ^true]. keyEvent = 28 ifTrue:["left" 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>>expandAllSafely (in category 'events') ----- + expandAllSafely + + self expandAllSafely: selectedMorph.!
Item was added: + ----- Method: SimpleHierarchicalListMorph>>expandAllSafely: (in category 'events') ----- + expandAllSafely: aMorph + + aMorph ifNil: [^ self]. + Cursor wait showWhile: [ + [self expandAllSafely: aMorph seen: IdentitySet new. self adjustSubmorphPositions] + on: TooManyItemsInTree do: [:ex | "Stop operation." + self adjustSubmorphPositions. + self inform: 'Too many children in sub-tree. Raise #expandAllLimit preference if needed.' translated. + self flag: #todo. "mt: Let the user choose to continue the operation for another n items..."]].!
Item was added: + ----- Method: SimpleHierarchicalListMorph>>expandAllSafely:seen: (in category 'events') ----- + expandAllSafely: aMorph seen: seenObjects + "Keep track of seen objects to handle endless recursion." + + (seenObjects ifAbsentAdd: aMorph withoutListWrapper value) ifFalse: [^ self]. + seenObjects size > self class expandAllLimit ifTrue: [^ TooManyItemsInTree signal]. + aMorph canExpand ifFalse: [^ self]. + aMorph isExpanded ifFalse: [aMorph toggleExpandedState]. + aMorph childrenDo: [:child | self expandAllSafely: child seen: seenObjects].!
Item was changed: ----- Method: SimpleHierarchicalListMorph>>mouseDown: (in category 'event handling') ----- mouseDown: evt
| aMorph selectors | aMorph := self itemFromPoint: evt position. evt yellowButtonPressed "First check for option (menu) click" ifTrue: [ (PluggableListMorph menuRequestUpdatesSelection and: [model okToChange]) ifTrue: [ aMorph == selectedMorph ifFalse: [self setSelectedMorph: aMorph]]. ^ self yellowButtonActivity: evt shiftPressed].
aMorph ifNil: [^ super mouseDown: evt].
(aMorph notNil and:[aMorph inToggleArea: (aMorph point: evt position from: self)]) ifTrue: [ | priorSelection | priorSelection := self selectedMorph. + (evt shiftPressed and: [aMorph canExpand and: [aMorph isExpanded not]]) + ifTrue: [self expandAllSafely: aMorph] + ifFalse: [self toggleExpandedState: aMorph event: evt]. - self toggleExpandedState: aMorph event: evt. (priorSelection notNil and: [self selectedMorph isNil]) ifTrue: [ self setProperty: #changeSelectionOnMouseUp toValue: true. self setProperty: #selectedMorph toValue: aMorph]. ^ self]. PluggableListMorph highlightPreSelection ifTrue: [ aMorph highlightedForMouseDown: true. self setProperty: #highlightedMorph toValue: aMorph]. self setProperty: #changeSelectionOnMouseUp toValue: true. selectors := Array with: #click: with: (self doubleClickEnabled ifTrue: [#doubleClick:] ifFalse: [nil]) with: nil with: (self dragEnabled ifTrue:[#startDrag:] ifFalse:[nil]). evt hand waitForClicksOrDrag: self event: evt selectors: selectors threshold: HandMorph dragThreshold "pixels".!
Item was added: + Notification subclass: #TooManyItemsInTree + instanceVariableNames: '' + classVariableNames: '' + poolDictionaries: '' + category: 'Morphic-Explorer'!
squeak-dev@lists.squeakfoundation.org