'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:)
!

