'From Cuis 5.0 [latest update: #4494] on 31 December 2020 at 1:31:57 pm'!
!classDefinition: #PluggableMasterListMorph category: 'Morphic-Widgets'!
PluggableListMorph subclass: #PluggableMasterListMorph
	instanceVariableNames: ''
	classVariableNames: ''
	poolDictionaries: ''
	category: 'Morphic-Widgets'!

!PluggableMasterListMorph commentStamp: '<historical>' prior: 0!
I am like my parent, but I vertical scroll my left and right siblings in synch with myself.!


!PluggableScrollPane methodsFor: 'access options' stamp: 'KenD 12/31/2020 13:05:54'!
alwaysHideVerticalScrollbar

	hideScrollBars _ #alwaysHideVertical.
	self vHideScrollBar.! !


!PluggableListMorph methodsFor: 'scrolling' stamp: 'KenD 12/31/2020 12:47:09'!
scrollSelectionIntoView
	"make sure that the current selection is visible"
	| row r |
	row _ self getCurrentSelectionIndex.
	row = 0 
		ifTrue: [
			"Value is 0, but we need to propagate it to model"
			scrollBar internalScrollValue: scrollBar scrollValue ]
		ifFalse: [
			self flag: #jmvVer2.
			r _ self listMorph drawBoundsForRow: row.
			r _ ((self listMorph externalize: r origin) extent: r extent).
			self scrollToShow: r ].
! !


!PluggableMasterListMorph methodsFor: 'scrolling' stamp: 'KenD 12/31/2020 12:49:53'!
scrollBy: delta
	"Scroll self and any siblings"
	super scrollBy: delta.
	self scrollSiblings! !

!PluggableMasterListMorph methodsFor: 'scrolling' stamp: 'KenD 12/31/2020 12:49:32'!
scrollSelectionIntoView
	"Vertical scroll siblings in synch with self"
	super scrollSelectionIntoView.
	self scrollSiblings! !

!PluggableMasterListMorph methodsFor: 'scrolling' stamp: 'KenD 12/31/2020 12:55:46'!
scrollSiblings
	"vertical scroll my siblings w self"
	leftSibling  ifNotNil: [ :left    |  left  scrollerOffset: ((left   scrollerOffset x) @ (self scrollerOffset y)) ].
	rightSibling ifNotNil: [ :right | right scrollerOffset: ((right scrollerOffset x) @ (self scrollerOffset y)) ].! !

!PluggableMasterListMorph methodsFor: 'scrolling' stamp: 'KenD 12/31/2020 12:54:27'!
scrollToShow: aRectangle

	super scrollToShow: aRectangle.
	self scrollSiblings ! !

!PluggableMasterListMorph methodsFor: 'scrolling' stamp: 'KenD 12/31/2020 13:27:33'!
vScrollBarValue: scrollValue

	super vScrollBarValue: scrollValue.
	self scrollSiblings ! !


