'From Squeak5.1 of 23 August 2016 [latest update: #16548] on 26 April 2017 at 11:33:42 am'! SimpleHierarchicalListMorph subclass: #PluggableTreeMorph instanceVariableNames: 'rootWrappers selectedWrapper getRootsSelector getChildrenSelector hasChildrenSelector getLabelSelector getIconSelector getSelectedPathSelector setSelectedParentSelector getHelpSelector dropItemSelector wantsDropSelector dragItemSelector dragTypeSelector nodeClass lastKeystrokeTime lastKeystrokes dragStartedSelector doubleClickSelector' classVariableNames: 'FilterByLabelsOnly MaximumSearchDepth' poolDictionaries: '' category: 'ToolBuilder-Morphic'! PluggableWidgetSpec subclass: #PluggableTreeSpec instanceVariableNames: 'roots getSelectedPath setSelected getSelected setSelectedParent getChildren hasChildren label icon unusedVar menu keyPress doubleClick dropItem dropAccept autoDeselect dragItem nodeClass columns vScrollBarPolicy hScrollBarPolicy dragStarted' classVariableNames: '' poolDictionaries: '' category: 'ToolBuilder-Kernel'! !Object methodsFor: '*Morphic-Explorer' stamp: 'pre 4/26/2017 11:16'! explorerContents ^ (self class allInstVarNames asOrderedCollection withIndexCollect: [:each :index | ObjectExplorerWrapper with: (self instVarAt: index) name: each model: self]) , ((1 to: self basicSize) collect: [:index | ObjectExplorerWrapper with: (self basicAt: index) name: index printString model: self ])! ! !ObjectExplorer methodsFor: 'user interface' stamp: 'pre 4/26/2017 11:27'! getDragItem: binding ^ binding value! ! !ObjectExplorer methodsFor: 'toolbuilder' stamp: 'pre 4/26/2017 10:21'! buildWith: builder | windowSpec treeSpec textSpec buttonSpec buttonOffset tool | windowSpec := builder pluggableWindowSpec new. windowSpec model: self; children: OrderedCollection new; label: #label; extent: self initialExtent. treeSpec := builder pluggableTreeSpec new. treeSpec model: self; nodeClass: self class nodeClass; roots: #getList; keyPress: #explorerKey:from:event:; getSelected: #currentSelection; setSelected: #currentSelection:; setSelectedParent: #currentParent:; menu: #genericMenu:; dragItem: #getDragItem:; autoDeselect: false; columns: (ObjectExplorerWrapper showContentsInColumns ifTrue: [{ [:listMorph | (listMorph filteredItems collect: [:item | item preferredWidthOfColumn: 1]) max]. nil "take all the space"}]); frame: (0@0 corner: 1@0.71). windowSpec children add: treeSpec. buttonOffset := (Preferences standardButtonFont widthOfString: 'inspect') * 3/2. textSpec := builder pluggableCodePaneSpec new. textSpec model: self; getText: #expression; editText: #expression:; menu: #codePaneMenu:shifted:; help: 'Evaluate expressions for the current tree selection...' translated; frame: (LayoutFrame fractions: (0@0.71 corner: 1@1) offsets: (0@0 corner: buttonOffset negated@0)). windowSpec children add: textSpec. buttonSpec := builder pluggableButtonSpec new model: self; label: 'inspect'; action: #inspectObject; help: 'Switch to an inspector tool'; frame: (LayoutFrame fractions: (1@0.71 corner: 1@1) offsets: (buttonOffset negated@0 corner: 0 @ 0)). windowSpec children add: buttonSpec. tool := builder build: windowSpec. self changed: #expandRootsRequested. ^ tool! ! !ObjectExplorerWrapper methodsFor: 'monitoring' stamp: 'pre 4/26/2017 11:31'! refresh self parent ifNil: [^ self]. [model explorerContents detect: [:wrapper | wrapper itemName = self itemName] ifFound: [:wrapper | ^ self object: wrapper object ] ifNone: [^ self object: nil]] on: Error do: [ :ex | self object: nil ]! ! !ObjectExplorerWrapper methodsFor: 'accessing' stamp: 'pre 4/26/2017 11:17'! contents ^ self object explorerContents do: [:wrapper | wrapper parent: self]; yourself! ! !PluggableTreeMorph methodsFor: 'accessing' stamp: 'pre 4/26/2017 10:22'! doubleClickEnabled ^ self doubleClickSelector notNil! ! !PluggableTreeMorph methodsFor: 'accessing' stamp: 'pre 4/25/2017 11:59'! doubleClickSelector ^ doubleClickSelector! ! !PluggableTreeMorph methodsFor: 'accessing' stamp: 'pre 4/25/2017 11:59'! doubleClickSelector: anObject doubleClickSelector := anObject! ! !PluggableTreeMorph methodsFor: 'updating' stamp: 'mt 3/7/2015 11:29'! update: what with: anObject super update: what with: anObject. what == #objectChanged ifTrue: [ self updateFromChangedObject: anObject].! ! !PluggableTreeMorph methodsFor: 'event handling' stamp: 'pre 4/26/2017 11:25'! doubleClick: evt | aMorph | aMorph := self itemFromPoint: evt position. self model perform: self doubleClickSelector with: aMorph withoutListWrapper ! ! !PluggableTreeMorph methodsFor: 'event handling' stamp: 'pre 4/26/2017 10:42'! 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 notNil and:[aMorph inToggleArea: (aMorph point: evt position from: self)]) ifTrue:[^self toggleExpandedState: aMorph event: evt]. aMorph ifNil:[^super mouseDown: evt]. aMorph highlightForMouseDown. self setProperty: #highlightedMorph toValue: aMorph. 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".! ! !PluggableTreeSpec methodsFor: 'accessing' stamp: 'pre 4/25/2017 12:05'! doubleClick "Answer the selector for reacting to a double click" ^ doubleClick! ! !PluggableTreeSpec methodsFor: 'accessing' stamp: 'pre 4/25/2017 12:05'! doubleClick: selector "Set the selector for reacting to a double click" doubleClick := selector! ! !PluggableTreeSpec reorganize! ('accessing' columns columns: doubleClick doubleClick: hScrollBarPolicy hScrollBarPolicy: icon icon: keyPress keyPress: label label: menu menu: nodeClass nodeClass: vScrollBarPolicy vScrollBarPolicy:) ('building' buildWith:) ('accessing - selection' autoDeselect autoDeselect: getSelected getSelected: getSelectedPath getSelectedPath: setSelected setSelected: setSelectedParent setSelectedParent:) ('accessing - drag and drop' dragItem dragItem: dragStarted dragStarted: dropAccept dropAccept: dropItem dropItem:) ('accessing - hierarchy' getChildren getChildren: hasChildren hasChildren: roots roots:) ! !PluggableTreeMorph reorganize! ('accessing' doubleClickEnabled doubleClickSelector doubleClickSelector: dragItemSelector dragItemSelector: dragStartedSelector dragStartedSelector: dragTypeSelector dragTypeSelector: dropItemSelector dropItemSelector: getChildrenSelector getChildrenSelector: getHelpSelector getHelpSelector: getIconSelector getIconSelector: getLabelSelector getLabelSelector: getMenuSelector getMenuSelector: getRootsSelector getRootsSelector: getSelectedPathSelector getSelectedPathSelector: getSelectedSelector getSelectedSelector: hasChildrenSelector hasChildrenSelector: items keystrokeActionSelector keystrokeActionSelector: lastKeystrokeTime lastKeystrokeTime: lastKeystrokes lastKeystrokes: nodeClass nodeClass: rootWrappers rootWrappers: selectedWrapper selectedWrapper: setSelectedParentSelector setSelectedParentSelector: setSelectedSelector setSelectedSelector: wantsDropSelector wantsDropSelector:) ('node access' balloonTextForNode: contentsOfNode: dropNode:on: hasNodeContents: iconOfNode: isDraggableNode: printNode: updateNode: wantsDroppedNode:on:) ('selection' getCurrentSelectionItem selectPath:in: selectedMorph: setSelectedMorph: setSelectedParentMorph:) ('updating' update: update:with: updateFromChangedObject: updateMorph: wrapRoots:) ('event handling' basicKeyPressed: doubleClick: keyStroke: keyboardFocusChange: mouseDown: specialKeyPressed: updateLastKeystrokes:) ('filtering' filterTree filteredItems hasFilter indicateFiltered indicateUnfiltered removeFilter selectNextMorphByFilter triggerFilterTree) ('initialization' initialize) ('scrolling' vUnadjustedScrollRange) ('geometry' bottomVisibleRowIndex charactersOccluded topVisibleRowIndex visibleItems) ('drag and drop' acceptDroppingMorph:event: startDrag: wantsDroppedMorph:event:) !