!PluggableScrollPane methodsFor: 'geometry' stamp: 'KenD 12/31/2020 13:09:16'!
updateScrollBarsBounds
	
	| t |
	hideScrollBars = #hide ifTrue: [^self].
	t _ self scrollBarClass scrollbarThickness.
	(hideScrollBars = #hideVertical)
	ifFalse: [
		scrollBar
			morphPosition: extent x - t - borderWidth @ borderWidth
			extent: t @ self vScrollBarHeight.
	].
	hScrollBar
		morphPosition: borderWidth @ (extent y - t - borderWidth)
		extent: self hScrollBarWidth@t! !

!PluggableScrollPane methodsFor: 'scrolling' stamp: 'KenD 12/31/2020 13:18:18'!
vIsScrollbarNeeded
	"Return whether the vertical scrollbar is needed"
	
	"Don't show it if we were told not to."
	hideScrollBars = #hide ifTrue: [ ^false ].
	
	hideScrollBars = #alwaysHideVertical  ifTrue: [ ^false ].

	hideScrollBars = #alwaysShowVertical ifTrue: [ ^true ].

	^self vLeftoverScrollRange > 0! !


!CodePackageListWindow methodsFor: 'GUI building' stamp: 'KenD 12/31/2020 13:06:12'!
buildMorphicWindow
	" 
	CodePackageListWindow open: CodePackageList new
	"
	| dirtyFlags names fileNames dirtyFlagsPane namesPane fileNamesPane 
	upperRow  description summary backColor labelBackground |
	backColor := self textBackgroundColor.	
	labelBackground := Theme current background.
	
	dirtyFlags := PluggableListMorph
		model: model 
		listGetter: #packageDirtyFlags
		indexGetter: #selectionIndex
		indexSetter: #selectionIndex:.
	dirtyFlags color: backColor;
			   hideScrollBarsIndefinitely.
	dirtyFlagsPane := LayoutMorph newColumn
		color: labelBackground;
		addMorph: (WidgetMorph new noBorder color: `Color transparent`) fixedHeight: 4;
		addMorphKeepMorphHeight: (LabelMorph new contents: ' Unsaved?');
		addMorphUseAll: dirtyFlags.

	names := PluggableMasterListMorph
		model: model 
		listGetter: #packageNames
		indexGetter: #selectionIndex
		indexSetter: #selectionIndex:.
	names color: backColor.
	namesPane := LayoutMorph newColumn
		color: labelBackground;
		addMorph: (WidgetMorph new noBorder color: `Color transparent`) fixedHeight: 4;
		addMorphKeepMorphHeight: (LabelMorph new contents: ' Package Name');
		addMorphUseAll: names.

	fileNames := PluggableListMorph
		model: model 
		listGetter: #packageFullNames
		indexGetter: #selectionIndex
		indexSetter: #selectionIndex:.
	fileNames color: backColor;
			   alwaysHideVerticalScrollbar.
	fileNamesPane := LayoutMorph newColumn
		color: labelBackground;
		addMorph: (WidgetMorph new noBorder color: `Color transparent`) fixedHeight: 4;
		addMorphKeepMorphHeight: (LabelMorph new contents: ' File Name');
		addMorphUseAll: fileNames.

	upperRow := LayoutMorph newRow.
	upperRow
		addMorph: dirtyFlagsPane proportionalWidth: 0.13;
		addAdjusterAndMorph: namesPane proportionalWidth: 0.27;
		addAdjusterAndMorph: fileNamesPane proportionalWidth: 0.6.
		
	description := (TextModelMorph
		textProvider: model
		textGetter: #description 
		textSetter: #description:) emptyTextDisplayMessage: 'Please enter a description for this package'.

	summary := (TextModelMorph
		textProvider: model
		textGetter: #summary) emptyTextDisplayMessage: 'Package summary (No package selected?)'.
		
	names leftSibling: dirtyFlags rightSibling: fileNames.

	self layoutMorph
		addMorph: upperRow proportionalHeight: 0.6;
		addAdjusterAndMorph: self buildButtonPane fixedHeight: Theme current buttonPaneHeight;
		addAdjusterAndMorph: summary fixedHeight: 60;
		addAdjusterAndMorph: description proportionalHeight: 0.25;
		addAdjusterAndMorph: self buildRequirementsPane proportionalHeight: 0.15.
	self setLabel: 'Installed Packages'! !

!CodePackageListWindow methodsFor: 'GUI building' stamp: 'KenD 12/31/2020 11:40:22'!
buildRequirementsPane

	| requirements deleteReqButton "editReqButton" reqLayout buttonLayout updateReqButton |
	requirements := PluggableListMorph
		model: (PackageRequirementsList fromCodePackageList: model)
		listGetter: #requirementsStrings
		indexGetter: #selectionIndex
		indexSetter: #selectionIndex:.
	requirements color: Theme current textPane.
		
	deleteReqButton := PluggableButtonMorph 
							model: requirements model
							action: #deleteSelectedRequirement 
							label: 'delete'::
							setBalloonText: 'Remove selected Feature requirement'.
	deleteReqButton color: self widgetsColor.
	updateReqButton _ PluggableButtonMorph 
							model: requirements model
							action: #updateSelectedRequirement 
							label: 'update'::
							setBalloonText: 'Update requirement to current Feature revision'.
	updateReqButton color: self widgetsColor.
							
	buttonLayout := LayoutMorph newRow.
	buttonLayout 
		addMorph: deleteReqButton 
		layoutSpec: (LayoutSpec 
						proportionalWidth: 1.0 
						proportionalHeight: 1.0
						offAxisEdgeWeight: #leftOrTop);
		color: self widgetsColor quiteWhiter;
		addMorph: updateReqButton 
		layoutSpec: (LayoutSpec 
						proportionalWidth: 1.0 
						proportionalHeight: 1.0
						offAxisEdgeWeight: #leftOrTop);
		color: self widgetsColor quiteWhiter.
		
	model when: #changed: send: #updateRequirementsFromPackageList to: requirements model.
	self when: #changed: send: #updateRequirementsFromPackageList to: requirements model.
	requirements model when: #changed: send: #verifyContents to: requirements.
	self when: #changed: send: #verifyContents to: requirements.
	
	reqLayout := LayoutMorph newRow.
	^ reqLayout 
		doAdoptWidgetsColor;
		addMorph: requirements 
			layoutSpec: (LayoutSpec 
							proportionalWidth: 0.8
							proportionalHeight: 1.0 
							offAxisEdgeWeight: #leftOrTop);
		addMorph: buttonLayout 
			layoutSpec: (LayoutSpec 
							proportionalWidth: 0.2 
							proportionalHeight: 1.0 
							offAxisEdgeWeight: #rightOrBottom);
		color: `Color transparent`;
		yourself
		! !

!methodRemoval: PluggableListMorph #scrollBy: stamp: 'KenD 12/31/2020 12:46:07'!
PluggableListMorph removeSelector: #scrollBy:!

!PluggableListMorph reorganize!
('accessing' rowAtLocation: rowAtLocation:ifNone:)
('accessing - properties' acceptDropsFrom:performing:whenOutsideList: makeItemsDraggable makeItemsUndraggable rejectDrops)
('drawing' drawOn: flashRow:)
('dropping/grabbing' acceptDroppingMorph:atRow:withEvent: acceptDroppingMorph:event: acceptDroppingMorph:outsideListWithEvent: wantsDroppedMorph:event:)
('event handling' keyboardFocusChange: mouseButton2Activity)
('event handling testing' allowsMorphDrop handlesKeyboard)
('events' doubleClick:localPosition: dragEvent:localPosition: gainFocusFrom: keyStroke: mouseButton1Down:localPosition: mouseButton1Up:localPosition: mouseEnter: mouseLeave:)
('events-processing' processMouseMove:localPosition:)
('geometry' fontPreferenceChanged scrollDeltaHeight scrollDeltaWidth)
('initialization' autoDeselect: doubleClickSelector: font font: initForKeystrokes initialize innerMorphClass listItemHeight model:listGetter:indexGetter:indexSetter:mainView:menuGetter:keystrokeAction:)
('keyboard navigation' arrowKey: deleteAction navigateDown navigateLeft navigateOnePageDown navigateOnePageUp navigateRight navigateToBottom navigateToTop navigateUp)
('menu' getMenu)
('menus' addCustomMenuItems:hand: copyListToClipboard copySelectionToClipboard)
('model access' getCurrentSelectionIndex getList getListItem: getListSize itemSelectedAmongMultiple: keyboardSearch: keystrokeAction: setSelectionIndex:)
('selection' maximumSelection minimumSelection numSelectionsInView privateVisualSelection: privateVisualSelectionIndex: selection: selectionIndex: visualSelection visualSelectionIndex)
('testing' is:)
('updating' update: updateList verifyContents)
('private' changeSelectionTo: itemsAreDraggable listMorph)
('siblings' leftSibling: leftSibling:rightSibling: rightSibling:)
('scrolling' scrollSelectionIntoView)
!


!PluggableMasterListMorph reorganize!
('scrolling' scrollBy: scrollSelectionIntoView scrollSiblings scrollToShow: vScrollBarValue:)
!

