'From Squeak5.3alpha of 19 August 2019 [latest update: #18804] on 21 August 2019 at 3:31:32 pm'!
LayoutProperties subclass: #TableLayoutProperties
	instanceVariableNames: 'cellInset cellPositioning cellSpacing layoutInset listCentering listDirection listSpacing reverseTableCells rubberBandCells wrapCentering wrapDirection minCellSize maxCellSize cellGap '
	classVariableNames: ''
	poolDictionaries: ''
	category: 'Morphic-Layouts'!

!FileList2 methodsFor: 'initialization' stamp: 'mt 8/21/2019 13:43'!
optionalButtonRow
	"Answer the button row associated with a file list"

	| aRow |
	aRow := AlignmentMorph newRow beSticky.
	aRow color: Color transparent.
	aRow clipSubmorphs: true.
	aRow layoutInset: 5@1; cellGap: 6.
	self universalButtonServices do:  "just the three sort-by items"
			[:service |
				aRow addMorphBack: (service buttonToTriggerIn: self).
				(service selector  == #sortBySize)
					ifTrue:
						[aRow addTransparentSpacerOfSize: (4@0)]].
	aRow setNameTo: 'buttons'.
	aRow setProperty: #buttonRow toValue: true.  "Used for dynamic retrieval later on"
	^ aRow!
]style[(17 2 51 3 1 1 4 1 1 2 4 1 2 16 6 1 8 3 4 1 6 7 11 3 4 1 14 1 4 3 4 1 12 1 1 1 1 2 8 1 1 3 4 1 23 1 3 2 30 6 7 1 1 5 4 1 13 1 1 7 1 18 1 4 1 6 1 7 1 8 2 2 1 11 1 6 7 7 1 4 1 27 1 1 1 1 1 1 1 4 4 1 10 1 9 3 4 1 12 1 10 1 8 1 4 3 37 2 1 1 4)b,cblack;,c000126126,cblack;,cgray;,cblack;,c106106106,cblack;,cgray;,cblack;,c106106106,cblack;,b,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c126000000,cblack;,c106106106,cblack;,c000000126,cblack;,c126000000,c000000126,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000126126,cblack;,c000000126,cblack;,cgray;,cblack;,c106106106,cblack;,c000000126,cblack;,c000126000,c000000126,cblack;,c000000126,cblack;,c126000000,c000126000,cblack;,c000126000,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,c000126000,cblack;,c000000126,cblack;,c000126000,c106106106,cblack;,c000000126,cblack;,c126000126,c126000000,c000000126,c126000000,c126000126,c000126000,cblack;,c106106106,cblack;,c000000126,cblack;,c126000126n,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000126126,cblack;,c126000000,cblack;,c106106106! !


!LayoutProperties methodsFor: 'accessing' stamp: 'mt 8/12/2019 15:30'!
disableLayout
	^disableLayout!
]style[(13 2 1 13)b,cblack;,c126000000,cblack;! !

!LayoutProperties methodsFor: 'accessing' stamp: 'mt 8/12/2019 15:30'!
disableLayout: aBool
	disableLayout := aBool!
]style[(14 1 5 16 2 1 5)b,cblack;,c000000126,cblack;,b,cblack;,c000000126! !

!LayoutProperties methodsFor: 'table defaults' stamp: 'mt 8/21/2019 09:06'!
cellGap
	"Default"
	^0!
]style[(7 2 9 2 2)b,cblack;,c000126126,cblack;,c126000000! !


!Morph methodsFor: 'change reporting' stamp: 'mt 8/9/2019 16:23'!
invalidRect: aRectangle from: aMorph
	| damageRect |
	self visible ifFalse: [ ^self ].
	aRectangle hasPositiveExtent ifFalse: [ ^self ].
	damageRect := aRectangle.
	aMorph == self ifFalse:[
		"Clip to receiver's clipping bounds if the damage came from a child"
		self clipSubmorphs 
			ifTrue:[damageRect := aRectangle intersect: self clippingBounds]].
	owner ifNotNil: [owner invalidRect: damageRect from: self].! !

!Morph methodsFor: 'change reporting' stamp: 'mt 8/8/2019 09:39'!
ownerChanged
	"This morph's owner has changed its geometry and is about to update its layout. This is a simple layout hook to update this morph's geometry according to its owner.
	
	For more advanced strategies, use a LayoutPolicy with some LayoutProperties. See #layoutPolicy: and maybe also #doLayoutIn:."

	self snapToEdgeIfAppropriate.!
]style[(12 2 293 3 4 1 23 1)b,cblack;,c000126126,cblack;,c126000000,cblack;,c000000126,cblack;! !

!Morph methodsFor: 'drawing' stamp: 'mt 8/12/2019 11:22'!
clipSubmorphs: aBool
	"Drawing specific. If this property is set, clip the receiver's submorphs to the receiver's clipping bounds."

	self fullBounds; changed.
	
	aBool == false
		ifTrue:[self removeProperty: #clipSubmorphs]
		ifFalse:[self setProperty: #clipSubmorphs toValue: aBool].
	
	self
		layoutChanged;
		fullBounds; changed.!
]style[(14 1 5 2 109 3 4 1 10 2 7 5 5 1 2 1 5 3 7 1 4 1 15 1 14 4 8 1 4 1 12 1 14 1 8 1 5 6 4 3 13 4 10 2 7 1)b,cblack;,c000000126,cblack;,c000126126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;! !

!Morph methodsFor: 'drawing' stamp: 'mt 8/15/2019 16:06'!
hide

	self visible ifTrue: [self visible: false].!
]style[(4 3 4 1 7 1 7 2 4 1 8 1 5 2)b,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;! !

!Morph methodsFor: 'drawing' stamp: 'mt 8/15/2019 16:06'!
show

	self visible ifFalse: [self visible: true].! !

!Morph methodsFor: 'drawing' stamp: 'mt 8/12/2019 15:12'!
visible: aBoolean 
	"set the 'visible' attribute of the receiver to aBoolean"
	(extension isNil and:[aBoolean]) ifTrue: [^ self].
	self visible == aBoolean ifTrue: [^ self].
	
	self changed.
	self assureExtension visible: aBoolean.
	self changed! !

!Morph methodsFor: 'geometry' stamp: 'mt 8/8/2019 09:00'!
position: aPoint 
	"Change the position of this morph, which is the top left corner of its bounds."
	
	| delta box |
	delta := (aPoint - self bounds topLeft) rounded.
	
	"Skip drawing and layout updates for null changes."
	(delta x = 0 and: [delta y = 0])
		ifTrue: [^ self].

	"Optimize drawing. Record one damage rectangle for short distance and two damage rectangles for large distances."
	box := self fullBounds.	
	(delta dotProduct: delta) > 100 "More than 10 pixels?"
		ifTrue: [self
					invalidRect: box;
					invalidRect: (box translateBy: delta)]
		ifFalse: [self
					invalidRect: (box merge: (box translateBy: delta))].
	
	"Move this morph and *all* of its submorphs."
	self privateFullMoveBy: delta.
	
	"For all known layout policies, my layout and the layout of my children is fine. Only the layout of my owner might be affected. So, tell about it."
	self owner ifNotNil: [:o | o layoutChanged].!
]style[(9 1 6 3 80 4 1 1 5 1 3 1 1 2 5 1 2 2 6 1 1 1 4 1 6 1 7 2 7 5 51 3 5 1 1 1 1 1 1 1 4 1 1 5 1 1 1 1 1 1 1 4 7 2 1 1 4 5 113 2 3 1 2 1 4 1 10 5 5 1 11 1 5 2 1 1 3 1 22 3 7 2 4 6 12 1 3 7 12 1 1 3 1 12 1 5 1 4 8 2 4 6 12 1 1 3 1 6 1 1 3 1 12 1 5 1 1 6 45 2 4 1 18 1 5 5 147 2 4 1 5 1 9 3 1 1 1 1 1 1 13 2)b,cblack;,c000000126,cblack;,c000126126,cblack;,cgray;,cblack;,c106106106,cblack;,c106106106,cblack;,cgray;,cblack;,c106106106,cblack;,b,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000126000,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,c000126000,cblack;,c000000126,cblack;,c126000000,cblack;,c126000000,cblack;,c000126126,cblack;,c106106106,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c126000000,cblack;,c000126126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000126000,c106106106,cblack;,c000000126,cblack;,c106106106,c000126000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000126000,c106106106,cblack;,c000000126,cblack;,c126000126,c106106106,cblack;,c000000126,cblack;,c106106106,c126000126,c000126000,cblack;,c000126126,cblack;,c126000000,cblack;,c000000126,cblack;,c106106106,cblack;,c000126126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,cgray;,cblack;,c000000126,cblack;,c000000126,cblack;! !

!Morph methodsFor: 'layout' stamp: 'mt 8/21/2019 09:50'!
adjustLayoutBounds
	"Adjust the receivers bounds depending on the resizing strategy imposed"
	
	| hFit vFit box sbox myExtent myOrigin myBox |
	hFit := self hResizing.
	vFit := self vResizing.
	(hFit == #shrinkWrap or:[vFit == #shrinkWrap]) ifFalse:[^self]. "not needed"
	
	box := self layoutBounds.
	sbox := self submorphBoundsForShrinkWrap outsetBy: self cellInset.
	
	myExtent := box extent.
	myOrigin := box origin.
	hFit == #shrinkWrap ifTrue:[
		myExtent := sbox extent x @ myExtent y.
		myOrigin := sbox origin x @ myOrigin y].
	vFit == #shrinkWrap ifTrue:[
		myExtent := myExtent x @ sbox extent y.
		myOrigin := myOrigin x @ sbox origin y].
	"Make sure we don't get smaller than minWidth/minHeight"
	myExtent x < self minWidth ifTrue:[
		myExtent := (myExtent x max: 
			(self minWidth - self bounds width + self layoutBounds width)) @ myExtent y].
	myExtent y < self minHeight ifTrue:[
		myExtent := myExtent x @ (myExtent y max:
			(self minHeight - self bounds height + self layoutBounds height))].
		
	myBox := myOrigin extent: myExtent.
	self layoutBounds: myBox.!
]style[(18 2 72 4 1 1 4 1 4 1 3 1 4 1 8 1 8 1 5 1 1 2 4 1 2 1 4 1 9 3 4 1 2 1 4 1 9 4 4 1 2 1 11 1 3 1 4 1 2 1 11 1 2 8 1 5 3 12 4 3 1 2 1 4 1 12 3 4 1 2 1 4 1 27 1 9 1 4 1 9 5 8 1 2 1 3 1 6 3 8 1 2 1 3 1 6 3 4 1 2 1 11 1 7 4 8 1 2 1 4 1 6 1 1 1 1 1 8 1 1 4 8 1 2 1 4 1 6 1 1 1 1 1 8 1 1 4 4 1 2 1 11 1 7 4 8 1 2 1 8 1 1 1 1 1 4 1 6 1 1 4 8 1 2 1 8 1 1 1 1 1 4 1 6 1 1 4 56 2 8 1 1 1 1 1 4 1 8 1 7 4 8 1 2 1 1 8 1 1 1 4 5 1 4 1 8 1 1 1 4 1 6 1 5 1 1 1 4 1 12 1 5 1 1 1 1 1 8 1 1 4 8 1 1 1 1 1 4 1 9 1 7 4 8 1 2 1 8 1 1 1 1 1 1 8 1 1 1 4 4 1 4 1 9 1 1 1 4 1 6 1 6 1 1 1 4 1 12 1 6 1 1 7 5 1 2 1 8 1 7 1 8 3 4 1 13 1 5 1)b,cblack;,c000126126,cblack;,cgray;,cblack;,c106106106,cblack;,c106106106,cblack;,c106106106,cblack;,c106106106,cblack;,c106106106,cblack;,c106106106,cblack;,c106106106,cblack;,cgray;,cblack;,c106106106,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c106106106,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,c000126000,c106106106,cblack;,c000000126,cblack;,c000000126,c000126000,cblack;,c000000126,cblack;,c126000000,cblack;,c000126126,cblack;,c106106106,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c106106106,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c106106106,cblack;,b,cblack;,c106106106,cblack;,c000000126,cblack;,c106106106,cblack;,b,cblack;,c106106106,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,b,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c106106106,cblack;,b,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,b,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,b,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000126126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,b,cblack;,c000126000,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,c126000126,c000126000,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,b,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,c126000126,c000126000,cblack;,c106106106,cblack;,b,cblack;,c106106106,cblack;,c000000126,cblack;,c106106106,cblack;,c126000000,cblack;,c000000126,cblack;,c106106106,cblack;! !

!Morph methodsFor: 'layout' stamp: 'mt 8/20/2019 11:29'!
doLayoutIn: layoutBounds 
	"Compute a new layout based on the given layout bounds."

	| box priorBounds |
	"0) Quick return. No children means no effect in layout policies. Use #minWidth and #minHeight to implement #shrinkWrap for morphs without submorphs."
	self hasSubmorphs ifFalse: [^ fullBounds := self outerBounds].
	
	"X.1) Prepare redraw. Testing for #bounds or #layoutBounds would be sufficient to figure out if we need an invalidation afterwards but #outerBounds is what we need for all leaf nodes so we use that"
	priorBounds := self outerBounds.

	"1) Compute the new layout. This goes down the entire morph hierarchy. See #layoutInBounds: and #minExtent, which are the usual layout-policy callbacks."
	self layoutPolicy ifNotNil: [:layout |
		
		"1.1) Compute the new layout."
		self removeProperty: #doLayoutAgain.		
		layout layout: self in: layoutBounds.
		
		"1.2) Do one additional run on the layout if requested in #layoutInBounds:."
		(self hasProperty: #doLayoutAgain) ifTrue: [
			self removeProperty: #doLayoutAgain.		
			layout flushLayoutCache.
			layout layout: self in: layoutBounds].
		self assert: (self hasProperty: #doLayoutAgain) not].
	
	"2) Give our children a chance to manually adjust after layout computation. This allows morphs to layout in their owner without having to use a layout policy."
	self submorphsDo: [:m | m ownerChanged].
	
	"3) Watch out for minimal extent and apply #shrinkWrap constraints."
	self adjustLayoutBounds.
	
	"4) Compute and set the new full bounds. IMPORTANT to finish layout computation."
	fullBounds := self privateFullBounds.
	
	"X.2) Redraw."
	box := self outerBounds.
	box = priorBounds ifFalse: [
		self invalidRect: (priorBounds quickMerge: box)].! !

!Morph methodsFor: 'layout' stamp: 'mt 8/12/2019 11:14'!
layoutBounds: aRectangle
	"Set the bounds for laying out children of the receiver. WE DO NOT MOVE CHILDREN HERE!!
	
	Note that this code is written so that #layoutBounds can be changed without touching this method. For example, the layout bounds are smaller or larger than the current bounds.
	
	WE MUST NOT TRIGGER #layoutChanged AGAIN!! See #doLayoutIn: and #adjustLayoutBounds."
	
	| priorBounds outer inner box |
	priorBounds := self outerBounds.
		
	outer := self bounds.
	inner := self layoutBounds.
	bounds := aRectangle origin + (outer origin - inner origin) corner:
				aRectangle corner + (outer corner - inner corner).
	
	bounds = outer ifFalse: [
		self removeProperty: #dropShadow.
		self invalidRect: (priorBounds quickMerge: self outerBounds)].!
]style[(13 1 10 2 353 4 1 1 11 1 5 1 5 1 3 1 1 2 11 1 2 1 4 1 11 6 5 1 2 1 4 1 6 3 5 1 2 1 4 1 12 10 2 1 10 1 6 1 1 2 5 1 6 1 1 1 5 1 6 2 7 5 10 1 6 1 1 2 5 1 6 1 1 1 5 1 6 13 1 1 5 1 8 5 4 1 15 1 11 4 4 1 12 1 1 11 1 11 1 4 1 11 1 2)b,cblack;,c000000126,cblack;,c000126126,cblack;,cgray;,cblack;,c106106106,cblack;,c106106106,cblack;,c106106106,cblack;,c106106106,cblack;,cgray;,cblack;,c106106106,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c106106106,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c106106106,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,b,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000126000,c106106106,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,c000126000,cblack;! !

!Morph methodsFor: 'layout' stamp: 'mt 8/12/2019 17:12'!
layoutChanged
	"Notify my dependents (such as owner and submorphs) about a possible layout change after, for example, a change in position or extent. As a result, the layout will be re-computed for this morph and all its submorphs on the next #fullBounds call."

	"0) Skip duplicate notifications. Only once after every successful layout computation."
	fullBounds ifNil: [^self].
	
	"1) Clear layout caches."
	fullBounds := nil.
	self layoutPolicy ifNotNil:[:layout | layout flushLayoutCache].
	
	"2) Notify all dependents. Note that we do not send #ownerChanged to our submorphs now because we have to ensure that each submorph gets notified *exactly once* right before layout computation. See #doLayoutIn:."
	self owner ifNotNil: [:o | self disableLayout ifFalse: [o layoutChanged]].!
]style[(13 2 246 3 87 13 6 2 5 6 25 13 2 1 3 3 4 1 12 1 9 2 6 1 1 1 6 1 16 6 212 2 4 1 5 1 9 3 1 1 1 1 4 1 13 1 8 1 1 1 1 13 1 2)b,cblack;,c000126126,cblack;,c000126126,cblack;,c000000126,cblack;,c126000000,cblack;,c000126126,cblack;,b,cblack;,c126000000,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,cgray;,cblack;,c000000126,cblack;,c000000126,cblack;,c000126126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,cgray;,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c000000126,cblack;,c000000126,c000126000,cblack;! !

!Morph methodsFor: 'layout' stamp: 'mt 8/11/2019 15:31'!
layoutComputed

	^ fullBounds notNil!
]style[(14 3 1 12 6)b,cblack;,c126000000,cblack;,c000000126! !

!Morph methodsFor: 'layout' stamp: 'mt 8/21/2019 11:43'!
layoutExtent: aPoint
	"Sets the extent for laying out children of the receiver. We avoid triggering #layoutChanged again. This implementation is based on #extent:."
	
	"self assert: self owner layoutComputed not."
	self extent: aPoint.
	
	"(self extent closeTo: aPoint) ifTrue: [^ self].

	self invalidRect: self outerBounds.
	bounds := bounds topLeft extent: aPoint.
	
	self removeProperty: #dropShadow.
	self invalidRect: self outerBounds."!
]style[(13 1 6 2 142 4 45 2 4 1 7 1 6 5 203)b,cblack;,c000000126,cblack;,c000126126,cblack;,c000126126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000126126! !

!Morph methodsFor: 'layout' stamp: 'mt 8/21/2019 10:29'!
layoutInBounds: cellBounds
	"Layout specific. Apply the given bounds to the receiver after being layed out in its owner."
	
	| box aSymbol |	
	"1) We are getting new bounds here but we haven't computed the receiver's layout yet."
	self layoutComputed ifFalse:[
		"Although the receiver has reported its #minExtent before the actual size it has may differ from what would be after the layout. Normally, this isn't a real problem, but if we have #shrinkWrap constraints (see #adjustLayoutBounds) then the receiver's bounds may be larger than the cellBounds. THAT is a problem because the centering may not work correctly if the receiver shrinks after the owner layout has been computed. To avoid this problem, we compute the receiver's layout now. Note that the layout computation is based on the new cell bounds rather than the receiver's current bounds."
		
		"1.1) Adjust the box for #rigid receiver. Both #spaceFill and #shrinkWrap can use the cellBounds for now, which is important for many space-fills in a row or column to have the same widths (or heights) such as all MenuMorphItems in our MenuMorph."
		box := cellBounds origin extent: 
			(self hResizing == #rigid ifTrue: [self bounds extent x] ifFalse: [cellBounds extent x]) @
			(self vResizing == #rigid ifTrue: [self bounds extent y] ifFalse: [cellBounds extent y]).
		
		"1.2) Move and resize the receiver to get started."
		self
			layoutPosition: box origin;
			layoutExtent: box extent.
		
		"1.3) Adjust to layout bounds and do the layout."
		box := box origin - (self bounds origin - self layoutBounds origin) corner:
					box corner - (self bounds corner - self layoutBounds corner).
		self doLayoutIn: box].
	
"	self assert: self layoutComputed.
	self assert: self owner layoutComputed not.
"
	"2) Are we done already?"
	cellBounds extent = self bounds extent
		"Nice fit. I usually am done here if #minExtent did already trigger layout update (via #fullBounds) while my owner's layout was calculating the cell sizes."
		ifTrue:[^ self layoutPosition: cellBounds origin].
		
	"3) We have the receiver's layout. Maybe we just computed it or we did not invalidate it in this run. The latter happens if our owner invalidates without telling us. The user dragging size grips in windows, for example. Now we have to consider #spaceFill constraints, which may trigger re-computation of the receiver's layout."
	box := self bounds.
	self hResizing == #spaceFill 
		ifTrue: [
			"Support dynamic width-for-height due to space-fill constraint -- another layout run needed?"
			(box width ~= cellBounds width and: [self vResizing == #shrinkWrap])
				ifTrue: [self owner ifNotNil: [:o | o setProperty: #doLayoutAgain toValue: true]].
			"Fill the cell."
			box := box origin extent: cellBounds width @ box height].
		
	self vResizing == #spaceFill
		ifTrue: [
			"Support dynamic height-for-width due to space-fill constraint -- another layout run needed?"
			(box height ~= cellBounds height and: [self hResizing == #shrinkWrap])
				ifTrue: [self owner ifNotNil: [:o | o setProperty: #doLayoutAgain toValue: true]].
			"Fill the cell."	
			box := box origin extent: box width @ cellBounds height].

	"4) We have the receiver's layout. Align in the cell according o the owners layout properties."
	self flag: #refactor. "mt: #layoutInBounds: should also provide cellPositioning, not only cellBounds. There should be no need to access the owner in this method."
	aSymbol := self owner ifNil: [#center] ifNotNil: [:o | o cellPositioning].
	box := box align: (box perform: aSymbol) with: (cellBounds perform: aSymbol).

"	self assert: self layoutComputed.
	self assert: self owner layoutComputed not.
"
	"5) Install the new bounds. This may invalidate my layout again, which is okay because my owner will ask about my fullBounds in #doLayoutIn: (and #privateFullBounds). My layout will be re-computed then."		
	self bounds: box.!
]style[(15 1 10 2 93 4 1 1 3 1 7 1 1 3 86 2 4 1 14 1 8 4 591 6 247 3 3 1 2 1 10 1 6 1 7 5 1 4 1 9 1 2 1 6 1 7 1 1 4 1 6 1 6 1 1 1 1 8 1 1 10 1 6 1 1 1 1 1 1 4 1 4 1 9 1 2 1 6 1 7 1 1 4 1 6 1 6 1 1 1 1 8 1 1 10 1 6 1 1 1 1 7 51 3 4 4 15 1 3 1 6 5 13 1 3 1 6 7 49 3 3 1 2 1 3 1 6 1 1 1 1 4 1 6 1 6 1 1 1 4 1 12 1 6 1 1 7 6 3 1 6 1 1 1 1 4 1 6 1 6 1 1 1 4 1 12 1 6 1 4 4 1 11 1 3 5 82 2 25 2 10 1 6 1 1 1 4 1 6 1 6 3 156 3 7 1 1 1 4 1 15 1 10 1 6 7 327 2 3 1 2 1 4 1 6 3 4 1 9 1 2 1 10 4 7 6 93 4 1 3 1 5 1 2 1 10 1 5 1 4 1 1 4 1 9 1 2 1 11 1 1 5 7 1 1 4 1 5 1 9 1 1 1 1 1 1 1 1 1 12 1 14 1 8 1 4 1 1 5 16 4 3 1 2 1 3 1 6 1 7 1 10 1 5 1 1 1 3 1 6 7 4 1 9 1 2 1 10 3 7 6 93 4 1 3 1 6 1 2 1 10 1 6 1 4 1 1 4 1 9 1 2 1 11 1 1 5 7 1 1 4 1 5 1 9 1 1 1 1 1 1 1 1 1 12 1 14 1 8 1 4 1 1 5 16 5 3 1 2 1 3 1 6 1 7 1 3 1 5 1 1 1 10 1 6 5 95 2 4 1 5 1 9 2 140 2 7 1 2 1 4 1 5 1 6 2 7 2 9 3 1 1 1 1 1 1 15 4 3 1 2 1 3 1 6 2 3 1 8 1 7 2 5 2 10 1 8 1 7 4 82 2 203 4 4 1 7 1 3 1)b,cblack;,c000000126,cblack;,c000126126,cblack;,cgray;,cblack;,c106106106,cblack;,c106106106,cblack;,cgray;,cblack;,c000126126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000126126,cblack;,c000126126,cblack;,c106106106,cblack;,b,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,c126000126,cblack;,c000000126,cblack;,c126000126,c000000126,cblack;,c000000126,cblack;,c000000126,c126000126,c000126000,cblack;,c000000126,cblack;,c000126000,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,c126000126,cblack;,c000000126,cblack;,c126000126,c000000126,cblack;,c000000126,cblack;,c000000126,c126000126,c000126000,cblack;,c000126126,cblack;,c126000000,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000126126,cblack;,c106106106,cblack;,b,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,c000126000,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,c000126000,cblack;,c126000000,cblack;,c000000126,cblack;,c106106106,cblack;,c000126126,cblack;,c000126126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000126126,cblack;,c000000126,cblack;,c126000000,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126126,cblack;,c106106106,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126126,cblack;,c000126000,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,c126000126,c000126000,cblack;,c000000126,cblack;,c000126000,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126,cblack;,c000000126,cblack;,cgray;,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,c126000126,c000126000,cblack;,c000126126,cblack;,c106106106,cblack;,b,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126126,cblack;,c000126000,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,c126000126,c000126000,cblack;,c000000126,cblack;,c000126000,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126,cblack;,c000000126,cblack;,cgray;,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,c126000126,c000126000,cblack;,c000126126,cblack;,c106106106,cblack;,b,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000126126,cblack;,c106106106,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,cgray;,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,b,cblack;,c106106106,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000126126,cblack;,c000126126,cblack;,c126000000,cblack;,c000000126,cblack;,c106106106,cblack;! !

!Morph methodsFor: 'layout' stamp: 'mt 8/12/2019 11:46'!
layoutPosition: aPoint
	"Sets the position for laying out children of the receiver. We have to move the children here. We avoid triggering #layoutChanged again. This implementation is based on #position:."
	
	| delta box |
	delta := (aPoint - self bounds topLeft) rounded.
	(delta x = 0 and: [delta y = 0]) ifTrue: [^ self].

	box := self privateFullBoundsForRedraw.
	self invalidRect: (box merge: (box translateBy: delta)).
	
	self privateFullMoveBy: delta.!
]style[(15 1 6 2 181 4 1 1 5 1 3 1 1 2 5 1 2 2 6 1 1 1 4 1 6 1 7 2 7 4 5 1 1 1 1 1 1 1 4 1 1 5 1 1 1 1 1 1 1 2 7 2 1 1 4 5 3 1 2 1 4 1 26 3 4 1 12 2 3 1 6 1 1 3 1 12 1 5 1 6 4 1 18 1 5 1)b,cblack;,c000000126,cblack;,c000126126,cblack;,cgray;,cblack;,c106106106,cblack;,c106106106,cblack;,cgray;,cblack;,c106106106,cblack;,b,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000126000,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,c000126000,cblack;,c000000126,cblack;,c126000000,cblack;,c126000000,cblack;,c106106106,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000126000,c106106106,cblack;,c000000126,cblack;,c106106106,c000126000,cblack;,c126000000,cblack;,c000000126,cblack;,c106106106,cblack;! !

!Morph methodsFor: 'layout' stamp: 'mt 8/20/2019 11:23'!
minExtent
	"Layout specific. Return the minimum size the receiver can be represented in.
	Implementation note: When this message is sent from an owner trying to lay out its children it will traverse down the morph tree and recompute the minimal arrangement of the morphs based on which the minimal extent is returned. When a morph with some layout strategy is encountered, the morph will ask its strategy to compute the new arrangement. However, since the final size given to the receiver is unknown at the point of the query, the assumption is made that the current bounds of the receiver are the base on which the layout should be computed. This scheme prevents strange layout changes when for instance, a table is contained in another table. Unless the inner table has been resized manually (which means its bounds are already enlarged) the arrangement of the inner table will not change here. Thus the entire layout computation is basically an iterative process which may have different results depending on the incremental changes applied."

	| layout minExtent extra hFit vFit |
	hFit := self hResizing.
	vFit := self vResizing.
	
	(self owner isNil or: [self owner layoutPolicy isNil])
		ifTrue: [
			hFit == #spaceFill ifTrue: [hFit := #rigid].
			vFit == #spaceFill ifTrue: [vFit := #rigid]].

	"0) The receiver will not adjust to parents layout by growing or shrinking, which means that an accurate layout defines the minimum size. So, compute the layout and return its bounds as minimal extent. DO NOT return fullBounds because the morph itself is being layed out."
	(hFit == #spaceFill or: [vFit == #spaceFill]) 
		ifFalse: [self fullBounds. ^ self bounds extent].

	"1) Ask the layout policy to compute the minimum extent."
	layout := self layoutPolicy.
	layout isNil 
		ifTrue: [minExtent := 0@0]
		ifFalse: [minExtent := layout minExtentOf: self in: self layoutBounds].

	"2) #rigid fitting has to stay as is." 
	hFit == #rigid 
		ifTrue: [minExtent := self width @ minExtent y].
	vFit == #rigid 
		ifTrue: [minExtent := minExtent x @ self height].

	"3) #spaceFill fitting has to account for layout inset."
	hFit == #spaceFill
		ifTrue: [
			(vFit == #shrinkWrap and: [self wrapDirection ~= #none])
				ifTrue: [minExtent := 1 @ minExtent y "Give h-space a chance to v-wrap and v-shrink."]
				ifFalse: [
					extra := self bounds width - self layoutBounds width.
					minExtent := (minExtent x + extra) @ minExtent y]].
	vFit == #spaceFill
		ifTrue: [
			(hFit == #shrinkWrap and: [self wrapDirection ~= #none])
				ifTrue: [minExtent := minExtent x @ 1 "Give v-space a chance to h-wrap and h-shrink."]
				ifFalse: [
					extra := self bounds height - self layoutBounds height.
					minExtent := minExtent x @ (minExtent y + extra)]].

	"4) #shrinkWrap fitting has to support height-for-width (or width-for-height)."
	(hFit == #shrinkWrap and: [layout notNil])
		ifTrue: [
			self fullBounds. "Compute layout now to get shrink-wrapped width."
			minExtent := self width @ minExtent y].
	(vFit == #shrinkWrap and: [layout notNil])
		ifTrue: [
			self fullBounds. "Compute layout now to get shrink-wrapped height."
			minExtent := minExtent x @ self height].

	"5) For morphs without submorphs, use #minWidth and #minHeight to implement #shrinkWrap such as in MenuItemMorph"
	^ minExtent max: self minWidth @ self minHeight! !

!Morph methodsFor: 'layout' stamp: 'mt 8/12/2019 11:45'!
privateFullBoundsForRedraw
	"Private. Compute the current submorph bounds *all the way down* to trigger re-draw. Implementation is based on #privateFullBounds and #submorphBounds. Avoid triggering layout computation but return bounds as is."
	
	| box |
	self hasSubmorphs ifFalse: [^ self outerBounds].
	box := self outerBounds copy.
	box := box quickMerge: (self clipSubmorphs 
						ifTrue: [self submorphBoundsForShrinkWrap intersect: self clippingBounds]
						ifFalse: [self submorphBoundsForShrinkWrap]).
	^box origin asIntegerPoint corner: box corner asIntegerPoint!
]style[(26 2 214 4 1 1 3 1 1 2 4 1 12 1 8 2 1 1 4 1 11 4 3 1 2 1 4 1 11 1 4 3 3 1 2 1 3 1 11 2 4 1 13 8 7 1 1 4 1 27 1 10 1 4 1 14 1 7 8 1 1 4 1 27 1 4 1 3 1 6 1 14 1 7 1 3 1 6 1 14)b,cblack;,c000126126,cblack;,cgray;,cblack;,c106106106,cblack;,cgray;,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c126000000,cblack;,c000000126,cblack;,c106106106,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,b,cblack;,c106106106,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,c000126000,cblack;,c000000126,cblack;,c000126000,c126000000,cblack;,c000000126,c000126000,cblack;,c126000000,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126! !

!Morph methodsFor: 'layout' stamp: 'mt 8/12/2019 11:32'!
submorphBoundsForShrinkWrap
	"Private. Compute the submorph bounds of the receiver to shrink-wrap around. Note that we are not interested in my submorphs' fullBounds. For full-bound wrapping, use #shrinkWrap all the way down."
	
	| box |
	self submorphsDo: [:m |
		m visible ifTrue: [
			box 
				ifNil:[box := m bounds copy]
				ifNotNil:[box := box quickMerge: m bounds]]].
	box ifNil:[^ self layoutBounds]. "e.g., having submorphs but not visible"
	^ box origin asIntegerPoint corner: box corner asIntegerPoint!
]style[(27 2 198 4 1 1 3 1 1 2 4 1 12 3 1 1 1 3 1 1 7 1 7 1 1 4 3 6 6 1 3 1 2 1 1 1 6 1 4 1 5 9 1 3 1 2 1 3 1 11 1 1 1 6 1 1 4 3 1 6 1 1 1 4 1 12 3 40 2 1 1 3 1 6 1 14 1 7 1 3 1 6 1 14)b,cblack;,c000126126,cblack;,cgray;,cblack;,c106106106,cblack;,cgray;,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,cgray;,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,cblack;,c106106106,cblack;,c000000126,c126000126,c106106106,cblack;,b,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,c126000126,cblack;,c000000126,c126000126,c106106106,cblack;,b,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,c126000126,c000126000,cblack;,c106106106,cblack;,c000000126,cblack;,c126000000,cblack;,c126000000,cblack;,c000000126,cblack;,c000126126,cblack;,c126000000,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126! !

!Morph methodsFor: 'layout-menu' stamp: 'mt 8/20/2019 10:19'!
changeHeightForWidth
	"Convenience. Configure morphs that do not have a layout policy to be layed out properly in an owner that has such a policy. Tell that owner that I change my height if somebody changes my width."
	
	self
		hResizing: #spaceFill;
		vResizing: #shrinkWrap;
		wrapDirection: #topToBottom.!
]style[(20 2 195 4 4 3 10 1 10 4 10 1 11 4 14 1 12 1)b,cblack;,c000126126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;! !

!Morph methodsFor: 'layout-menu' stamp: 'mt 8/20/2019 08:35'!
changeTableLayout
	| layout |
	((layout := self layoutPolicy) notNil and:[layout isTableLayout])
		ifTrue:[^self]. "already table layout"
	self layoutPolicy: TableLayout new.!
]style[(17 2 1 1 6 1 1 3 1 6 1 2 1 4 1 12 1 1 6 1 4 1 6 1 13 1 4 7 1 5 3 22 2 4 1 13 13 3 1)b,cblack;,cgray;,cblack;,c106106106,cblack;,cgray;,cblack;,c000126000,c106106106,cblack;,b,cblack;,c126000000,cblack;,c000000126,c000126000,cblack;,c000000126,cblack;,c000000126,c000126000,c106106106,cblack;,c000000126,c000126000,cblack;,c000000126,cblack;,c126000000,cblack;,c000126126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;! !

!Morph methodsFor: 'layout-menu' stamp: 'mt 8/20/2019 10:19'!
changeWidthForHeight
	"Convenience. Configure morphs that do not have a layout policy to be layed out properly in an owner that has such a policy. Tell that owner that I change my width if somebody changes my height."
	
	self
		hResizing: #shrinkWrap;
		vResizing: #spaceFill;
		wrapDirection: #leftToRight.! !

!Morph methodsFor: 'layout-menu' stamp: 'mt 8/20/2019 10:20'!
changesHeightForWidth
	
	^ (self hResizing ~= #shrinkWrap
		and: [self vResizing = #shrinkWrap])
		and: [self wrapDirection ~= #none]!
]style[(21 4 1 2 4 1 9 1 2 1 11 3 4 1 1 4 1 9 1 1 1 11 1 4 4 2 4 1 13 1 2 1 5 1)b,cblack;,c126000000,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,c000126000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;! !

!Morph methodsFor: 'layout-menu' stamp: 'mt 8/20/2019 10:20'!
changesWidthForHeight
	
	^ (self hResizing = #shrinkWrap
		and: [self vResizing ~= #shrinkWrap])
		and: [self wrapDirection ~= #none]!
]style[(21 4 1 2 4 1 9 1 1 1 11 3 4 1 1 4 1 9 1 2 1 11 1 4 4 2 4 1 13 1 2 1 5 1)b,cblack;,c126000000,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,c000126000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;! !

!Morph methodsFor: 'layout-properties' stamp: 'mt 8/21/2019 09:07'!
cellGap
	"Layout specific. This property specifies an extra space *between* cells in the layout."
	| props |
	props := self layoutProperties.
	^props ifNil:[0] ifNotNil:[props cellGap].!
]style[(7 2 88 2 1 1 5 1 1 2 5 1 2 1 4 1 16 3 1 5 1 6 1 1 2 9 1 5 1 7 2)b,cblack;,c000126126,cblack;,cgray;,cblack;,c106106106,cblack;,cgray;,cblack;,c106106106,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,c106106106,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;! !

!Morph methodsFor: 'layout-properties' stamp: 'mt 8/21/2019 09:07'!
cellGap: aNumber
	"Layout specific. This property specifies an extra space *between* cells in the layout."
	self assureTableProperties cellGap: aNumber.
	self layoutChanged.!
]style[(8 1 7 2 88 2 4 1 21 1 8 1 7 3 4 1 13 1)b,cblack;,c000000126,cblack;,c000126126,cblack;,c126000000,cblack;,c000000126,cblack;,cred;,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;! !

!Morph methodsFor: 'layout-properties' stamp: 'mt 8/12/2019 15:31'!
disableLayout
	"Layout specific. Disable laying out the receiver in a layout"
	| props |
	props := self layoutProperties.
	^props ifNil:[false] ifNotNil:[props disableLayout].!
]style[(13 2 62 2 1 1 5 1 1 2 5 1 2 1 4 1 16 3 1 5 1 6 1 5 2 9 1 5 1 13 2)b,cblack;,c000126126,cblack;,cgray;,cblack;,c106106106,cblack;,cgray;,cblack;,c106106106,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,c106106106,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;! !

!Morph methodsFor: 'layout-properties' stamp: 'mt 8/12/2019 17:28'!
disableLayout: aBool
	"Layout specific. Disable laying out the receiver in a layout"

	self fullBounds; layoutChanged.
	self assureLayoutProperties disableLayout: aBool.
	self fullBounds; layoutChanged; changed.!
]style[(14 1 5 2 62 3 4 1 10 2 13 3 4 1 22 1 14 1 5 3 4 1 10 2 13 2 7 1)b,cblack;,c000000126,cblack;,c000126126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;! !

!Morph methodsFor: 'layout-properties' stamp: 'mt 8/12/2019 17:32'!
disableTableLayout: aBool
	"Layout specific. Disable laying out the receiver in table layout"
	
	self fullBounds; layoutChanged.
	self assureLayoutProperties disableTableLayout: aBool.
	self fullBounds; layoutChanged; changed.!
]style[(19 1 5 2 66 4 4 1 10 2 13 3 4 1 22 1 19 1 5 3 4 1 10 2 13 2 7 1)b,cblack;,c000000126,cblack;,c000126126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;! !


!BorderedMorph methodsFor: 'resize handling' stamp: 'mt 8/21/2019 13:52'!
addMorph: aMorph fullFrame: aLayoutFrame
	"Add aMorph according to aLayoutFrame."

	self cellGap > 0 ifTrue: [
		| left right bottom top spacing |

		spacing := self cellGap.
		left := aLayoutFrame leftOffset ifNil: [0].
		right := aLayoutFrame rightOffset ifNil: [0].

		bottom := aLayoutFrame bottomOffset ifNil: [0].
		top := aLayoutFrame topOffset ifNil: [0].
		
		"Add a spacing to the frame if it is not top or leftmost."
		aLayoutFrame leftFraction = 0
			ifFalse: [left := left + spacing]
			ifTrue: [
				"Expect another, resizable widget besides me if I have a fixed width."
				aLayoutFrame hasFixedWidth ifTrue: [right := right - spacing]].
		aLayoutFrame topFraction = 0
			ifFalse: [top := top + spacing]
			ifTrue: [
				"Expect another, resizable widget besides me if I have a fixed height."
				aLayoutFrame hasFixedHeight ifTrue: [bottom := bottom - spacing]].
			
		aLayoutFrame
			topOffset: top;
			bottomOffset: bottom;
			leftOffset: left;
			rightOffset: right].
	
	super addMorph: aMorph fullFrame: aLayoutFrame.
	
	self wantsPaneSplitters ifTrue: [self addPaneSplitters].!
]style[(9 1 6 1 10 1 12 2 39 3 4 1 7 1 1 1 1 1 7 5 1 1 4 1 5 1 6 1 3 1 7 1 1 4 7 1 2 1 4 1 7 4 4 1 2 1 12 1 10 1 6 1 1 1 1 4 5 1 2 1 12 1 11 1 6 1 1 1 1 5 6 1 2 1 12 1 12 1 6 1 1 1 1 4 3 1 2 1 12 1 9 1 6 1 1 1 1 7 58 3 12 1 12 1 1 1 1 4 8 1 1 4 1 2 1 4 1 1 1 7 1 4 7 1 1 5 70 5 12 1 13 1 7 1 1 5 1 2 1 5 1 1 1 7 1 1 4 12 1 11 1 1 1 1 4 8 1 1 3 1 2 1 3 1 1 1 7 1 4 7 1 1 5 71 5 12 1 14 1 7 1 1 6 1 2 1 6 1 1 1 7 1 1 8 12 4 10 1 3 5 13 1 6 5 11 1 4 5 12 1 5 6 5 1 9 1 6 1 10 1 12 5 4 1 18 1 7 2 4 1 16 2)b,cblack;,c000000126,cblack;,b,cblack;,c000000126,cblack;,c000126126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,cgray;,cblack;,cgray;,cblack;,cgray;,cblack;,cgray;,cblack;,cgray;,cblack;,cgray;,cblack;,cgray;,cblack;,cgray;,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,cgray;,cblack;,b,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c126000000,c000126000,cblack;,cgray;,cblack;,b,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c126000000,c000126000,cblack;,cgray;,cblack;,b,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c126000000,c000126000,cblack;,cgray;,cblack;,b,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c126000000,c000126000,cblack;,c000126126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000126000,cgray;,cblack;,b,cblack;,cgray;,cblack;,c000000126,cblack;,cgray;,c000126000,cblack;,c000000126,cblack;,c000126000,cblack;,c000126126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126,cgray;,cblack;,b,cblack;,cgray;,cblack;,c000000126,cblack;,cgray;,c126000126,c000126000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000126000,cgray;,cblack;,b,cblack;,cgray;,cblack;,c000000126,cblack;,cgray;,c000126000,cblack;,c000000126,cblack;,c000126000,cblack;,c000126126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126,cgray;,cblack;,b,cblack;,cgray;,cblack;,c000000126,cblack;,cgray;,c126000126,c000126000,cblack;,c000000126,cblack;,c000000126,cblack;,cgray;,cblack;,c000000126,cblack;,cgray;,cblack;,c000000126,cblack;,cgray;,cblack;,c000000126,cblack;,cgray;,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;! !


!AlignmentMorph class methodsFor: 'instance creation' stamp: 'mt 8/21/2019 11:24'!
columnPrototype
	"Answer a prototypical column"

	| sampleMorphs aColumn |
	sampleMorphs := #(red yellow green) collect:
		[:aColor | Morph new extent: 130 @ 38; color: (Color perform: aColor); setNameTo: aColor asString; yourself].
	aColumn := self inAColumn: sampleMorphs.
	aColumn setNameTo: 'Column'.
	aColumn color: Color veryVeryLightGray.
	aColumn cellGap: 4; layoutInset: 6.
	aColumn enableDragNDrop.
	aColumn setBalloonText: 'Things dropped into here will automatically be organized into a column. Once you have added your own items here, you will want to remove the sample colored rectangles that this started with, and you will want to change this balloon help message to one of your own!!' translated.
	^ aColumn!
]style[(15 2 30 3 1 1 12 1 7 1 1 2 12 1 2 1 1 1 3 1 6 1 5 2 8 5 6 1 1 7 3 1 7 1 3 1 1 1 2 2 6 1 1 6 8 1 6 1 2 10 1 6 1 8 2 8 4 7 1 2 1 4 1 10 1 12 3 7 1 10 1 8 3 7 1 6 7 17 3 7 1 8 1 1 2 12 1 1 3 7 1 15 3 7 1 15 1 266 1 10 3 1 1 7)bu,cblack;,c000126126,cblack;,cgray;,cblack;,c106106106,cblack;,c106106106,cblack;,cgray;,cblack;,c106106106,cblack;,b,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,cgray;,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000126000,cblack;,c000000126,cblack;,c000000126,c000126000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c106106106,cblack;,c106106106,cblack;,c000000126,cblack;,c126000126n,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c106106106,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c126000126n,cblack;,c000000126,cblack;,c126000000,cblack;,c106106106! !

!AlignmentMorph class methodsFor: 'instance creation' stamp: 'mt 8/21/2019 11:24'!
rowPrototype
	"Answer a prototypical row"

	| sampleMorphs aRow |
	sampleMorphs := (1 to: (2 + 3 atRandom)) collect:
		[:integer | EllipseMorph new extent: ((60 + (20 atRandom)) @ (80 + ((20 atRandom)))); color: Color random; setNameTo: ('egg',  integer asString); yourself].
	aRow := self inARow: sampleMorphs.
	aRow setNameTo: 'Row'.
	aRow enableDragNDrop.
	aRow cellGap: 6.
	aRow layoutInset: 8.
	aRow setBalloonText: 'Things dropped into here will automatically be organized into a row. Once you have added your own items here, you will want to remove the sample colored eggs that this started with, and you will want to change this balloon help message to one of your own!!' translated.
	aRow color: Color veryVeryLightGray.
	^ aRow

			"AlignmentMorph rowPrototype openInHand"!
]style[(12 2 27 3 1 1 12 1 4 1 1 2 12 1 2 2 1 1 3 1 1 1 1 1 1 1 1 8 1 2 8 5 7 1 1 14 3 1 7 1 1 1 2 1 1 1 3 1 8 1 1 1 1 1 1 2 1 1 1 1 1 2 1 8 1 1 1 1 2 6 7 6 2 10 1 1 5 1 2 7 1 8 1 2 8 4 4 1 2 1 4 1 7 1 12 3 4 1 10 1 5 3 4 1 15 3 4 1 8 1 1 3 4 1 12 1 1 3 4 1 15 1 257 1 10 3 4 1 6 7 17 3 1 1 4 5 40)bu,cblack;,c000126126,cblack;,cgray;,cblack;,c106106106,cblack;,c106106106,cblack;,cgray;,cblack;,c106106106,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c000126000,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,c000126000,cblack;,c000000126,cblack;,c000000126,cblack;,cgray;,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c126000126,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,c126000000,c126000126,cblack;,c000000126,cblack;,c126000126,c126000000,cblack;,c000000126,cblack;,c126000000,c000234000,c126000000,cblack;,c000000126,c000234000,c126000000,c126000126,c000126000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c126000126n,c000000126,cblack;,c000000126,cblack;,c000000126,c000126000,cblack;,c000000126,cblack;,c106106106,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c106106106,cblack;,c106106106,cblack;,c000000126,cblack;,c126000126n,cblack;,c106106106,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c126000000,cblack;,c106106106,cblack;,c000000126,cblack;,c126000000,cblack;,c106106106,cblack;,c000000126,cblack;,c126000126n,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c106106106,cblack;,c000126126! !


!DialogWindow methodsFor: 'updating' stamp: 'mt 8/11/2019 21:23'!
updateButtonExtent: margin

	"Update all button extents."
	(buttonRow submorphs collect: [:ea | ea minimumExtent]) max + margin in: [:preferredExtent |
		buttonRow submorphsDo: [:ea | ea extent: preferredExtent]].
	
	"See if horizontal button layout would be more appropriate."
	self flag: #magicNumber. "mt: Remove number with computation, maybe choose button font and 20 characters"
	(buttonRow submorphs collect: [:ea | ea fullBounds width]) sum > 400
		ifTrue: [buttonRow
					hResizing: #shrinkWrap;
					listDirection: #topToBottom;
					wrapDirection: #none;
					layoutInset: (buttonRow owner fullBounds width - (buttonRow owner layoutInset left*2) - buttonRow submorphs first fullBounds width // 2@0)]
		ifFalse: [buttonRow
					hResizing: #spaceFill;
					listDirection: #leftToRight;
					wrapDirection: #topToBottom;
					layoutInset: 0].!
]style[(19 1 6 3 28 13 9 1 8 1 1 1 2 1 1 1 2 1 13 1 2 3 1 1 1 6 1 3 3 15 1 1 13 12 1 1 1 2 1 1 1 2 1 7 1 15 1 6 60 2 4 1 5 1 12 2 80 13 9 1 8 1 1 1 2 1 1 1 2 1 10 1 5 1 2 3 1 1 1 3 3 7 17 10 1 11 7 14 1 12 7 14 1 5 7 12 1 1 10 5 1 10 1 5 1 1 1 1 10 5 1 11 1 5 1 1 1 1 11 9 1 5 1 10 1 5 1 2 1 1 1 1 1 4 8 17 10 1 10 7 14 1 12 7 14 1 12 7 12 1 1 2)b,cblack;,c000000126,cblack;,c000126126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,cblack;,c000000126,cblack;,cgray;,cblack;,c000000126,cblack;,c000000126,c000126000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,cgray;,cblack;,c000000126,cblack;,c000126000,cblack;,c000000126,cblack;,cgray;,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,c000126000,cblack;,c000126126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000126126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,cblack;,c000000126,cblack;,cgray;,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,c000126000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,c126000000,c126000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,c000000126,c126000000,c000126000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;! !

!DialogWindow methodsFor: 'running' stamp: 'mt 8/12/2019 14:58'!
getUserResponse

	| hand world |
	self message ifEmpty: [messageMorph delete]. "Do not waste space."
	self paneMorph submorphs
		ifEmpty: ["Do not waste space and avoid strange button-row wraps."
			self paneMorph delete.
			self buttonRowMorph wrapDirection: #none]. 
	
	hand := self currentHand.
	world := self currentWorld.

	self fullBounds.
	self moveToPreferredPosition.
	self openInWorld: world.
	
	hand showTemporaryCursor: nil. "Since we are out of context, reset the cursor."
	
	hand keyboardFocus in: [:priorKeyboardFocus |
		hand mouseFocus in: [:priorMouseFocus |
			self exclusive ifTrue: [hand newMouseFocus: self].
			hand newKeyboardFocus: self.

			[self isInWorld] whileTrue:[world doOneSubCycle].

			hand newKeyboardFocus: priorKeyboardFocus.
			hand newMouseFocus: priorMouseFocus]].

	^ result!
]style[(15 3 1 1 4 1 5 1 1 2 4 1 7 1 8 15 6 3 21 2 4 1 9 1 9 3 8 2 56 4 4 1 9 1 6 5 4 1 14 1 14 1 5 7 4 1 2 1 4 1 11 3 5 1 2 1 4 1 12 4 4 1 10 3 4 1 23 3 4 1 12 1 5 5 4 1 20 1 3 2 48 4 4 1 13 1 3 3 18 1 1 3 4 1 10 1 3 1 1 1 15 1 1 4 4 1 9 1 7 1 1 4 1 14 1 4 1 5 4 1 17 1 4 6 1 4 1 9 1 1 10 1 5 1 13 1 6 4 1 17 1 18 5 4 1 14 1 15 1 5 1 7)b,cblack;,cgray;,cblack;,c106106106,cblack;,c106106106,cblack;,cgray;,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c106106106,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c106106106,cblack;,c106106106,cblack;,c000000126,cblack;,c126000000,cblack;,c000126126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,cgray;,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,cblack;,c000000126,cblack;,cgray;,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126,c106106106,cblack;,c000000126,cblack;,c126000000,c126000126,cblack;,c106106106,cblack;,c000000126,cblack;,c126000000,cblack;,c126000126,c126000000,cblack;,c000000126,c126000126,cblack;,c000000126,c126000126,c106106106,cblack;,c000000126,c126000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,c000126000,cblack;,c126000000,cblack;! !

!DialogWindow methodsFor: 'initialization' stamp: 'mt 8/21/2019 11:23'!
createBody

	| body |
	body := Morph new
		name: 'Body';
		changeTableLayout;
		hResizing: #shrinkWrap;
		vResizing: #shrinkWrap;
		rubberBandCells: true;
		listDirection: #topToBottom;
		layoutInset: (10@5 corner: 10@10);
		cellGap: 5;
		color: Color transparent;
		yourself.
	body addAllMorphs: {self createMessage: ''. self createPane. self createButtonRow. self createFilter}.
	self addMorphBack: body.!
]style[(10 3 1 1 4 1 1 2 4 1 2 7 3 3 5 1 6 4 17 4 10 1 11 4 10 1 11 4 16 1 4 4 14 1 12 4 12 2 2 1 1 1 7 1 2 1 2 5 8 1 1 4 6 7 11 4 8 3 4 1 13 2 4 1 14 1 2 2 4 1 10 2 4 1 15 2 4 1 12 4 4 1 13 1 4 1)b,cblack;,cgray;,cblack;,c106106106,cblack;,cgray;,cblack;,c106106106,cblack;,b,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126n,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,c000000126,c126000000,cblack;,c000000126,cblack;,c126000000,c000000126,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000126n,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c106106106,cblack;! !

!DialogWindow methodsFor: 'initialization' stamp: 'mt 8/21/2019 11:23'!
createButtonRow

	^ buttonRow := Morph new
		name: 'Buttons';
		color: Color transparent;
		changeTableLayout;
		vResizing: #shrinkWrap;
		hResizing: #spaceFill;
		listDirection: #leftToRight;
		listCentering: #center;
		cellGap: 5;
		yourself!
]style[(15 3 1 11 2 7 3 3 5 1 9 4 6 7 11 4 17 4 10 1 11 4 10 1 10 4 14 1 12 4 14 1 7 4 8 1 1 4 8)b,cblack;,c126000000,cblack;,b,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126n,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126! !

!DialogWindow methodsFor: 'initialization' stamp: 'mt 8/12/2019 17:03'!
createTitle: aString 
	"Mimick behavior of MenuMorph title creation."
	
	| box closeButton menuButton |
	box := Morph new
		name: #title;
		changeTableLayout;
		listDirection: #leftToRight;
		yourself.
	
	titleMorph := aString asText asMorph lock.

	closeButton := SystemWindowButton new
		color: Color transparent;
		target: self;
		extent: 12@12;
		actionSelector: #cancelDialog;
		balloonText: 'Cancel this dialog' translated;
		borderWidth: 0;
		labelGraphic: SystemWindow closeBoxImage;
		extent: SystemWindow closeBoxImage extent;
		visible: self class includeCloseButton;
		yourself.

	menuButton := SystemWindowButton new
		color: Color transparent;
		target: self;
		actionSelector: #offerDialogMenu;
		balloonText: 'Dialog menu' translated;
		borderWidth: 0;
		labelGraphic: SystemWindow menuBoxImage;
		extent: SystemWindow menuBoxImage extent;
		visible: self class includeControlMenu;
		yourself.
	
	box addAllMorphs: {closeButton. titleMorph. menuButton}.
	
	self addMorphBack: box.
	self setTitleParameters.! !

!DialogWindow methodsFor: 'initialization' stamp: 'mt 8/20/2019 11:27'!
initialize

	super initialize.
	
	self
		changeTableLayout;
		listDirection: #topToBottom;
		hResizing: #shrinkWrap;
		vResizing: #shrinkWrap;
		rubberBandCells: true;
		setProperty: #indicateKeyboardFocus toValue: #never.
	
	self createTitle: 'Dialog'.
	self createBody.
	
	self setDefaultParameters.
	
	keyMap := Dictionary new.
	exclusive := true.
	autoCancel := false.
	preferredPosition := ActiveWorld center.!
]style[(10 3 5 1 10 5 4 3 17 4 14 1 12 4 10 1 11 4 10 1 11 4 16 1 4 4 12 1 22 1 8 1 6 5 4 1 12 1 8 3 4 1 10 5 4 1 20 12 2 12 3 13 2 1 4 14 2 1 5 21 2 13 6 1)b,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000126n,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,b,cblack;,c000000126,cblack;,b,cblack;,c126000000,cblack;,b,cblack;,c126000000,cblack;,b,cblack;,c000000126,cblack;! !

!DialogWindow methodsFor: 'initialization' stamp: 'mt 8/7/2019 17:37'!
moveToPreferredPosition
	self center:
		(preferredPosition isPoint
			ifTrue: [ preferredPosition ]
			ifFalse: [ self center + self currentHand position - preferredPosition center ]).
	self bounds: (self bounds translatedToBeWithin: self currentWorld bounds)!
]style[(23 2 4 1 7 22 7 4 7 1 1 19 1 4 8 1 1 1 4 1 6 1 1 1 4 1 11 1 8 1 1 19 6 1 1 4 4 1 7 2 4 1 6 1 21 1 4 1 12 1 6 1)b,cblack;,c125000000,cblack;,c000000125,cblack;,c000000125,cblack;,c000000125,cblack;,c000125000,cblack;,c000125000,cblack;,c000000125,cblack;,c000125000,cblack;,c125000000,cblack;,c000000125,cblack;,c000000125,cblack;,c125000000,cblack;,c000000125,cblack;,c000000125,cblack;,c000000125,cblack;,c000000125,cblack;,c000125000,cblack;,c125000000,cblack;,c000000125,cblack;,c125000000,cblack;,c000000125,cblack;,c000000125,cblack;,c125000000,cblack;,c000000125,cblack;,c000000125,cblack;! !

!DialogWindow methodsFor: 'initialization' stamp: 'mt 8/12/2019 17:08'!
setMessageParameters
	
	messageMorph ifNotNil: [
		| fontToUse colorToUse |
		fontToUse := self userInterfaceTheme font ifNil: [TextStyle defaultFont].
		colorToUse := self userInterfaceTheme textColor ifNil: [Color black].
		
		messageMorph
			hResizing: #shrinkWrap;
			vResizing: #shrinkWrap.
		
		messageMorph contents
			addAttribute: (TextFontReference toFont: fontToUse);
			addAttribute: (TextColor color: colorToUse).
		messageMorph textColor: colorToUse].!
]style[(20 17 9 5 1 1 9 1 10 1 1 3 9 1 2 1 4 1 18 1 4 1 6 1 1 10 11 1 4 10 1 2 1 4 1 18 1 9 1 6 1 1 6 5 1 23 10 1 11 5 10 1 11 20 8 4 13 1 1 18 7 1 9 1 5 13 1 1 10 6 1 10 1 17 10 1 10 2)b,cblack;,c000000126,cblack;,cgray;,cblack;,cgray;,cblack;,cgray;,cblack;,cgray;,cblack;,cgray;,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,cblack;,c000000126,c000126000,cblack;,cgray;,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,cblack;,c000000126,c000126000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,cblack;,c000000126,cblack;,cgray;,c000126000,cblack;,c000000126,cblack;,c000126000,cblack;,c000000126,cblack;,cgray;,c000126000,cblack;,c000000126,cblack;,cgray;,cblack;! !

!DialogWindow methodsFor: 'initialization' stamp: 'mt 8/21/2019 11:23'!
setTitleParameters

	(self submorphNamed: #title) ifNotNil: [:title |
		title
			fillStyle: (self class gradientDialog
				ifFalse: [SolidFillStyle color: (self userInterfaceTheme titleColor ifNil: [Color r: 0.658 g: 0.678 b: 0.78])]
				ifTrue: [self titleGradientFor: title from: (self userInterfaceTheme titleColor ifNil: [Color r: 0.658 g: 0.678 b: 0.78])]);
			borderStyle: (self userInterfaceTheme titleBorderStyle ifNil: [BorderStyle simple]) copy;
			borderColor: (self userInterfaceTheme titleBorderColor ifNil: [Color r: 0.6 g: 0.7 b: 1]);
			borderWidth: (self userInterfaceTheme titleBorderWidth ifNil: [0]);
			cornerStyle: (self wantsRoundedCorners ifTrue: [#rounded] ifFalse: [#square]);
			vResizing: #shrinkWrap;
			hResizing: #spaceFill;
			cellGap: 5;
			layoutInset: (5@3 corner: 5@ (2+(self wantsRoundedCorners ifFalse: [0] ifTrue: [self cornerRadius])))].
	
	titleMorph ifNotNil: [
		| fontToUse colorToUse |
		fontToUse := self userInterfaceTheme titleFont ifNil: [TextStyle defaultFont].
		colorToUse := self userInterfaceTheme titleTextColor ifNil: [Color black].
	
		"Temporary HACK for 64-bit CI build. Can be removed in the future."
		titleMorph contents isText ifFalse: [^ self].
		
		titleMorph
			hResizing: #spaceFill;
			vResizing: #shrinkWrap.
	
		titleMorph contents
			addAttribute: (TextFontReference toFont: fontToUse);
			addAttribute: (TextColor color: colorToUse);
			addAttribute: TextAlignment centered].!
]style[(18 4 4 1 14 1 6 2 9 3 5 1 1 3 5 4 10 1 1 4 1 5 1 14 5 8 1 1 15 6 1 5 1 18 1 10 1 6 1 1 6 2 1 5 1 2 1 5 1 2 1 4 1 1 1 5 7 1 1 4 1 17 1 5 1 5 1 5 1 18 1 10 1 6 1 1 6 2 1 5 1 2 1 5 1 2 1 4 1 1 1 1 5 12 1 1 4 1 18 1 16 1 6 1 1 12 6 1 1 1 4 5 12 1 1 4 1 18 1 16 1 6 1 1 6 2 1 3 1 2 1 3 1 2 1 1 1 1 5 12 1 1 4 1 18 1 16 1 6 1 1 1 1 1 5 12 1 1 4 1 19 1 7 1 1 8 1 1 8 1 1 7 1 1 5 10 1 11 5 10 1 10 5 8 1 1 5 12 1 1 1 1 1 1 7 1 1 1 1 1 1 1 5 1 19 1 8 1 1 1 1 1 7 1 1 4 1 12 1 1 1 1 17 9 5 1 1 9 1 10 1 1 3 9 1 2 1 4 1 18 1 9 1 6 1 1 10 11 1 4 10 1 2 1 4 1 18 1 14 1 6 1 1 6 5 1 6 67 14 8 1 6 1 8 1 1 1 1 4 1 21 10 1 10 5 10 1 11 17 8 4 13 1 1 18 7 1 9 1 5 13 1 1 10 6 1 10 1 5 13 15 8 2)b,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,cgray;,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000234000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,c000234000,c126000000,c126000126,cblack;,c000000126,cblack;,c126000126,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000234000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,c000234000,c126000000,c126000126,c000126000,cblack;,c000000126,cblack;,c000126000,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126,cblack;,c000000126,c126000126,c000126000,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,c126000126,c000126000,cblack;,c000000126,cblack;,c000126000,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126,c126000000,c126000126,c000126000,cblack;,c000000126,cblack;,c000126000,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126,c000000126,c126000126,cblack;,c000000126,cblack;,c126000126,c000000126,c126000126,c000126000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000126000,c126000000,c000000126,c126000000,cblack;,c000000126,cblack;,c126000000,c000000126,cblack;,c126000126,c126000000,c000000126,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000234000,c126000000,c000234000,cblack;,c000000126,cblack;,c000234000,c126000000,cblack;,c000000126,c000234000,c126000000,c126000126,c000126000,cblack;,c000000126,cblack;,cgray;,cblack;,cgray;,cblack;,cgray;,cblack;,cgray;,cblack;,cgray;,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,cblack;,c000000126,c000126000,cblack;,cgray;,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,cblack;,c000000126,c000126000,cblack;,c000126126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c126000000,cblack;,c126000000,c000126000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,cblack;,c000000126,cblack;,cgray;,c000126000,cblack;,c000000126,cblack;,c000126000,cblack;,c000000126,cblack;,cgray;,c000126000,cblack;,c000000126,cblack;,c000000126,cblack;! !

!DialogWindow methodsFor: '*ToolBuilder-Morphic-opening' stamp: 'mt 8/7/2019 17:44'!
openAsTool

	^ self getUserResponse!
]style[(10 3 1 1 4 1 15)b,cblack;,c126000000,cblack;,c126000000,cblack;,c000000126! !


!GradientEditor methodsFor: 'initialization' stamp: 'mt 8/21/2019 11:24'!
addButtonRow
	| button button2 buttonRow button3 |
	buttonRow := RectangleMorph new borderWidth: 0; 
		color: Color transparent;
		layoutPolicy: TableLayout new;
		 hResizing: #spaceFil;
		 vResizing: #spaceFill;
		 cellPositioning: #center;
		 listCentering: #topLeft;
		 listDirection: #LeftToRight;
		 reverseTableCells: true;
		 cellGap: 4.

	button := PluggableButtonMorph on: self
				getState: nil
				action: #addHandle
				label: #addColorButtonLabel.
	button hResizing: #spaceFill;
			vResizing: #spaceFill.
	buttonRow  addMorph: button.

	button2 := PluggableButtonMorph on: self
				getState: nil
				action: #deleteHandle
				label: #removeColorButtonLabel.
	button2 hResizing: #spaceFill;
			vResizing: #spaceFill.
	buttonRow addMorph: button2.

	button3 := PluggableButtonMorph on: self
				getState: nil
				action: #delete
				label: #closeButtonLabel.
	button3 hResizing: #spaceFill;
			vResizing: #spaceFill.
	buttonRow addMorph: button3.
	
	self addMorph: buttonRow!
]style[(12 2 1 1 6 1 7 1 9 1 7 1 1 2 9 1 2 16 3 1 12 1 1 5 6 7 11 4 13 13 3 5 10 1 9 5 10 1 10 5 16 1 7 5 14 1 8 5 14 1 12 5 18 1 4 5 8 1 1 4 6 1 2 22 3 1 4 5 9 1 3 5 7 1 10 5 6 1 20 3 6 1 10 1 10 5 10 1 10 3 9 2 9 1 6 4 7 1 2 22 3 1 4 5 9 1 3 5 7 1 13 5 6 1 23 3 7 1 10 1 10 5 10 1 10 3 9 1 9 1 7 4 7 1 2 22 3 1 4 5 9 1 3 5 7 1 7 5 6 1 17 3 7 1 10 1 10 5 10 1 10 3 9 1 9 1 7 5 4 1 9 1 9)b,cblack;,cgray;,cblack;,c106106106,cblack;,c106106106,cblack;,c106106106,cblack;,c106106106,cblack;,cgray;,cblack;,c106106106,cblack;,b,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c106106106,cblack;,b,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c106106106,cblack;,c106106106,cblack;,b,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c106106106,cblack;,c106106106,cblack;,b,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c106106106,cblack;,c126000000,cblack;,c000000126,cblack;,c106106106! !

!GradientEditor methodsFor: 'initialization' stamp: 'mt 8/21/2019 11:24'!
myLayout
	self color: (Color white darker) ;
		 cornerStyle: #rounded ;
		 borderWidth: 0;
		 layoutPolicy: TableLayout new;
		 hResizing: #shrinkWrap;
		 vResizing: #shrinkWrap;
		 cellPositioning: #center;
		 listCentering: #topLeft;
		 layoutInset: 4;
		 listDirection: #topToBottom;
		 reverseTableCells: true;
		 wrapCentering: #topLeft;
		 cellGap: 4!
]style[(8 2 4 1 6 8 5 1 6 7 12 1 8 6 12 1 1 5 13 13 3 5 10 1 11 5 10 1 11 5 16 1 7 5 14 1 8 5 12 1 1 5 14 1 12 5 18 1 4 5 14 1 8 5 8 1 1)b,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000! !


!HSVAColorSelectorMorph methodsFor: 'initialization' stamp: 'mt 8/21/2019 11:24'!
initialize
	"Initialize the receiver."

	super initialize.
	self
		extent: 180@168;
		changeTableLayout;
		cellGap: 4;
		aMorph: self newAColorMorph;
		hsvMorph: self newHSVColorMorph;
		addMorphBack: self hsvMorph;
		addMorphBack: self aMorph.
	self aMorph color: self hsvMorph selectedColor!
]style[(10 2 26 3 5 1 10 3 4 3 7 1 3 1 3 4 17 4 8 1 1 4 7 1 4 1 14 4 9 1 4 1 16 4 13 1 4 1 8 4 13 1 4 1 6 3 4 1 6 1 6 1 4 1 8 1 13)b,cblack;,c000126126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,c000000126,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126! !


!HSVColorSelectorMorph methodsFor: 'initialization' stamp: 'mt 8/21/2019 11:24'!
initialize
	"Initialize the receiver."

	super initialize.
	self
		borderWidth: 0;
		changeTableLayout;
		cellGap: 4;
		listDirection: #leftToRight;
		cellPositioning: #topLeft;
		svMorph: self newSVColorMorph;
		hMorph: self newHColorMorph;
		addMorphBack: self svMorph;
		addMorphBack: self hMorph;
		extent: 192@152;
		hue: 0.5!
]style[(10 2 26 3 5 1 10 3 4 3 12 1 1 4 17 4 8 1 1 4 14 1 12 4 16 1 8 4 8 1 4 1 15 4 7 1 4 1 14 4 13 1 4 1 7 4 13 1 4 1 6 4 7 1 3 1 3 4 4 1 3)b,cblack;,c000126126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,c000000126,c126000000,cblack;,c000000126,cblack;,c126000000! !


!MenuItemMorph methodsFor: 'initialization' stamp: 'mt 7/9/2016 15:57'!
initialize
	"initialize the state of the receiver"
	super initialize.
	""
	
	contents := ''.
	hasFocus := false.
	isEnabled := true.
	subMenu := nil.
	isSelected := false.
	target := nil.
	selector := nil.
	arguments := nil.
	font := self userInterfaceTheme font ifNil: [TextStyle defaultFont].
	self
		color: (self userInterfaceTheme textColor ifNil: [Color black]);
		hResizing: #spaceFill;
		vResizing: #shrinkWrap! !


!MenuMorph methodsFor: 'initialization' stamp: 'mt 8/9/2019 14:14'!
initialize
	super initialize.

	self setDefaultParameters.

	self changeTableLayout.
	self listDirection: #topToBottom.
	self hResizing: #shrinkWrap.
	self vResizing: #shrinkWrap.
	defaultTarget := nil.
	selectedItem := nil.
	stayUp := false.
	popUpOwner := nil.!
]style[(10 2 5 1 10 4 4 1 20 4 4 1 17 3 4 1 14 1 12 3 4 1 10 1 11 3 4 1 10 1 11 17 2 1 3 16 2 1 3 10 2 1 5 14 2 1 3 1)b,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,b,cblack;,c126000000,cblack;,b,cblack;,c126000000,cblack;,b,cblack;,c126000000,cblack;,b,cblack;,c126000000,cblack;! !

!MenuMorph methodsFor: 'initialization' stamp: 'mt 8/21/2019 10:16'!
setTitleParametersFor: aMenuTitle 

	aMenuTitle
		color: (self userInterfaceTheme titleColor ifNil: [Color transparent]);
		borderStyle: (self userInterfaceTheme titleBorderStyle ifNil: [BorderStyle simple]) copy;
		borderColor: (self userInterfaceTheme titleBorderColor ifNil: [Color r: 0.6 g: 0.7 b: 1]);
		borderWidth: (self userInterfaceTheme titleBorderWidth ifNil: [0]);
		cornerStyle: (self wantsRoundedCorners ifTrue: [#rounded] ifFalse: [#square]);
		vResizing: #shrinkWrap;
		wrapCentering: #center;
		cellPositioning: #center;
		cellGap: 5;
		layoutInset: (5@0 corner: 5@0).!
]style[(22 1 10 4 10 3 6 2 4 1 18 1 10 1 6 1 1 6 11 1 5 12 2 4 1 18 1 16 1 6 1 1 12 6 1 2 4 4 12 2 4 1 18 1 16 1 6 1 1 6 2 1 3 1 2 1 3 1 2 1 1 1 5 12 2 4 1 18 1 16 1 6 1 1 1 1 5 12 2 4 1 19 1 7 1 1 8 1 1 8 1 1 7 1 5 10 1 11 4 14 1 7 4 16 1 7 4 8 1 1 4 12 2 1 1 1 1 7 1 1 1 1 2)b,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,cblack;,c000000126,c000126000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,cblack;,c000000126,c000126000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,c000126000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c126000000,c000126000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c000000126,c000126000,cblack;,c000000126,cblack;,c000126000,c000000126,c000126000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,c000000126,c126000000,cblack;,c000000126,cblack;,c126000000,c000000126,c126000000,cblack;! !


!MorphicToolBuilder methodsFor: 'widgets optional' stamp: 'mt 8/21/2019 10:18'!
buildPluggableDialog: aSpec

	| widget |

	widget := self dialogClass new.
	self register: widget id: aSpec name.
	
	widget model: aSpec model.

	"Set child dependent layout properties. The pane morph holds the special contents."
	widget paneMorph wantsPaneSplitters: (aSpec wantsResizeHandles ifNil: [true]).
	self setLayoutHintsFor: widget paneMorph spec: aSpec.
	widget paneMorph layoutInset: (aSpec padding ifNil: [ProportionalSplitterMorph gripThickness]).
	widget paneMorph cellGap: (aSpec spacing ifNil: [ProportionalSplitterMorph gripThickness]).
	widget paneMorph wantsPaneSplitters ifTrue: [
		widget paneMorph addCornerGrips"addEdgeGrips".
		widget paneMorph grips do: [:ea | ea showHandle: true]].

	"Now create the children."
	panes := OrderedCollection new.
	aSpec children isSymbol
		ifTrue: [
			widget getChildrenSelector: aSpec children.
			widget update: aSpec children]
		ifFalse: [
			self buildAll: aSpec children in: widget paneMorph].

	"Now create the buttons."
	aSpec buttons isSymbol
		ifTrue: [
			widget getButtonsSelector: aSpec buttons.
			widget update: aSpec buttons]
		ifFalse: [
			self buildAll: aSpec buttons in: widget buttonRowMorph.
			widget updateButtonProperties].

	aSpec title ifNotNil: [:label |
		label isSymbol 
			ifTrue:[widget getTitleSelector: label; update: label]
			ifFalse:[widget title: label]].
	aSpec message ifNotNil: [:label |
		label isSymbol 
			ifTrue:[widget getMessageSelector: label; update: label]
			ifFalse:[widget message: label]].
	
	"Interaction behavior."
	aSpec autoCancel ifNotNil: [:b | widget autoCancel: b].
	aSpec exclusive ifNotNil: [:b | widget exclusive: b].
		
	widget closeDialogSelector: aSpec closeAction.
	self buildHelpFor: widget spec: aSpec. 

	"Everything is shrink-wrapped around the pane morph."
	widget paneMorph extent: (aSpec extent ifNil:[widget initialExtent]).

	^ widget!
]style[(21 1 5 3 1 1 6 1 1 3 6 1 2 1 4 1 11 1 3 3 4 1 9 1 6 1 3 1 5 1 4 5 6 1 6 1 5 1 5 4 83 2 6 1 9 1 19 2 5 1 18 1 6 1 1 4 1 4 4 1 18 1 6 1 9 1 5 1 5 3 6 1 9 1 12 2 5 1 7 1 6 1 1 26 13 1 4 6 1 9 1 8 2 5 1 7 1 6 1 1 26 13 1 4 6 1 9 1 18 1 7 5 6 1 9 1 14 14 4 6 1 9 1 5 1 3 1 1 1 2 1 1 1 2 1 11 1 4 1 5 26 8 2 19 3 3 5 1 8 1 8 3 7 6 6 1 20 1 5 1 8 5 6 1 7 1 5 1 8 4 8 6 4 1 9 1 5 1 8 1 3 1 6 1 9 5 25 2 5 1 7 1 8 3 7 6 6 1 19 1 5 1 7 5 6 1 7 1 5 1 7 4 8 6 4 1 9 1 5 1 7 1 3 1 6 1 14 5 6 1 22 5 5 1 5 1 9 3 5 1 1 3 5 1 8 5 7 1 6 1 17 1 5 2 7 1 5 1 4 8 1 6 1 6 1 5 1 4 5 1 7 1 9 3 5 1 1 3 5 1 8 5 7 1 6 1 19 1 5 2 7 1 5 1 4 8 1 6 1 8 1 5 1 6 23 2 5 1 10 1 9 3 1 1 1 1 6 1 11 1 1 4 5 1 9 1 9 3 1 1 1 1 6 1 10 1 1 7 6 1 20 1 5 1 11 3 4 1 13 1 6 1 5 1 5 5 53 2 6 1 9 1 7 2 5 1 6 1 6 1 6 1 13 1 5 1 1 6)b,cblack;,c000000126,cblack;,cgray;,cblack;,c106106106,cblack;,cgray;,cblack;,c106106106,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c126000000,c000126000,cblack;,c126000000,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,cblack;,c000000126,c000126000,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,cblack;,c000000126,c000126000,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,c000126126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,cblack;,c000000126,cblack;,cgray;,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,c000126000,cblack;,c000126126,cblack;,b,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000126126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,cgray;,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,c000126000,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,c000126000,cblack;,c000000126,c000126000,c106106106,cblack;,c000000126,cblack;,c000000126,c000126000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,cgray;,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,c000126000,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,c000126000,cblack;,c000000126,c000126000,c106106106,cblack;,c000000126,cblack;,c000000126,c000126000,cblack;,c000126126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,cgray;,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,cgray;,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000126126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,c000126000,c106106106,cblack;,c000000126,c000126000,cblack;,c126000000,cblack;,c106106106! !

!MorphicToolBuilder methodsFor: 'widgets required' stamp: 'mt 8/21/2019 10:18'!
buildPluggablePanel: aSpec

	| widget |
	widget := self panelClass new.
	self register: widget id: aSpec name.

	widget model: aSpec model.

	"Set child dependent layout properties."
	widget wantsPaneSplitters: (aSpec wantsResizeHandles ifNil: [false]).
	self setLayoutHintsFor: widget spec: aSpec.
	widget layoutInset: (aSpec padding ifNil: [0]).
	widget cellGap: (aSpec spacing ifNil: [
		widget wantsPaneSplitters
			ifTrue: [ProportionalSplitterMorph gripThickness]
			ifFalse: [2]]).

	"Now create the children."
	aSpec children isSymbol
		ifTrue: [
			widget getChildrenSelector: aSpec children.
			widget update: aSpec children]
		ifFalse: [
			self buildAll: aSpec children in: widget].

	self setFrame: aSpec frame in: widget.
	self setLayout: aSpec layout in: widget.
	
	parent ifNotNil:[self add: widget to: parent].

	widget borderWidth: 0.
	self buildHelpFor: widget spec: aSpec. 
	widget color: Color transparent.
	
	^ widget!
]style[(20 1 5 3 1 1 6 1 1 2 6 1 2 1 4 1 10 1 3 3 4 1 9 1 6 1 3 1 5 1 4 4 6 1 6 1 5 1 5 4 40 2 6 1 19 2 5 1 18 1 6 1 1 5 1 4 4 1 18 1 6 1 5 1 5 3 6 1 12 2 5 1 7 1 6 1 1 1 1 4 6 1 8 2 5 1 7 1 6 1 1 3 6 1 18 4 7 1 1 26 13 1 4 8 1 1 1 1 1 5 26 2 5 1 8 1 8 3 7 6 6 1 20 1 5 1 8 5 6 1 7 1 5 1 8 4 8 6 4 1 9 1 5 1 8 1 3 1 6 5 4 1 9 1 5 1 5 1 3 1 6 3 4 1 10 1 5 1 6 1 3 1 6 12 9 1 4 1 4 1 6 1 3 12 6 1 12 1 1 3 4 1 13 1 6 1 5 1 5 4 6 1 6 7 11 5 1 1 6)b,cblack;,c000000126,cblack;,cgray;,cblack;,c106106106,cblack;,cgray;,cblack;,c106106106,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c126000000,c000126000,cblack;,c126000000,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c126000000,c000126000,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126,cblack;,c000000126,c126000126,cblack;,c000000126,cblack;,c126000126,c126000000,c126000126,c000126000,cblack;,c000126126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c126000000,cblack;,c126000000,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c106106106! !

!MorphicToolBuilder methodsFor: 'widgets required' stamp: 'mt 8/21/2019 10:18'!
buildPluggableWindow: aSpec
	| widget |

	aSpec layout == #proportional ifFalse:[
		"This needs to be implemented - probably by adding a single pane and then the rest"
		^self error: 'Not implemented'.
	].

	widget := (self windowClassFor: aSpec) new.
	self register: widget id: aSpec name.
	
	widget model: aSpec model.

	"Set child dependent layout properties."
	widget wantsPaneSplitters: (aSpec wantsResizeHandles ifNil: [true]).
	self setLayoutHintsFor: widget spec: aSpec.
	widget layoutInset: (aSpec padding ifNil: [ProportionalSplitterMorph gripThickness]).
	widget cellGap: (aSpec spacing ifNil: [ProportionalSplitterMorph gripThickness]).
	
	"Now create the children."
	panes := OrderedCollection new.
	aSpec children isSymbol
		ifTrue: [
			widget getChildrenSelector: aSpec children.
			widget update: aSpec children]
		ifFalse: [
			self buildAll: aSpec children in: widget].
	widget setUpdatablePanesFrom: panes.
	
	aSpec label ifNotNil: [:label|
		label isSymbol 
			ifTrue:[widget getLabelSelector: label]
			ifFalse:[widget setLabel: label]].

	aSpec multiWindowStyle notNil ifTrue:
		[widget savedMultiWindowState: (SavedMultiWindowState on: aSpec model)].

	widget closeWindowSelector: aSpec closeAction.
	self buildHelpFor: widget spec: aSpec. 

	widget bounds: (RealEstateAgent 
		initialFrameFor: widget 
		initialExtent: (aSpec extent ifNil:[widget initialExtent])
		world: self currentWorld).

	^ widget!
]style[(21 1 5 2 1 1 6 1 1 3 5 1 6 1 2 1 13 1 8 4 83 3 5 1 6 1 17 8 6 1 2 2 4 1 15 1 5 2 3 3 4 1 9 1 6 1 3 1 5 1 4 5 6 1 6 1 5 1 5 4 40 2 6 1 19 2 5 1 18 1 6 1 1 4 1 4 4 1 18 1 6 1 5 1 5 3 6 1 12 2 5 1 7 1 6 1 1 26 13 1 4 6 1 8 2 5 1 7 1 6 1 1 26 13 1 6 26 8 2 19 3 3 5 1 8 1 8 3 7 6 6 1 20 1 5 1 8 5 6 1 7 1 5 1 8 4 8 6 4 1 9 1 5 1 8 1 3 1 6 4 6 1 22 11 5 1 5 1 9 3 5 1 3 5 1 8 5 7 1 6 1 17 1 5 1 4 8 1 6 1 9 1 5 1 5 5 1 16 1 6 1 7 4 6 1 22 1 1 22 3 1 5 1 5 1 5 6 1 20 1 5 1 11 3 4 1 13 1 6 1 5 1 5 5 6 1 7 21 16 1 6 4 14 1 1 5 1 6 1 6 1 6 1 13 1 1 3 6 1 4 1 12 5 1 1 6)b,cblack;,c000000126,cblack;,cgray;,cblack;,c106106106,cblack;,cgray;,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000126n,cblack;,c106106106,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c126000000,c000126000,cblack;,c126000000,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,cblack;,c000000126,c000126000,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,cblack;,c000000126,c000126000,cblack;,c000126126,cblack;,b,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cgray;,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,c000126000,c106106106,cblack;,c000000126,cblack;,c000000126,c000126000,cblack;,c000000126,c000126000,c106106106,cblack;,c000000126,cblack;,c000000126,c000126000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000126000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,c000126000,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000126000,c000000126,cblack;,c000000126,cblack;,c000000126,c126000126,c106106106,cblack;,c000000126,c126000126,c000126000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c106106106! !


!NewColorPickerMorph methodsFor: 'initialize-release' stamp: 'mt 8/21/2019 11:26'!
newBottomRow
	^ Morph new
		 color: Color transparent ;
		 changeTableLayout ;
		 listDirection: #leftToRight ;
		 hResizing: #spaceFill; vResizing: #shrinkWrap ;
		 height: 20 ;
		 cellGap: 4 ;
		 addMorph: (StringMorph contents: 'Current selection:' translated) ;
		 addMorphBack: self newColorPresenterMorph ;
		 addMorphBack: self newCloseButton!
]style[(12 2 1 7 3 4 6 7 11 6 17 6 14 1 12 6 10 1 10 2 10 1 11 6 7 1 2 6 8 1 1 6 9 14 9 1 20 1 10 7 13 1 4 1 22 6 13 1 4 1 14)b,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126n,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126! !

!NewColorPickerMorph methodsFor: 'initialize-release' stamp: 'mt 8/21/2019 11:26'!
setup
	self
		 color: (Color white darker) ;
		 cornerStyle: #rounded ;
		 changeTableLayout ;
		 hResizing: #shrinkWrap ;
		 vResizing: #shrinkWrap ;
		 extent: 240@240 ;
		 addMorphBack: hsvaMorph ;
		 addMorphBack: self newColorExpressionMorph ;
		 addMorphBack: self newBottomRow ;
		 layoutInset: 4 ;
		 cellGap: 2.
		
		Preferences menuAppearance3d
		ifTrue: [self addDropShadow].
	!
]style[(5 2 4 4 6 8 5 1 6 7 12 1 8 6 17 6 10 1 11 6 10 1 11 6 7 1 3 1 3 6 13 16 13 1 4 1 23 6 13 1 4 1 12 6 12 1 1 6 8 1 1 19 16 3 7 2 4 1 13 4)b,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,c000000126,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;! !

!NewColorPickerMorph methodsFor: 'initialize-release' stamp: 'mt 8/21/2019 11:26'!
setupForProperties
	self
		 color: (Color white darker) ;
		 changeTableLayout ;
		 hResizing: #shrinkWrap ;
		 vResizing: #shrinkWrap ;
		 extent: 240@240 ;
		 addMorphBack: hsvaMorph ;
		 layoutInset: 4 ;
		 cellGap: 2.!
]style[(18 2 4 4 6 8 5 1 6 7 17 6 10 1 11 6 10 1 11 6 7 1 3 1 3 6 13 16 12 1 1 6 8 1 1 1)b,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,c000000126,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;! !


!ObjectsTool methodsFor: 'tabs' stamp: 'mt 8/21/2019 11:19'!
paneForTabs: tabList 
	"Answer a pane bearing tabs for the given list"
	| aPane |
	tabList do: [:t |
			t color: Color transparent.
			t borderWidth: 1;
				borderColor: Color black].

	aPane := Morph new
				changeTableLayout;
				color: self baseBackgroundColor;
				listDirection: #leftToRight;
				wrapDirection: #topToBottom;
				vResizing: #spaceFill;
				hResizing: #spaceFill;
				cellGap: 6;
				layoutInset: 4;
				listCentering: #center;
				listSpacing: #equal;
				addAllMorphs: tabList;
				yourself.

	aPane width: self layoutBounds width.

	^ aPane!
]style[(12 1 7 3 47 2 1 1 5 1 1 2 7 1 3 3 1 1 1 4 1 1 6 7 11 5 1 1 12 1 1 6 12 7 5 5 5 1 2 7 3 5 17 6 6 1 4 1 19 6 14 1 12 6 14 1 12 6 10 1 10 6 10 1 10 6 8 1 1 6 12 1 1 6 14 1 7 6 12 1 6 6 13 1 7 6 8 4 5 1 6 1 4 1 12 1 5 4 1 1 5)b,cblack;,c000000126,cblack;,c000126126,cblack;,cgray;,cblack;,c106106106,cblack;,cgray;,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,cgray;,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,b,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c106106106! !


!PBPreferenceButtonMorph methodsFor: 'extra controls' stamp: 'mt 8/21/2019 11:21'!
addExtraControls
	| m |
	m := self horizontalPanel
		cellGap: 3;
		addAllMorphs: self actionButtons;
		addMorphBack: self horizontalFiller;
		addMorphBack: self moreButton;
		yourself.
	self 
		addMorphBack: (self blankSpaceOf: 2@2);
		addMorphBack: self preferenceHelpTextMorph;
		addMorphBack: self horizontalLine;
		addMorphBack: self preferenceCodeTextMorph;
		fullBounds; "to force a layout compute needed by the textMorphs's autoFit"
		addMorphBack: m
!
]style[(16 2 1 1 1 1 1 2 1 1 2 1 4 1 15 3 8 1 1 4 13 1 4 1 13 4 13 1 4 1 16 4 13 1 4 1 10 4 8 3 4 4 13 2 4 1 13 1 1 1 1 5 13 1 4 1 23 4 13 1 4 1 14 4 13 1 4 1 23 4 10 2 62 3 13 1 1 1)b,cblack;,cgray;,cblack;,c106106106,cblack;,cgray;,cblack;,c106106106,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,c000000126,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000126126,cblack;,c000000126,cblack;,c106106106,cblack;! !

!PBPreferenceButtonMorph methodsFor: 'initialization' stamp: 'mt 8/21/2019 11:21'!
initializeLayout
	self layoutPolicy: TableLayout new;
		beTransparent;
		layoutInset: 0;
		cellGap: 0;
		listCentering: #topLeft;
		cellPositioning: #topLeft;
		listDirection: #topToBottom;
		hResizing: #spaceFill;
		vResizing: #shrinkWrap.		!
]style[(16 2 4 1 13 13 3 4 13 4 12 1 1 4 8 1 1 4 14 1 8 4 16 1 8 4 14 1 12 4 10 1 10 4 10 1 11 3)b,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;! !

!PBPreferenceButtonMorph methodsFor: 'utility methods' stamp: 'mt 8/21/2019 11:21'!
basicPanel
	^BorderedMorph new
		beTransparent;
		extent: 0@0;
		borderWidth: 0;
		layoutInset: 0;
		cellGap: 0;
		layoutPolicy: TableLayout new;
		listCentering: #topLeft;
		cellPositioning: #center;
		hResizing: #spaceFill;
		vResizing: #shrinkWrap;
		yourself!
]style[(10 2 1 14 3 3 13 4 7 1 1 1 1 4 12 1 1 4 12 1 1 4 8 1 1 4 13 13 3 4 14 1 8 4 16 1 7 4 10 1 10 4 10 1 11 4 8)b,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,c000000126,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126! !


!PBPreferenceView methodsFor: 'user interface' stamp: 'mt 8/21/2019 11:21'!
basicPanel
	^BorderedMorph new
		beTransparent;
		extent: 0@0;
		borderWidth: 0;
		layoutInset: 0;
		cellGap: 5;
		layoutPolicy: TableLayout new;
		listCentering: #topLeft;
		cellPositioning: #center;
		hResizing: #shrinkWrap;
		vResizing: #shrinkWrap;
		yourself!
]style[(10 2 1 14 3 3 13 4 7 1 1 1 1 4 12 1 1 4 12 1 1 4 8 1 1 4 13 13 3 4 14 1 8 4 16 1 7 4 10 1 11 4 10 1 11 4 8)b,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,c000000126,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126! !


!PBBooleanPreferenceView methodsFor: 'user interface' stamp: 'mt 8/21/2019 11:21'!
representativeButtonWithColor: aColor inPanel: aPreferencesPanel
	^self horizontalPanel
		layoutInset: 2;
		cellGap: 7;
		color: aColor;
		addMorphBack: self morphForName;
		addMorphBack: self horizontalFiller; 
		addMorphBack: self enabledButton;
		addMorphBack: self localToProjectButton;
		yourself.!
]style[(30 1 6 1 8 1 17 2 5 1 15 3 12 1 1 4 8 1 1 4 6 1 6 4 13 1 4 1 12 4 13 1 4 1 16 5 13 1 4 1 13 4 13 1 4 1 20 4 8 1)b,cblack;,c000000126,cblack;,b,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;! !


!PBColorPreferenceView methodsFor: 'user interface' stamp: 'mt 8/21/2019 11:21'!
representativeButtonWithColor: aColor inPanel: aPreferenceBrowser
	^self horizontalPanel
		layoutInset: 2;
		color: aColor;
		cellGap: 20;
		cellPositioning: #center;
		addMorphBack: self morphForName;
		addMorphBack: self horizontalFiller;
		addMorphBack: self colorMenuButton;
		yourself!
]style[(30 1 6 1 8 1 18 2 5 1 15 3 12 1 1 4 6 1 6 4 8 1 2 4 16 1 7 4 13 1 4 1 12 4 13 1 4 1 16 4 13 1 4 1 15 4 8)b,cblack;,c000000126,cblack;,b,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126! !


!PBNumericPreferenceView methodsFor: 'user interface' stamp: 'mt 8/21/2019 11:21'!
representativeButtonWithColor: aColor inPanel: aPreferenceBrowser
	^self horizontalPanel
		layoutInset: 2;
		color: aColor;
		cellGap: 20;
		cellPositioning: #center;
		addMorphBack: self morphForName;
		addMorphBack: self horizontalFiller;
		addMorphBack: self textField;
		yourself.!
]style[(30 1 6 1 8 1 18 2 5 1 15 3 12 1 1 4 6 1 6 4 8 1 2 4 16 1 7 4 13 1 4 1 12 4 13 1 4 1 16 4 13 1 4 1 9 4 8 1)b,cblack;,c000000126,cblack;,b,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;! !


!PBTextPreferenceView methodsFor: 'user interface' stamp: 'mt 8/21/2019 11:21'!
representativeButtonWithColor: aColor inPanel: aPreferenceBrowser
	^self horizontalPanel
		layoutInset: 2;
		color: aColor;
		cellGap: 20;
		cellPositioning: #center;
		addMorphBack: self morphForName;
		addMorphBack: self textField;
		yourself.!
]style[(30 1 6 1 8 1 18 2 5 1 15 3 12 1 1 4 6 1 6 4 8 1 2 4 16 1 7 4 13 1 4 1 12 4 13 1 4 1 9 4 8 1)b,cblack;,c000000126,cblack;,b,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;! !


!PasteUpMorph methodsFor: 'options' stamp: 'mt 8/21/2019 13:27'!
autoLineLayout: aBoolean
	"Make the receiver be viewed with auto-line-layout, which means that its submorphs will be laid out left-to-right and then top-to-bottom in the manner of a word processor, or (if aBoolean is false,) cease applying auto-line-layout"

	aBoolean ifTrue:
		[self viewingNormally ifTrue: [self saveBoundsOfSubmorphs]].
	aBoolean ifTrue:[
		self layoutPolicy: TableLayout new.
		self layoutInset: 8; cellGap: 4.
		self listDirection: #leftToRight; wrapDirection: #topToBottom.
	] ifFalse:[
		self layoutPolicy: nil.
		self layoutInset: 0; cellGap: 0.
	].
!
]style[(15 1 8 2 231 3 8 1 7 4 4 1 15 1 7 1 1 4 1 21 1 4 8 1 7 4 4 1 13 13 3 4 4 1 12 1 1 2 8 1 1 4 4 1 14 1 12 2 14 1 12 5 8 4 4 1 13 1 3 4 4 1 12 1 1 2 8 1 1 6)b,cblack;,c000000126,cblack;,c000126126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c126000000,cblack;,c000000126,c000126000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;! !


!PluggableCheckBoxMorph methodsFor: 'installing' stamp: 'mt 8/21/2019 13:46'!
basicPanel
	^BorderedMorph new
		beTransparent;
		extent: 0@0;
		borderWidth: 0;
		layoutInset: 0;
		cellGap: 0;
		layoutPolicy: TableLayout new;
		listCentering: #topLeft;
		cellPositioning: #center;
		hResizing: #spaceFill;
		vResizing: #shrinkWrap;
		yourself!
]style[(10 2 1 14 3 3 13 4 7 1 1 1 1 4 12 1 1 4 12 1 1 4 8 1 1 4 13 13 3 4 14 1 8 4 16 1 7 4 10 1 10 4 10 1 11 4 8)b,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,c000000126,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126! !


!PluggableDropDownListMorph methodsFor: 'drawing' stamp: 'mt 8/21/2019 13:46'!
basicPanel
	^BorderedMorph new
		beTransparent;
		extent: 0@0;
		borderWidth: 0;
		layoutInset: 0;
		cellGap: 0;
		layoutPolicy: TableLayout new;
		listCentering: #topLeft;
		cellPositioning: #center;
		hResizing: #spaceFill;
		vResizing: #shrinkWrap;
		yourself!
]style[(10 2 1 14 3 3 13 4 7 1 1 1 1 4 12 1 1 4 12 1 1 4 8 1 1 4 13 13 3 4 14 1 8 4 16 1 7 4 10 1 10 4 10 1 11 4 8)b,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,c000000126,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126! !


!PreferenceWizardMorph methodsFor: 'initialization' stamp: 'mt 8/21/2019 13:46'!
createCheckbox: label for: selector help: terms

	| box lbl btn |
	
	btn := self createButton
		layoutInset: 0;
		label: ' ';
		onColor: (self defaultColor adjustBrightness: 0.3) offColor: (self defaultColor adjustBrightness: 0.3);
		vResizing: #rigid;
		hResizing: #rigid;
		action: ('toggle', selector) asSymbol;
		getStateSelector: ('state', selector) asSymbol;
		getLabelSelector: ('label', selector) asSymbol;
		extent: 25@25.

	lbl := self createLabel: label color: self defaultTextColor.
	
	box := Morph new
		color: Color transparent;
		changeTableLayout;
		listDirection: #leftToRight;
		cellPositioning: #topLeft;
		hResizing: #spaceFill;
		vResizing: #shrinkWrap;
		cellGap: 10;
		yourself.
		
	box addAllMorphs: {btn. lbl}.
	self
		setBalloonText: (terms isString ifTrue: [terms] ifFalse: [self findHelpStringFor: terms])
		for: box.
	^ box!
]style[(15 1 5 1 4 1 8 1 5 1 5 3 1 1 3 1 3 1 3 1 1 4 3 1 2 1 4 1 12 3 12 1 1 4 6 1 3 4 8 2 4 1 12 1 17 1 3 2 9 2 4 1 12 1 17 1 3 5 10 1 6 4 10 1 6 4 7 2 8 1 1 8 2 8 4 17 2 7 1 1 8 2 8 4 17 2 7 1 1 8 2 8 4 7 1 2 1 2 4 3 1 2 1 4 1 12 1 5 1 6 1 4 1 16 5 3 1 2 7 3 3 6 7 11 4 17 4 14 1 12 4 16 1 8 4 10 1 10 4 10 1 11 4 8 1 2 4 8 6 3 1 13 2 3 2 3 4 4 3 15 2 5 1 8 1 7 1 1 5 1 1 8 1 1 4 1 18 1 5 1 4 4 1 3 3 1 1 3)b,cblack;,c000000126,cblack;,b,cblack;,c000000126,cblack;,b,cblack;,c000000126,cblack;,cgray;,cblack;,c106106106,cblack;,c106106106,cblack;,c106106106,cblack;,cgray;,cblack;,c106106106,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000126n,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126n,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126n,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126n,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,c000000126,c126000000,cblack;,c106106106,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c106106106,cblack;,b,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c106106106,cblack;,c106106106,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c000000126,c000126000,cblack;,c000000126,cblack;,c000126000,c126000000,cblack;,c000000126,cblack;,c000000126,c000126000,cblack;,c000000126,cblack;,c106106106,cblack;,c126000000,cblack;,c106106106! !

!PreferenceWizardMorph methodsFor: 'initialization' stamp: 'mt 8/21/2019 13:46'!
createPage

	^ Morph new
		color: Color transparent;
		hResizing: #spaceFill;
		vResizing: #spaceFill;
		changeTableLayout;
		listDirection: #topToBottom;
		cellPositioning: #topLeft;
		layoutInset: 20;
		cellGap: 10;
		yourself!
]style[(10 3 1 7 3 3 6 7 11 4 10 1 10 4 10 1 10 4 17 4 14 1 12 4 16 1 8 4 12 1 2 4 8 1 2 4 8)b,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126! !

!PreferenceWizardMorph methodsFor: 'initialization' stamp: 'mt 8/21/2019 13:46'!
initialize

	super initialize.
	
	isFullScreen := false.

	self hasLowPerformance
		ifTrue: [self color: self defaultColor]
		ifFalse: [self color: (self defaultColor alpha: 0.75)].
		
	self setProperty: #indicateKeyboardFocus toValue: #never.
	
	Preferences enable: #systemWindowEmbedOK.
	
	titleMorph := ('Welcome to Squeak' translated asText
		addAttribute: (TextColor color: self defaultTextColor);
		addAttribute: (TextFontReference toFont: (StrikeFont familyName: 'Darkmap DejaVu Sans' pointSize: 20));
		yourself) asMorph lock.
	titleMorph margins: (10@0 corner: 10@10).
	titleMorph layoutFrame: (LayoutFrame fractions: (0 @ 0 corner: 1 @ 0) offsets: (0@ 0 corner: 0 @ titleMorph height)).
	
	self
		initializePages;
		initializeButtons;
		initializeControlMorph;
		initializePreviewWorld;
		initializeForLowPerformance.

	self
		changeProportionalLayout;
		layoutInset: 20;
		cellGap: 10;
		cellPositioning: #center;
		addAllMorphs: {titleMorph. buttonRowMorph. controlMorph. previewWorld. startButton. skipButton. lowPerformanceMorph}.
		
	self addKeyboardCaptureFilter: self.!
]style[(10 3 5 1 10 18 2 1 5 4 4 1 17 3 7 2 4 1 6 1 4 1 12 4 8 2 4 1 6 1 1 4 1 12 1 6 1 4 1 7 4 1 12 1 22 1 8 1 6 17 7 1 20 16 2 2 19 1 10 1 6 3 13 1 1 10 6 1 4 1 16 1 4 13 1 1 18 7 1 1 11 11 1 21 1 10 1 2 1 1 4 8 2 7 1 4 14 8 2 2 1 1 1 7 1 2 1 2 15 12 14 10 1 1 1 1 1 1 1 1 7 1 1 1 1 1 1 1 1 8 1 1 1 1 1 1 1 7 1 1 1 1 12 6 1 6 4 3 15 4 17 4 22 4 22 4 27 4 4 3 24 4 12 1 2 4 8 1 2 4 16 1 7 4 13 109 4 1 25 1 4 1)b,cblack;,c126000000,cblack;,c000000126,cblack;,b,cblack;,c126000000,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000126000,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,c000126000,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,b,cblack;,c126000126n,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,c000126000,cblack;,c000000126,cblack;,c000126000,cblack;,c000000126,cblack;,c126000126,cblack;,c000000126,cblack;,c126000126n,cblack;,c000000126,cblack;,c126000000,c126000126,c000126000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,c000000126,c126000000,cblack;,c000000126,cblack;,c126000000,c000000126,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,c000126000,cblack;,c000000126,cblack;,c000126000,c126000000,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,c000126000,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;! !

!PreferenceWizardMorph methodsFor: 'initialization' stamp: 'mt 8/21/2019 13:47'!
initializeButtons

	buttonRowMorph := Morph new
		color: Color transparent;
		changeTableLayout;
		listDirection: #leftToRight;
		cellGap: 10;
		layoutInset: (0@20 corner: 0@0);
		vResizing: #shrinkWrap;
		hResizing: #spaceFill;
		yourself.
		
	buttonRowMorph addAllMorphs: {
		previousButton := self createButton action: #previous; label: 'Previous' translated.
		pagesLabel := (self createLabel: '0 / 0') hResizing: #shrinkWrap; margins: (20@0 corner: 20@0); fullBounds; yourself.
		nextButton := self createButton action: #next; label: 'Next' translated.
		self createHorizontalSpacer.
		self createButton action: #showSqueak; label: 'Done' translated}.
	
	
	buttonRowMorph fullBounds.
	buttonRowMorph layoutFrame: (LayoutFrame fractions: (0 @ 1 corner: 1 @ 1) offsets: (0@ buttonRowMorph height negated corner: 0 @ 0)).
	
	
	
	startButton := (self createButton action: #showPlayfield; label: 'Configure' translated).
	skipButton := (self createButton action: #showSqueak; label: 'Skip' translated).
	
	(startButton width max: skipButton width) in: [:w |
		startButton hResizing: #rigid; width: w.
		skipButton hResizing: #rigid; width: w.
		
		startButton layoutFrame: (LayoutFrame fractions: (0.5 @ 0.6 corner: 0.5 @ 0.6) offsets: (2*w negated @ 0 corner: 0 @ 0)).
		skipButton layoutFrame: (LayoutFrame fractions: (0.5 @ 0.6 corner: 0.5 @ 0.6) offsets: (0@ 0 corner: 2*w @ 0))].!
]style[(17 18 2 7 3 3 6 7 11 4 17 4 14 1 12 4 8 1 2 4 12 2 1 1 2 1 7 1 1 1 1 5 10 1 11 4 10 1 10 4 8 21 13 20 2 1 4 1 12 1 7 1 9 2 6 1 10 1 10 15 2 2 4 1 12 1 7 2 10 1 11 2 8 2 2 1 1 1 7 1 2 1 1 3 10 2 8 15 2 1 4 1 12 1 7 1 5 2 6 1 6 1 10 4 4 1 22 4 4 1 12 1 7 1 11 2 6 1 6 1 10 23 10 18 12 14 10 1 1 1 1 1 1 1 1 7 1 1 1 1 1 1 1 1 8 1 1 1 1 16 6 1 7 1 7 1 1 1 1 1 1 1 22 2 2 4 1 12 1 7 1 14 2 6 1 11 1 10 15 2 2 4 1 12 1 7 1 11 2 6 1 6 1 10 19 5 1 4 12 5 2 3 3 1 1 1 15 10 1 6 2 6 1 1 15 10 1 6 2 6 1 1 19 12 1 1 12 10 1 1 3 1 1 1 3 1 7 1 3 1 1 1 3 1 1 8 1 1 1 2 1 7 1 1 1 1 1 7 1 1 1 1 1 1 1 1 15 12 1 1 12 10 1 1 3 1 1 1 3 1 7 1 3 1 1 1 3 1 1 8 1 1 1 1 1 1 1 7 1 1 2 1 1 1 1 1 1 2)b,cblack;,b,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,c000000126,c126000000,cblack;,c000000126,cblack;,c126000000,c000000126,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126n,cblack;,c000000126,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c126000126n,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,c000000126,c126000000,cblack;,c000000126,cblack;,c126000000,c000000126,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126n,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126n,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,c000126000,cblack;,c000000126,cblack;,c000126000,c126000000,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,c000126000,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126n,cblack;,c000000126,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126n,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,cgray;,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,cblack;,c000000126,cblack;,c126000126,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,c126000126,cblack;,c000000126,cblack;,c126000126,c126000000,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,c126000126,c000126000,cblack;,c000000126,cblack;,c000126000,cblack;,c000000126,cblack;,c126000126,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,c126000126,cblack;,c000000126,cblack;,c126000126,c126000000,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,c000000126,cblack;,c000000126,cblack;,c126000000,c126000126,c000126000,cblack;! !


!ScrollBar methodsFor: 'initialize' stamp: 'mt 8/12/2019 17:16'!
initializeDownButton
	"initialize the receiver's downButton"

	downButton := RectangleMorph newBounds: self boundsForDownButton.
	downButton 
		on: #mouseDown
		send: #scrollDownInit
		to: self.
	downButton 
		on: #mouseUp
		send: #finishedScrolling
		to: self.
	self updateDownButtonImage.	
	self addMorphFront: downButton.
	downButton
		visible: self class scrollBarsWithoutArrowButtons not;
		disableLayout: downButton visible not.!
]style[(20 2 38 14 2 16 10 1 4 1 19 17 3 1 10 3 5 1 15 3 3 1 4 17 3 1 8 3 5 1 18 3 3 1 4 3 4 1 21 4 4 1 14 27 8 1 4 1 5 1 29 1 3 4 14 12 7 1 3 1)b,cblack;,c000126126,cblack;,b,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;! !

!ScrollBar methodsFor: 'initialize' stamp: 'mt 8/12/2019 17:16'!
initializeMenuButton
"initialize the receiver's menuButton"
	"Preferences disable: #scrollBarsWithoutMenuButton"
	"Preferences enable: #scrollBarsWithoutMenuButton"
	menuButton := RectangleMorph newBounds: self boundsForMenuButton.
	menuButton
		on: #mouseEnter
		send: #menuButtonMouseEnter:
		to: self.
	menuButton
		on: #mouseDown
		send: #menuButtonMouseDown:
		to: self.
	menuButton
		on: #mouseLeave
		send: #menuButtonMouseLeave:
		to: self.
	"menuButton 
	addMorphCentered: (RectangleMorph 
	newBounds: (0 @ 0 extent: 4 @ 2) 
	color: Color black)."
	self updateMenuButtonImage.
	self addMorphFront: menuButton.
	menuButton
		visible: (self class scrollBarsWithoutMenuButton or: [self orientation == #horizontal]) not;
		disableLayout: menuButton visible not.!
]style[(20 1 38 2 51 2 50 13 2 16 10 1 4 1 19 16 3 1 11 3 5 1 22 3 3 1 4 16 3 1 10 3 5 1 21 3 3 1 4 16 3 1 11 3 5 1 22 3 3 1 4 3 106 2 4 1 21 3 4 1 14 27 8 2 4 1 5 1 27 1 3 1 1 4 1 11 1 2 1 11 1 2 3 4 14 12 7 1 3 1)b,cblack;,c000126126,cblack;,c000126126,cblack;,c000126126,cblack;,b,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000126126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,c000126000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;! !

!ScrollBar methodsFor: 'initialize' stamp: 'mt 8/12/2019 17:16'!
initializeUpButton
"initialize the receiver's upButton"
	upButton := RectangleMorph newBounds: self boundsForUpButton.
	upButton
		on: #mouseDown
		send: #scrollUpInit
		to: self.
	upButton
		on: #mouseUp
		send: #finishedScrolling
		to: self.
	self updateUpButtonImage.
	self addMorph: upButton.	
	upButton
		visible: self class scrollBarsWithoutArrowButtons not;
		disableLayout: upButton visible not.!
]style[(18 1 36 11 2 16 10 1 4 1 17 14 3 1 10 3 5 1 13 3 3 1 4 14 3 1 8 3 5 1 18 3 3 1 4 3 4 1 19 3 4 1 9 24 8 1 4 1 5 1 29 1 3 4 14 10 7 1 3 1)b,cblack;,c000126126,cblack;,b,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;! !

!ScrollBar methodsFor: 'updating' stamp: 'mt 8/12/2019 17:16'!
updateSlider

	| imagesNeedUpdate |
	imagesNeedUpdate := upButton width ~= (self orientation == #horizontal ifTrue: [self height] ifFalse: [self width]).
	
	self menuButton
		visible: (self orientation == #horizontal or: [self class scrollBarsWithoutMenuButton]) not;
		disableLayout: self menuButton visible not;
		bounds: self boundsForMenuButton.
	self upButton
		visible: self class scrollBarsWithoutArrowButtons not;
		disableLayout: self upButton visible not;
		bounds: self boundsForUpButton.
	self downButton
		visible: self class scrollBarsWithoutArrowButtons not;
		disableLayout: self downButton visible not;
		bounds: self boundsForDownButton.

	super updateSlider.

	pagingArea bounds: self totalSliderArea.
	self expandSlider.

	imagesNeedUpdate ifTrue: [
		self menuButton visible ifTrue: [self updateMenuButtonImage].
		self upButton visible ifTrue: [self updateUpButtonImage].
		self downButton visible ifTrue: [self updateDownButtonImage]].!
]style[(12 3 1 1 16 1 1 2 16 1 2 10 5 1 2 2 4 1 11 1 2 1 11 1 7 1 1 4 1 6 1 1 8 1 1 4 1 5 1 6 4 1 10 3 8 2 4 1 11 1 2 1 11 1 3 1 1 4 1 5 1 27 1 2 3 4 14 1 4 1 10 1 7 1 3 4 7 1 4 1 19 3 4 1 8 3 8 1 4 1 5 1 29 1 3 4 14 1 4 1 8 1 7 1 3 4 7 1 4 1 17 3 4 1 10 3 8 1 4 1 5 1 29 1 3 4 14 1 4 1 10 1 7 1 3 4 7 1 4 1 19 4 5 1 12 15 7 1 4 1 15 3 4 1 12 4 16 1 7 5 4 1 10 1 7 1 7 1 1 4 1 21 1 4 4 1 8 1 7 1 7 1 1 4 1 19 1 4 4 1 10 1 7 1 7 1 1 4 1 21 1 2)b,cblack;,cgray;,cblack;,c106106106,cblack;,cgray;,cblack;,c106106106,cblack;,b,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c126000000,cblack;,c000000126,c000126000,cblack;,c000000126,cblack;,c000126000,c126000000,cblack;,c000000126,c000126000,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c126000000,cblack;,c000000126,cblack;,c000000126,c000126000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c126000000,cblack;,c000000126,c000126000,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c126000000,cblack;,c000000126,c000126000,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c126000000,cblack;,c000000126,c000126000,cblack;! !


!ScrollBar class methodsFor: 'images - samples' stamp: 'mt 8/21/2019 13:36'!
arrowSamples
	"create a set of arrow with different sizes, colors and directions"
	" 
	ScrollBar arrowSamples.  
	"
	| column |
	column := AlignmentMorph newColumn vResizing: #shrinkWrap;
				 hResizing: #shrinkWrap;
				 layoutInset: 1;
				 borderColor: Color black;
				 borderWidth: 0;
				 wrapCentering: #center;
				 cellPositioning: #center;
				 color: Color white;
				 yourself.
	
	self sampleSizes
		do: [:size | 
			| row | 
			row := AlignmentMorph newRow color: Color transparent;
						 vResizing: #shrinkWrap;
						 cellGap: 2 @ 0;
						 yourself.
			
			self sampleColors
				do: [:color | 
					#(#top #right #bottom #left )
						do: [:direction | 
							row addMorphBack: (ScrollBar
									arrowOfDirection: direction
									size: size
									color: color) asMorph]].
			
			column addMorphBack: row].
	
	column openInHand!
]style[(12 2 67 2 32 2 1 1 6 1 1 2 6 1 2 16 9 1 10 1 11 7 10 1 11 7 12 1 1 7 12 7 5 7 12 1 1 7 14 1 7 7 16 1 7 7 6 7 5 7 8 5 4 1 11 3 3 3 4 1 1 5 1 1 3 1 1 5 3 1 2 16 6 1 6 7 11 9 10 1 11 9 8 1 1 1 1 1 1 9 8 9 4 1 12 5 3 1 1 1 5 1 1 7 1 1 4 1 6 1 7 1 5 9 3 1 1 1 9 1 1 9 3 1 13 1 1 19 17 1 9 10 5 1 4 10 6 1 5 1 1 7 1 1 9 6 1 13 1 3 6 6 1 10)bu,cblack;,c000126126,cblack;,c000126126,cblack;,cgray;,cblack;,c106106106,cblack;,cgray;,cblack;,c106106106,cblack;,b,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,cgray;,cblack;,cgray;,cblack;,cgray;,cblack;,cgray;,cblack;,cgray;,cblack;,b,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,cblack;,c000000126,cblack;,cgray;,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126,cblack;,c000000126,cblack;,cgray;,cblack;,cgray;,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,c126000000,cblack;,c000000126,c126000126,c000126000,cblack;,c106106106,cblack;,c000000126,cblack;,cgray;,cblack;,c106106106,cblack;,c000000126! !

!ScrollBar class methodsFor: 'images - samples' stamp: 'mt 8/21/2019 13:41'!
boxSamples
	"create a set of box with different sizes and colors"
	" 
	ScrollBar boxSamples.  
	"
	| column |
	column := AlignmentMorph newColumn vResizing: #shrinkWrap;
				 hResizing: #shrinkWrap;
				 layoutInset: 1;
				 borderColor: Color black;
				 borderWidth: 0;
				 wrapCentering: #center;
				 cellPositioning: #center;
				 color: Color white;
				 yourself.
	""
	self sampleSizes
		do: [:size | 
			| row | 
			row := AlignmentMorph newRow color: Color transparent;
						 vResizing: #shrinkWrap;
						 cellGap: 2 @ 0;
						 yourself.
			""
			self sampleColors
				do: [:color | 
					row addMorphBack: (ScrollBar boxOfSize: size color: color) asMorph].
			""
			column addMorphBack: row].
	""
	""
	column openInHand!
]style[(10 2 53 2 30 2 1 1 6 1 1 2 6 1 2 16 9 1 10 1 11 7 10 1 11 7 12 1 1 7 12 7 5 7 12 1 1 7 14 1 7 7 16 1 7 7 6 7 5 7 8 3 2 2 4 1 11 3 3 3 4 1 1 5 1 1 3 1 1 5 3 1 2 16 6 1 6 7 11 9 10 1 11 9 8 1 1 1 1 1 1 9 8 5 2 4 4 1 12 5 3 1 1 1 5 1 1 7 3 1 13 1 1 10 10 1 4 1 6 1 5 1 1 7 1 5 2 4 6 1 13 1 3 4 2 2 2 2 6 1 10)bu,cblack;,c000126126,cblack;,c000126126,cblack;,cgray;,cblack;,c106106106,cblack;,cgray;,cblack;,c106106106,cblack;,b,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,cgray;,cblack;,cgray;,cblack;,cgray;,cblack;,cgray;,cblack;,cgray;,cblack;,b,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000126126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,cblack;,c000000126,cblack;,cgray;,cblack;,cgray;,cblack;,c000000126,cblack;,c126000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,c126000126,cblack;,c000000126,c000126000,cblack;,c000126126,cblack;,c106106106,cblack;,c000000126,cblack;,cgray;,cblack;,c000126126,cblack;,c000126126,cblack;,c106106106,cblack;,c000000126! !


!ScrollPane methodsFor: 'accessing' stamp: 'mt 8/9/2019 11:52'!
scrollBarOnLeft: aBoolean

	scrollBarOnLeft := aBoolean.
	self layoutChanged.!
]style[(16 1 8 19 2 1 8 3 4 1 13 1)b,cblack;,c000000126,cblack;,b,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;! !

!ScrollPane methodsFor: 'accessing' stamp: 'mt 8/9/2019 11:52'!
scrollBarThickness: anInteger
	
	scrollBarThickness := anInteger.
	
	self updateMinimumExtent.
	self layoutChanged.!
]style[(19 1 9 23 2 1 9 5 4 1 19 3 4 1 13 1)b,cblack;,c000000126,cblack;,b,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;! !

!ScrollPane methodsFor: 'geometry' stamp: 'mt 8/9/2019 13:28'!
resetExtent
	"Reset the extent. (may be overridden by subclasses which need to do more than this)"
	
	self flag: #deprecate. "mt: Remove all uses in Etoys."
	self resizeScroller!
]style[(11 2 85 4 4 1 5 1 10 2 31 2 4 1 14)b,cblack;,c000126126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000126126,cblack;,c126000000,cblack;,c000000126! !

!ScrollPane methodsFor: 'geometry' stamp: 'mt 8/12/2019 17:21'!
setScrollDeltas
	"Set the ScrollBar deltas, value and interval, based on the current scroll pane size, offset and range."

	scroller ifNil: [^ self].
	
	self hideOrShowScrollBars.
	self vSetScrollDelta.
	self hSetScrollDelta.!
]style[(15 2 104 12 6 2 1 1 4 6 4 1 20 3 4 1 15 3 4 1 15 1)b,cblack;,c000126126,cblack;,c000000126,cblack;,c126000000,cblack;,c126000000,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;! !

!ScrollPane methodsFor: 'initialization' stamp: 'mt 8/10/2019 12:19'!
initialize
	
	"initialize the state of the receiver"
	super initialize.
	""
	self initializePreferences.
	hasFocus := false.
	self initializeScrollBars.
	""
	
	self extent: self defaultExtent.
	self updateMinimumExtent.
	
	self setDefaultParameters.
	self addKeyboardCaptureFilter: self.!
]style[(10 4 38 2 5 1 10 3 2 2 4 1 21 12 2 1 5 3 4 1 20 3 2 4 4 1 7 1 4 1 13 3 4 1 19 5 4 1 20 3 4 1 25 1 4 1)b,cblack;,c000126126,cblack;,c126000000,cblack;,c000000126,cblack;,c000126126,cblack;,c126000000,cblack;,c000000126,cblack;,b,cblack;,c126000000,cblack;,c126000000,cblack;,c000000126,cblack;,c000126126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;! !

!ScrollPane methodsFor: 'scrolling' stamp: 'mt 8/12/2019 14:52'!
adjustOffset
	"Layout specific. If our scroller is large enough, avoid hiding contents due to bad offset."

	| sbox adjustedOffset |
	sbox := scroller submorphBoundsForShrinkWrap.
	adjustedOffset := (sbox width <= scroller width ifTrue: [0] ifFalse: [scroller offset x]) @
		(sbox height <= scroller height ifTrue: [0] ifFalse: [scroller offset y]).
	scroller offset: adjustedOffset.!
]style[(12 2 92 3 1 1 4 1 14 1 1 2 4 1 2 10 27 3 14 1 2 2 4 1 5 1 2 10 5 1 7 1 1 1 1 1 8 1 1 9 6 1 1 1 2 1 4 4 1 6 1 2 10 6 1 7 1 1 1 1 1 8 1 1 9 6 1 1 1 13 7 1 14 1)b,cblack;,c000126126,cblack;,cgray;,cblack;,c106106106,cblack;,c106106106,cblack;,cgray;,cblack;,c106106106,cblack;,b,cblack;,c000000126,cblack;,c106106106,cblack;,b,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c126000000,c000126000,cblack;,c000000126,cblack;,c000126000,cblack;,c000000126,cblack;,c000000126,c000126000,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c126000000,c000126000,cblack;,c000000126,cblack;,c000126000,cblack;,c000000126,cblack;,c000000126,c000126000,cblack;,c000000126,cblack;,c106106106,cblack;! !

!ScrollPane methodsFor: 'scrolling' stamp: 'mt 8/9/2019 12:03'!
hHideScrollBar

	self hIsScrollbarShowing ifFalse: [^self].
	self removeMorph: hScrollBar.!
]style[(14 3 4 1 19 1 8 2 5 4 4 1 12 12)b,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c126000000,cblack;,c000000126,cblack;! !

!ScrollPane methodsFor: 'scrolling' stamp: 'mt 8/9/2019 12:02'!
hideOrShowScrollBars

	self 
		vHideOrShowScrollBar; 
		hHideOrShowScrollBar.!
]style[(20 3 4 4 20 5 20 1)b,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;! !

!ScrollPane methodsFor: 'scrolling' stamp: 'mt 8/9/2019 12:03'!
hShowScrollBar

	self hIsScrollbarShowing ifTrue: [^self].
	self hResizeScrollBar.
	self privateAddMorph: hScrollBar atIndex: 1.
	retractableScrollBar ifTrue: [self comeToFront].!
]style[(14 3 4 1 19 1 7 2 5 4 4 1 16 3 4 1 16 12 8 1 1 24 7 2 4 1 11 2)b,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;! !

!ScrollPane methodsFor: 'scrolling' stamp: 'mt 8/9/2019 15:36'!
scrollToShow: aRectangle

	| newOffset |
	newOffset := self offsetToShow: aRectangle.
	scroller offset = newOffset ifTrue: [^ self].
	scroller offset: newOffset.
	self layoutChanged.!
]style[(13 1 10 3 1 1 9 1 1 2 9 1 2 1 4 1 13 1 10 12 6 1 1 1 9 1 7 2 1 1 4 13 7 1 9 3 4 1 13 1)b,cblack;,c000000126,cblack;,cgray;,cblack;,c106106106,cblack;,cgray;,cblack;,c106106106,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c126000000,cblack;,c126000000,cblack;,c000000126,cblack;,c106106106,cblack;,c126000000,cblack;,c000000126,cblack;! !

!ScrollPane methodsFor: 'scrolling' stamp: 'mt 8/9/2019 11:58'!
vHideScrollBar
	self vIsScrollbarShowing ifFalse: [^self].
	self removeMorph: scrollBar.!
]style[(14 2 4 1 19 1 8 2 5 4 4 1 12 11)b,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c126000000,cblack;,c000000126,cblack;! !

!ScrollPane methodsFor: 'scrolling' stamp: 'mt 8/9/2019 12:02'!
vShowScrollBar

	self vIsScrollbarShowing ifTrue: [^ self].
	self vResizeScrollBar.
	self privateAddMorph: scrollBar atIndex: 1.
	retractableScrollBar ifTrue: [self comeToFront]!
]style[(14 3 4 1 19 1 7 2 1 1 4 4 4 1 16 3 4 1 16 11 8 1 1 24 7 2 4 1 11 1)b,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c126000000,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;! !

!ScrollPane methodsFor: 'layout' stamp: 'mt 8/20/2019 11:32'!
doLayoutIn: layoutBounds
	"Manually layout my submorphs. Maybe we can find a proper layout policy in the future."
	
	self removeProperty: #doLayoutAgain.
	self
		resizeScrollBars;
		resizeScroller;
		adjustOffset;
		setScrollDeltas.
	
	"Do one additional run if required."
	(self hasProperty: #doLayoutAgain) ifTrue: [
		self doLayoutIn: layoutBounds.
		self assert: (self hasProperty: #doLayoutAgain) not.
		^ self].
	
	super doLayoutIn: layoutBounds.!
]style[(11 1 12 2 87 4 4 1 15 1 14 3 4 3 16 4 14 4 12 4 15 5 36 3 4 1 12 1 14 2 7 5 4 1 11 1 12 4 4 1 7 1 1 4 1 12 1 14 1 1 3 4 1 1 4 6 5 1 11 1 12 1)b,cblack;,c000000126,cblack;,c000126126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000126000,c126000000,cblack;,c000000126,cblack;,c000000126,c000126000,cblack;,c000000126,cblack;,c126000000,cblack;,c126000000,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;! !

!ScrollPane methodsFor: 'layout' stamp: 'mt 8/12/2019 13:16'!
layoutChanged

	self setProperty: #doLayoutAgain toValue: true.
	super layoutChanged.!
]style[(13 3 4 1 12 1 14 1 8 1 4 3 5 1 13 1)b,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c126000000,cblack;,c000000126,cblack;! !

!ScrollPane methodsFor: 'accessing retractable' stamp: 'mt 8/10/2019 12:19'!
retractableOrNot
	"Change scroll bar operation"

	retractableScrollBar := retractableScrollBar not.
	retractableScrollBar
		ifTrue: [
			self removeMorph: scrollBar; removeMorph: hScrollBar]
		ifFalse: [(submorphs includes: scrollBar) 
					ifFalse: 
						[self privateAddMorph: scrollBar atIndex: 1.
						self privateAddMorph: hScrollBar atIndex: 1]].
	self updateMinimumExtent.!
]style[(16 2 29 24 2 22 3 26 7 6 4 1 12 12 12 15 8 2 1 10 9 10 1 7 8 8 1 4 1 16 11 8 1 1 8 4 1 16 12 8 1 1 1 4 4 1 19 1)b,cblack;,c000126126,cblack;,b,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,cblack;,c000000126,cblack;,c000126000,cblack;,c000000126,cblack;,c000126000,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,c000126000,cblack;,c126000000,cblack;,c000000126,cblack;! !


!PluggableTextMorph methodsFor: 'accessing' stamp: 'mt 8/10/2019 12:16'!
wrapFlag: aBoolean

	textMorph ifNil: [self setText: ''].
	textMorph
		wrapFlag: aBoolean;
		autoFit: true.
	
	"Text navigation will be tedious if there is no horizontal scroll bar w/o wrapping."
	aBoolean ifFalse: [self showHScrollBarOnlyWhenNeeded].

	self layoutChanged.!
]style[(9 1 8 13 6 2 4 1 8 1 2 16 9 1 8 4 8 1 4 5 84 2 8 1 8 2 4 1 28 5 4 1 13 1)b,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000126n,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000126126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;! !

!PluggableTextMorph methodsFor: 'model access' stamp: 'mt 8/10/2019 11:42'!
setSelection: anInterval
	"Sets a new selection of characters. If the argument is nil, give the model a chance to just leave the selection where it currently is."
	
	(anInterval notNil and: [anInterval ~= selectionInterval]) ifTrue: [
		
		"Note old selection."
		textMorph selectionChanged.
		
		"Update selection."
		selectionInterval := anInterval.
		textMorph editor selectFrom: anInterval first to: anInterval last.

		"Note new selection."	
		textMorph selectionChanged].

	"Even if there is no change, ensure that the selection is visible."
	self scrollSelectionIntoView.!
]style[(13 1 10 2 136 5 10 1 6 1 4 1 1 10 1 2 18 1 2 7 8 21 13 16 7 19 21 2 1 10 14 6 1 11 1 10 1 5 1 3 1 10 1 4 5 21 14 16 5 67 2 4 1 23 1)b,cblack;,c000000126,cblack;,c000126126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c000000126,cblack;,c000000126,cblack;,c000126000,cblack;,c000000126,cblack;,c000126126,cblack;,c000000126,cblack;,c000126126,cblack;,b,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126126,cblack;,c000000126,cblack;,c000126126,cblack;,c126000000,cblack;,c000000126,cblack;! !


!ScrollPane class methodsFor: 'preferences' stamp: 'mt 8/9/2019 13:24'!
useRetractableScrollBars: aBoolean
	
	UseRetractableScrollBars = aBoolean ifTrue: [^ self].
	UseRetractableScrollBars := aBoolean.
	ScrollPane allSubInstances do: [:pane | 
		pane retractable: aBoolean].!
]style[(25 1 8 4 24 1 1 1 8 1 7 2 1 1 4 4 24 1 2 1 8 14 15 1 3 3 4 1 1 4 4 1 12 1 8 2)bu,cblack;,c000000126,cblack;,c063063063,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c126000000,cblack;,c063063063,cblack;,b,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,cgray;,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;! !


!ServiceGui methodsFor: 'styling' stamp: 'mt 8/21/2019 13:46'!
styleBar: aBar
	aBar setNameTo: 'button bar'.
	aBar beSticky;
		hResizing: #spaceFill;
		wrapCentering: #center;
		cellPositioning: #leftCenter;
		clipSubmorphs: true;
		color: Color veryVeryLightGray.!
]style[(9 1 4 2 4 1 10 1 12 3 4 1 8 4 10 1 10 4 14 1 7 4 16 1 11 4 14 1 4 4 6 7 17 1)b,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126n,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;! !


!SystemProgressMorph methodsFor: 'initialization' stamp: 'mt 8/21/2019 13:41'!
initialize
	super initialize.
	activeSlots := 0.
	bars := Array new: 10.
	labels := Array new: 10.
	lock := Semaphore forMutualExclusion.
	self setDefaultParameters;
		setProperty: #morphicLayerNumber toValue: self morphicLayerNumber;
		layoutPolicy: TableLayout new;
		listDirection: #topToBottom;
		cellPositioning: #leftCenter;
		cellGap: 5;
		listCentering: #center;
		hResizing: #shrinkWrap;
		vResizing: #shrinkWrap;
		layoutInset: Inset;
		minWidth: 150!
]style[(10 2 5 1 10 15 2 1 1 8 2 7 4 1 2 10 2 7 4 1 2 8 2 11 18 3 4 1 20 4 12 1 19 1 8 1 4 1 18 4 13 13 3 4 14 1 12 4 16 1 11 4 8 1 1 4 14 1 7 4 10 1 11 4 10 1 11 4 12 1 5 4 9 1 3)b,cblack;,c126000000,cblack;,c000000126,cblack;,b,cblack;,c126000000,cblack;,b,cblack;,c000000126,cblack;,c126000000,cblack;,b,cblack;,c000000126,cblack;,c126000000,cblack;,b,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c063063063,cblack;,c000000126,cblack;,c126000000! !


!SystemWindow methodsFor: 'initialization' stamp: 'mt 8/21/2019 13:41'!
initialize
	"Initialize a system window. Add label, stripes, etc., if desired"

	super initialize.

	self layoutPolicy: ProportionalLayout new.

	self wantsPaneSplitters: true.
	self layoutInset: ProportionalSplitterMorph gripThickness.
	self cellGap: ProportionalSplitterMorph gripThickness.

	self initializeLabelArea.				
	self addCornerGrips.
	self setDefaultParameters.

	allowReframeHandles := true.
	isCollapsed := false.
	paneMorphs := Array new.
	mustNotClose := false.
	updatablePanes := Array new.

	self initializeKeyboardShortcuts.!
]style[(10 2 66 3 5 1 10 4 4 1 13 20 3 4 4 1 19 1 4 3 4 1 12 27 13 3 4 1 8 27 13 4 4 1 19 7 4 1 14 3 4 1 20 24 2 1 4 15 2 1 5 14 2 7 3 16 2 1 5 18 2 7 3 4 4 1 27 1)b,cblack;,c000126126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,b,cblack;,c126000000,cblack;,b,cblack;,c126000000,cblack;,b,cblack;,c000000126,cblack;,b,cblack;,c126000000,cblack;,b,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;! !

!SystemWindow methodsFor: 'label' stamp: 'mt 8/21/2019 10:21'!
labelHeight
	"Answer the height for the window label.  The standard behavior is at bottom; a hook is provided so that models can stipulate other heights, in support of various less-window-looking demos."

	| aHeight |
	(model notNil and: [model respondsTo: #desiredWindowLabelHeightIn:]) ifTrue:
		[(aHeight := model desiredWindowLabelHeightIn: self) ifNotNil: [^ aHeight]].

	^ label ifNil: [0] ifNotNil:
		 [(label height + self cellInset + self cellGap + self layoutInset) max:
			(collapseBox ifNotNil: [collapseBox height] ifNil: [10])]!
]style[(11 2 190 3 1 1 7 1 1 9 6 1 4 1 1 6 11 1 28 1 2 7 4 1 7 1 2 7 27 1 4 1 1 9 1 1 1 1 7 1 5 1 7 6 2 1 2 9 5 1 6 6 1 1 1 4 1 9 1 1 1 4 1 7 1 1 1 4 1 11 1 1 4 4 1 12 9 1 1 12 6 1 1 6 1 1 2 1 1 1)b,cblack;,c000126126,cblack;,cgray;,cblack;,c106106106,cblack;,cgray;,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,cblack;,c000000126,cblack;,c000000126,c000126000,cblack;,c000000126,cblack;,c000126000,c106106106,cblack;,b,cblack;,c000000126,cblack;,c126000000,c000126000,cblack;,c000000126,cblack;,c000126000,c126000000,cblack;,c106106106,c000126000,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000126000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,c000126000,cblack;,c000000126,cblack;,c000126000,cblack;,c000000126,cblack;,c126000126,cblack;,c000000126,c126000126,cblack;,c000000126,cblack;,c126000126,c126000000,c126000126,c000126000,cblack;! !


!ArchiveViewer methodsFor: 'initialization' stamp: 'mt 8/21/2019 13:43'!
createButtonBar
	| bar |
	
	bar := AlignmentMorph newRow.
	bar
		color: self defaultBackgroundColor;
		rubberBandCells: false;
		vResizing: #shrinkWrap;
		cellGap: 6 @ 0.
	#(#('new archive' #canCreateNewArchive #createNewArchive 'Create a new, empty archive and discard this one') #('load archive' #canOpenNewArchive #openNewArchive 'Open another archive and discard this one') #('save archive' #canSaveArchive #saveArchive 'Save this archive under a new name') #('extract all' #canExtractAll #extractAll 'Extract all this archive''s members into a directory') #('add file' #canAddMember #addMember 'Add a file to this archive') #('add clipboard' #canAddMember #addMemberFromClipboard 'Add the contents of the clipboard as a new file') #('add dir ' #canAddMember #addDirectory 'Add the entire contents of a directory, with all of its subdirectories') #('extract member' #canExtractMember #extractMember 'Extract the selected member to a file') #('delete member' #canDeleteMember #deleteMember 'Remove the selected member from this archive') #('rename member' #canRenameMember #renameMember 'Rename the selected member') #('view all' #canViewAllContents #changeViewAllContents 'Toggle the view of all the selected member''s contents')) 
		do: 
			[:arr | 
			| button |
			(button := PluggableButtonMorph 
						on: self
						getState: arr second
						action: arr third)
				vResizing: #spaceFill;
				hResizing: #spaceFill;
				onColor: self buttonOnColor offColor: self buttonOffColor;
				label: arr first withCRs;
				setBalloonText: arr fourth.
			bar addMorphBack: button].
	^bar!
]style[(15 2 1 1 3 1 1 4 3 1 2 16 6 3 3 3 6 1 4 1 22 4 16 1 5 4 10 1 11 4 8 1 1 1 1 1 1 3 1 1 1 1 13 1 20 1 17 1 50 2 1 1 14 1 18 1 15 1 43 2 1 1 14 1 15 1 12 1 36 2 1 1 13 1 14 1 11 1 54 2 1 1 10 1 13 1 10 1 28 2 1 1 15 1 13 1 23 1 49 2 1 1 10 1 13 1 13 1 72 2 1 1 16 1 17 1 14 1 39 2 1 1 15 1 16 1 13 1 46 2 1 1 15 1 16 1 13 1 28 2 1 1 10 1 19 1 22 1 56 6 3 7 3 1 1 5 1 1 6 1 1 4 1 6 1 2 29 3 1 4 7 9 1 3 1 6 7 7 1 3 1 5 1 5 10 1 10 6 10 1 10 6 8 1 4 1 13 1 9 1 4 1 14 6 6 1 3 1 5 1 7 6 15 1 3 1 6 5 3 1 13 1 6 4 1 3)b,cblack;,cgray;,cblack;,c106106106,cblack;,cgray;,cblack;,c106106106,cblack;,b,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126n,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126n,cblack;,c000000126,cblack;,c126000126n,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126n,cblack;,c000000126,cblack;,c126000126n,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126n,cblack;,c000000126,cblack;,c126000126n,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126n,cblack;,c000000126,cblack;,c126000126n,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126n,cblack;,c000000126,cblack;,c126000126n,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126n,cblack;,c000000126,cblack;,c126000126n,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126n,cblack;,c000000126,cblack;,c126000126n,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126n,cblack;,c000000126,cblack;,c126000126n,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126n,cblack;,c000000126,cblack;,c126000126n,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126n,cblack;,c000000126,cblack;,c126000126n,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126n,cblack;,c000000126,cblack;,c000000126,cblack;,cgray;,cblack;,cgray;,cblack;,cgray;,cblack;,cgray;,cblack;,c000126000,cgray;,cblack;,b,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,c000126000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,cgray;,cblack;,c126000000,c106106106! !


!PreferenceBrowserMorph methodsFor: 'submorphs - buttons' stamp: 'mt 8/21/2019 11:20'!
newButtonRow
	^BorderedMorph new
		color: Color transparent;
		borderWidth: 0;
		cellGap: 2;
		layoutInset: 2;
		layoutPolicy: TableLayout new;
		listDirection: #leftToRight;
		listCentering: #topLeft;
		cellPositioning: #topLeft;
		on: #mouseEnter send: #paneTransition: to: self;
		on: #mouseLeave send: #paneTransition: to: self;
		addMorphBack: self defaultButton;
		addMorphBack: self newSeparator;
		addMorphBack: self saveButton;
		addMorphBack: self loadButton;
		addMorphBack: self newSeparator;
		addMorphBack: self saveToDiskButton;
		addMorphBack: self loadFromDiskButton;
		addMorphBack: self newSeparator;
		addMorphBack: self themeButton;
		addMorphBack: self newTransparentFiller;
		addMorphBack: self helpButton;
		yourself.!
]style[(12 2 1 14 3 3 6 7 11 4 12 1 1 4 8 1 1 4 12 1 1 4 13 13 3 4 14 1 12 4 14 1 8 4 16 1 8 4 3 1 11 1 5 1 16 1 3 1 4 4 3 1 11 1 5 1 16 1 3 1 4 4 13 1 4 1 13 4 13 1 4 1 12 4 13 1 4 1 10 4 13 1 4 1 10 4 13 1 4 1 12 4 13 1 4 1 16 4 13 1 4 1 18 4 13 1 4 1 12 4 13 1 4 1 11 4 13 1 4 1 20 4 13 1 4 1 10 4 8 1)b,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;! !

!PreferenceBrowserMorph methodsFor: 'submorphs - category list' stamp: 'mt 8/21/2019 11:21'!
newCategoryListPanel
	^Morph new
		hResizing: #shrinkWrap;
		vResizing: #spaceFill;
		color: Color transparent;
		layoutPolicy: TableLayout new;
		cellGap: 3;
		listCentering: #topLeft;
		listDirection: #topToBottom;
		cellPositioning: #topLeft;
		clipSubmorphs: true;
		addMorphBack: self newCategoryListPanelLabel;
		addMorphBack: self newCategoryList!
]style[(20 2 1 6 3 3 10 1 11 4 10 1 10 4 6 7 11 4 13 13 3 4 8 1 1 4 14 1 8 4 14 1 12 4 16 1 8 4 14 1 4 4 13 1 4 1 25 4 13 1 4 1 15)b,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126! !

!PreferenceBrowserMorph methodsFor: 'submorphs - main panel' stamp: 'mt 8/21/2019 11:20'!
mainPanel
	^mainPanel ifNil: 
		[mainPanel := BorderedMorph new
			color: Color transparent;
			borderWidth: 0;
			hResizing: #spaceFill;
			vResizing: #spaceFill;
			cellGap: 5;
			changeProportionalLayout;
			on: #mouseEnter send: #paneTransition: to: self;
			addMorphBack: self newCategoryList;
			addMorphBack: self preferenceList;
			layoutFrame: (LayoutFrame fractions: (0@0 corner: 1@1) offsets: (0@ 30 corner: 0@0));
			addPaneSplitters;
			yourself].!
]style[(9 2 1 10 6 15 2 15 3 4 6 7 11 5 12 1 1 5 10 1 10 5 10 1 10 5 8 1 1 5 24 5 3 1 11 1 5 1 16 1 3 1 4 5 13 1 4 1 15 5 13 1 4 1 14 5 12 1 1 12 10 1 1 1 1 1 1 7 1 1 1 1 1 1 8 1 1 1 1 1 2 1 7 1 1 1 1 1 1 5 16 5 8 2)b,cblack;,c126000000,cblack;,c000000126,cblack;,b,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,cblack;,c000000126,cblack;,c126000126,c126000000,c000000126,c126000000,cblack;,c000000126,cblack;,c126000000,c000000126,c126000000,c126000126,cblack;,c000000126,cblack;,c126000126,c126000000,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,c000000126,c126000000,c126000126,c000126000,cblack;,c000000126,cblack;,c000000126,cblack;! !

!PreferenceBrowserMorph methodsFor: 'submorphs - preference list' stamp: 'mt 8/21/2019 11:21'!
newPreferenceListPanel
	| panel |
	panel := Morph new
		hResizing: #spaceFill;
		vResizing: #spaceFill;
		color: Color transparent;
		layoutPolicy: TableLayout new;
		cellGap: 3;
		listCentering: #topLeft;
		listDirection: #topToBottom;
		cellPositioning: #topLeft;
		clipSubmorphs: true;
		addMorphBack: self newPreferenceListPanelLabel;
		addMorphBack: self preferenceList.
	^panel.!
]style[(22 2 1 1 5 1 1 2 5 1 2 7 3 3 10 1 10 4 10 1 10 4 6 7 11 4 13 13 3 4 8 1 1 4 14 1 8 4 14 1 12 4 16 1 8 4 14 1 4 4 13 1 4 1 27 4 13 1 4 1 14 3 1 5 1)b,cblack;,cgray;,cblack;,c106106106,cblack;,cgray;,cblack;,c106106106,cblack;,b,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,c106106106,cblack;! !

!PreferenceBrowserMorph methodsFor: 'submorphs - search panel' stamp: 'mt 8/21/2019 11:21'!
newSearchPanel
	| bottom |
	bottom := Morph new
		color: Color transparent;
		cellGap: 5;
		layoutPolicy: TableLayout new;
		listDirection: #leftToRight;
		listCentering: #topLeft;
		cellPositioning: #topLeft;
		hResizing: #spaceFill;
		vResizing: #shrinkWrap;
		addMorphBack: self newSearchTextField
		yourself.
	^Morph new
		color: Color transparent;
		layoutPolicy: TableLayout new;
		listDirection: #topToBottom;
		listCentering: #topLeft;
		cellPositioning: #topLeft;
		hResizing: #spaceFill;
		vResizing: #shrinkWrap;
		cellGap: 3;
		addMorphBack: (StringMorph contents: 'Search preferences for: ');
		addMorphBack: bottom;
		yourself.!
]style[(14 2 1 1 6 1 1 2 6 1 2 7 3 3 6 7 11 4 8 1 1 4 13 13 3 4 14 1 12 4 14 1 8 4 16 1 8 4 10 1 10 4 10 1 11 4 13 1 4 1 18 3 8 3 1 6 3 3 6 7 11 4 13 13 3 4 14 1 12 4 14 1 8 4 16 1 8 4 10 1 10 4 10 1 11 4 8 1 1 4 13 14 9 1 26 5 13 1 6 4 8 1)b,cblack;,cgray;,cblack;,c106106106,cblack;,cgray;,cblack;,c106106106,cblack;,b,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126n,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;! !


!ServiceBrowserMorph methodsFor: 'as yet unclassified' stamp: 'mt 8/21/2019 13:45'!
newButtonRow
	^BorderedMorph new
		color: Color transparent; 
		cellGap: 2;
		layoutInset: 2;
		layoutPolicy: TableLayout new;
		listDirection: #leftToRight;
		listCentering: #topLeft;
		cellPositioning: #topLeft;
		on: #mouseEnter send: #paneTransition: to: self;
		on: #mouseLeave send: #paneTransition: to: self;
		"addMorphBack: self defaultButton;
		addMorphBack: self newSeparator;
		addMorphBack: self saveButton;
		addMorphBack: self loadButton;
		addMorphBack: self newSeparator;
		addMorphBack: self saveToDiskButton;
		addMorphBack: self loadFromDiskButton;
		addMorphBack: self newSeparator;
		addMorphBack: self newTransparentFiller;
		addMorphBack: self helpButton;"
		yourself.!
]style[(12 2 1 14 3 3 6 7 11 5 8 1 1 4 12 1 1 4 13 13 3 4 14 1 12 4 14 1 8 4 16 1 8 4 3 1 11 1 5 1 16 1 3 1 4 4 3 1 11 1 5 1 16 1 3 1 4 4 362 3 8 1)b,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000126126,cblack;,c000000126,cblack;! !


!TableLayout methodsFor: 'layout' stamp: 'mt 8/21/2019 09:20'!
computeCellArrangement: cellHolder in: newBounds horizontal: aBool target: aMorph 
	"Compute number of cells we can put in each row/column. The returned array contains a list of all the cells we can put into the row/column at each level.
	Note: The arrangement is so that the 'x' value of each cell advances along the list direction and the 'y' value along the wrap direction. The returned arrangement has an extra cell at the start describing the width and height of the row."

	| cells wrap spacing output maxExtent n sum index max cell first last w cellMax maxCell hFill vFill gap |
	maxCell := cellHolder key.
	cells := cellHolder value.
	properties wrapDirection == #none 
		ifTrue: [wrap := SmallInteger maxVal]
		ifFalse: 
			[wrap := aBool ifTrue: [newBounds width] ifFalse: [newBounds height].
			wrap := wrap max: (maxCell x)].
	spacing := properties cellSpacing.
	(spacing == #globalRect or: [spacing = #globalSquare]) 
		ifTrue: 
			["Globally equal spacing is a very special case here, so get out fast and easy"

			^self 
				computeGlobalCellArrangement: cells
				in: newBounds
				horizontal: aBool
				wrap: wrap
				spacing: spacing].
	output := WriteStream on: Array new.
	gap := properties cellGap asPoint.
	aBool ifFalse: [gap := gap transposed].
	first := last := nil.
	maxExtent := 0 @ 0.
	sum := 0.
	index := 1.
	n := 0.
	hFill := vFill := false.
	[index <= cells size] whileTrue: 
			[w := sum.
			cell := cells at: index.
			cellMax := maxExtent max: cell cellSize.	"e.g., minSize"
			sum := (spacing == #localRect or: [spacing == #localSquare]) 
						ifTrue: 
							["Recompute entire size of current row"

							max := spacing == #localSquare 
										ifTrue: [cellMax x max: cellMax y]
										ifFalse: [cellMax x].
							(n + 1) * max]
						ifFalse: [sum + cell cellSize x].
			(sum + (n * gap x) > wrap and: [first notNil]) 
				ifTrue: 
					["It doesn't fit and we're not starting a new line"

					(spacing == #localSquare or: [spacing == #localRect]) 
						ifTrue: 
							[spacing == #localSquare 
								ifTrue: [maxExtent := (maxExtent x max: maxExtent y) asPoint].
							first do: [:c | c cellSize: maxExtent]].
					w := w + ((n - 1) * gap x).
					"redistribute extra space"
					first nextCell 
						ifNotNil: [first nextCell do: [:c | c addExtraSpace: gap x @ 0]].
					last := LayoutCell new.
					last cellSize: w @ maxExtent y.
					last hSpaceFill: hFill.
					last vSpaceFill: vFill.
					last nextCell: first.
					output position = 0 ifFalse: [last addExtraSpace: 0 @ gap y].
					output nextPut: last.
					first := nil.
					maxExtent := 0 @ 0.
					sum := 0.
					n := 0.
					hFill := vFill := false]
				ifFalse: 
					["It did fit; use next item from input"

					first ifNil: [first := last := cell]
						ifNotNil: 
							[last nextCell: cell.
							last := cell].
					index := index + 1.
					n := n + 1.
					maxExtent := cellMax.
					hFill := hFill or: [cell hSpaceFill].
					vFill := vFill or: [cell vSpaceFill]]].
	first ifNotNil: 
			[last := LayoutCell new.
			sum := sum + ((n - 1) * gap x).
			first nextCell 
				ifNotNil: [first nextCell do: [:c | c addExtraSpace: gap x @ 0]].
			last cellSize: sum @ maxExtent y.
			last hSpaceFill: hFill.
			last vSpaceFill: vFill.
			last nextCell: first.
			output position = 0 ifFalse: [last addExtraSpace: 0 @ gap y].
			output nextPut: last].
	output := output contents.
	properties listSpacing == #equal 
		ifTrue: 
			["Make all the heights equal"

			max := output inject: 0 into: [:size :c | size max: c cellSize y].
			output do: [:c | c cellSize: c cellSize x @ max]].
	^output! !

!TableLayout methodsFor: 'layout' stamp: 'mt 8/21/2019 10:02'!
computeCellSizes: aMorph in: newBounds horizontal: aBool
	"Step 1: Compute the minimum extent for all the children of aMorph"
	| cells block minSize maxSize maxCell insetExtra |
	cells := WriteStream on: (Array new: aMorph submorphCount).
	minSize := properties minCellSize asPoint.
	maxSize := properties maxCellSize asPoint.
	aBool ifTrue:[
		minSize := minSize transposed.
		maxSize := maxSize transposed].
	maxCell := 0@0.
	insetExtra := properties cellInset.
	insetExtra isRectangle
		ifTrue: [insetExtra := insetExtra left + insetExtra right @ (insetExtra top + insetExtra bottom)]
		ifFalse: [insetExtra := insetExtra*2 asPoint].
	block := [:m| | size cell |
		m disableTableLayout ifFalse:[
			size := m minExtent asIntegerPoint + insetExtra.
			cell := LayoutCell new target: m.
			aBool ifTrue:[
				cell hSpaceFill: m hResizing == #spaceFill.
				cell vSpaceFill: m vResizing == #spaceFill.
			] ifFalse:[
				cell hSpaceFill: m vResizing == #spaceFill.
				cell vSpaceFill: m hResizing == #spaceFill.
				size := size transposed.
			].
			size := (size min: maxSize) max: minSize.
			cell cellSize: size.
			maxCell := maxCell max: size.
			cells nextPut: cell]].
	properties reverseTableCells
		ifTrue:[aMorph submorphsReverseDo: block]
		ifFalse:[aMorph submorphsDo: block].
	^maxCell -> cells contents! !

!TableLayout methodsFor: 'layout' stamp: 'mt 8/21/2019 09:00'!
placeCells: arrangement in: newBounds horizontal: aBool target: aMorph 
	"Place the morphs within the cells accordingly"

	| xDir yDir anchor yDist place cell xDist cellRect corner inset |
	inset := properties cellInset.
	(inset isNumber and: [inset isZero]) ifTrue: [inset := nil].
	aBool 
		ifTrue: 
			["horizontal layout"

			properties listDirection == #rightToLeft 
				ifTrue: 
					[xDir := -1 @ 0.
					properties wrapDirection == #bottomToTop 
						ifTrue: 
							[yDir := 0 @ -1.
							anchor := newBounds bottomRight]
						ifFalse: 
							[yDir := 0 @ 1.
							anchor := newBounds topRight]]
				ifFalse: 
					[xDir := 1 @ 0.
					properties wrapDirection == #bottomToTop 
						ifTrue: 
							[yDir := 0 @ -1.
							anchor := newBounds bottomLeft]
						ifFalse: 
							[yDir := 0 @ 1.
							anchor := newBounds topLeft]]]
		ifFalse: 
			["vertical layout"

			properties listDirection == #bottomToTop 
				ifTrue: 
					[xDir := 0 @ -1.
					properties wrapDirection == #rightToLeft 
						ifTrue: 
							[yDir := -1 @ 0.
							anchor := newBounds bottomRight]
						ifFalse: 
							[yDir := 1 @ 0.
							anchor := newBounds bottomLeft]]
				ifFalse: 
					[xDir := 0 @ 1.
					anchor := properties wrapDirection == #rightToLeft 
								ifTrue: 
									[yDir := -1 @ 0.
									newBounds topRight]
								ifFalse: 
									[yDir := 1 @ 0.
									newBounds topLeft]]].
	1 to: arrangement size
		do: 
			[:i | 
			cell := arrangement at: i.
			cell extraSpace ifNotNil: [anchor := anchor + (cell extraSpace y * yDir)].
			yDist := cell cellSize y * yDir.	"secondary advance direction"
			place := anchor.
			cell := cell nextCell.
			[cell isNil] whileFalse: 
					[cell extraSpace ifNotNil: [place := place + (cell extraSpace x * xDir)].
					xDist := cell cellSize x * xDir.	"primary advance direction"
					corner := place + xDist + yDist.
					cellRect := Rectangle origin: (place min: corner)
								corner: (place max: corner).
					inset ifNotNil: [cellRect := cellRect insetBy: inset].
					cell target layoutInBounds: cellRect.
					place := place + xDist.
					cell := cell nextCell].
			anchor := anchor + yDist]!
]style[(11 1 11 1 3 1 9 1 11 1 5 1 7 1 6 3 47 3 1 1 4 1 4 1 6 1 5 1 5 1 4 1 5 1 8 1 6 1 5 1 1 2 5 1 2 12 9 4 5 1 8 1 4 1 1 5 1 6 1 2 7 2 5 1 2 1 3 4 5 4 7 6 19 16 13 1 2 1 12 6 7 7 1 4 1 2 1 2 1 1 1 1 18 13 1 2 1 12 8 7 9 1 4 1 2 1 1 1 1 1 2 9 6 1 2 1 9 1 11 1 7 8 9 1 4 1 2 1 1 1 1 1 1 9 6 1 2 1 9 1 8 1 1 5 8 7 1 4 1 2 1 1 1 1 1 1 18 13 1 2 1 12 8 7 9 1 4 1 2 1 1 1 1 1 2 9 6 1 2 1 9 1 10 1 7 8 9 1 4 1 2 1 1 1 1 1 1 9 6 1 2 1 9 1 7 1 1 4 8 6 17 16 13 1 2 1 12 6 7 7 1 4 1 2 1 1 1 1 1 2 18 13 1 2 1 12 8 7 9 1 4 1 2 1 2 1 1 1 1 9 6 1 2 1 9 1 11 1 7 8 9 1 4 1 2 1 1 1 1 1 1 9 6 1 2 1 9 1 10 1 1 5 8 7 1 4 1 2 1 1 1 1 1 1 7 6 1 2 12 13 1 2 1 12 10 7 11 1 4 1 2 1 2 1 1 1 1 11 9 1 8 1 9 8 11 1 4 1 2 1 1 1 1 1 1 11 9 1 7 1 1 4 1 1 3 1 11 1 4 3 3 7 1 1 1 5 4 1 2 1 11 1 3 1 1 5 4 1 10 1 9 1 1 6 1 2 1 6 1 1 1 1 4 1 10 1 1 1 1 1 4 1 1 5 5 1 2 1 4 1 8 1 1 1 1 1 4 2 29 4 5 1 2 1 6 5 4 1 2 1 4 1 8 5 1 4 1 5 1 1 11 7 1 4 1 10 1 9 1 1 5 1 2 1 5 1 1 1 1 4 1 10 1 1 1 1 1 4 1 1 7 5 1 2 1 4 1 8 1 1 1 1 1 4 2 27 6 6 1 2 1 5 1 1 1 5 1 1 1 5 7 8 1 2 11 7 1 1 5 1 4 1 6 1 9 7 1 1 5 1 4 1 6 1 7 5 1 9 1 1 8 1 2 1 8 1 8 1 5 1 7 4 1 6 1 15 1 8 7 5 1 2 1 5 1 1 1 5 7 4 1 2 1 4 1 8 1 5 6 1 2 1 6 1 1 1 5 1)b,cblack;,c000000126,cblack;,b,cblack;,c000000126,cblack;,b,cblack;,c000000126,cblack;,b,cblack;,c000000126,cblack;,c000126126,cblack;,cgray;,cblack;,c106106106,cblack;,c106106106,cblack;,c106106106,cblack;,c106106106,cblack;,c106106106,cblack;,c106106106,cblack;,c106106106,cblack;,c106106106,cblack;,c106106106,cblack;,c106106106,cblack;,cgray;,cblack;,c106106106,cblack;,b,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c106106106,cblack;,c000000126,c000126000,cblack;,c000000126,cblack;,c106106106,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000126126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c106106106,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126,c106106106,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c106106106,cblack;,b,cblack;,c000000126,cblack;,c000000126,c126000126,cblack;,c000000126,cblack;,c126000126,c106106106,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c106106106,cblack;,b,cblack;,c000000126,cblack;,c000000126,c126000126,c000126000,cblack;,c000000126,cblack;,c000126000,c106106106,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126,c106106106,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c106106106,cblack;,b,cblack;,c000000126,cblack;,c000000126,c126000126,cblack;,c000000126,cblack;,c126000126,c106106106,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c106106106,cblack;,b,cblack;,c000000126,cblack;,c000000126,c126000126,c000126000,cblack;,c000000126,cblack;,c000126126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c106106106,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126,c106106106,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c106106106,cblack;,b,cblack;,c000000126,cblack;,c000000126,c126000126,cblack;,c000000126,cblack;,c126000126,c106106106,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c106106106,cblack;,b,cblack;,c000000126,cblack;,c000000126,c126000126,c000126000,cblack;,c000000126,cblack;,c000126000,c106106106,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c106106106,cblack;,b,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126,c106106106,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,c126000126,cblack;,c000000126,cblack;,c126000126,c106106106,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,c126000126,c000126000,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,cgray;,cblack;,c106106106,cblack;,b,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c106106106,cblack;,b,cblack;,c106106106,cblack;,c000000126,cblack;,c126000126,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,c126000126,c000126000,cblack;,c106106106,cblack;,b,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000126126,cblack;,c106106106,cblack;,b,cblack;,c106106106,cblack;,c106106106,cblack;,b,cblack;,c106106106,cblack;,c000000126,cblack;,c000126000,c106106106,cblack;,c000000126,c000126000,cblack;,c000000126,cblack;,c000126000,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126,c106106106,cblack;,b,cblack;,c106106106,cblack;,c000000126,cblack;,c126000000,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,c126000000,c126000126,cblack;,c106106106,cblack;,b,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000126126,cblack;,c106106106,cblack;,b,cblack;,c106106106,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c106106106,cblack;,c106106106,cblack;,b,cblack;,c000000126,cblack;,c126000126,c106106106,cblack;,c000000126,cblack;,c106106106,c126000126,cblack;,c000000126,cblack;,c126000126,c106106106,cblack;,c000000126,cblack;,c106106106,c126000126,cblack;,c106106106,cblack;,c000000126,cblack;,c126000126,c106106106,cblack;,b,cblack;,c106106106,cblack;,c000000126,cblack;,c106106106,c126000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c106106106,cblack;,b,cblack;,c106106106,cblack;,c000000126,cblack;,c106106106,cblack;,c106106106,cblack;,b,cblack;,c106106106,cblack;,c000000126,c000126000,cblack;,c106106106,cblack;,b,cblack;,c106106106,cblack;,c000000126,cblack;,c106106106,cblack;! !

!TableLayout methodsFor: 'optimized' stamp: 'mt 8/21/2019 10:26'!
layoutLeftToRight: aMorph in: newBounds 
	"An optimized left-to-right list layout"

	| inset insetExtra gap extent block posX posY centering extraPerCell amount minX minY maxX maxY n width extra last cell size height sum vFill first cellRect |
	size := properties minCellSize asPoint.
	minX := size x.
	minY := size y.
	size := properties maxCellSize asPoint.
	maxX := size x.
	maxY := size y.
	inset := properties cellInset.
	insetExtra := inset isRectangle
		ifTrue: [insetExtra := inset left + inset right @ (inset top + inset bottom)]
		ifFalse: [insetExtra := inset*2 asPoint].
	(inset isNumber and: [inset isZero]) ifTrue: [inset := nil].
	gap := properties cellGap asPoint x.
	extent := newBounds extent.
	n := 0.
	vFill := false.
	sum := 0.
	width := height := 0.
	first := last := nil.
	block := 
			[:m | | sizeX props sizeY | 
			props := m layoutProperties ifNil: [m].
			props disableTableLayout 
				ifFalse: 
					[n := n + 1.
					cell := LayoutCell new target: m.
					props hResizing == #spaceFill 
						ifTrue: 
							[cell hSpaceFill: true.
							extra := m spaceFillWeight.
							cell extraSpace: extra.
							sum := sum + extra]
						ifFalse: [cell hSpaceFill: false].
					props vResizing == #spaceFill ifTrue: [vFill := true].
					size := m minExtent + insetExtra.
					sizeX := size x.
					sizeY := size y.
					sizeX < minX ifTrue: [sizeX := minX] ifFalse: [sizeX := sizeX min: maxX].
					sizeY < minY ifTrue: [sizeY := minY] ifFalse: [sizeY := sizeY min: maxY].
					cell cellSize: sizeX.
					last ifNil: [first := cell] ifNotNil: [last nextCell: cell].
					last := cell.
					width := width + sizeX.
					sizeY > height ifTrue: [height := sizeY]]].
	properties reverseTableCells 
		ifTrue: [aMorph submorphsReverseDo: block]
		ifFalse: [aMorph submorphsDo: block].
	n > 1 ifTrue: [width := width + ((n - 1) * gap)].
	(properties hResizing == #shrinkWrap 
		and: [properties rubberBandCells or: [sum isZero]]) 
			ifTrue: [extent := width @ (extent y max: height)].
	(properties vResizing == #shrinkWrap 
		and: [properties rubberBandCells or: [vFill not]]) 
			ifTrue: [extent := (extent x max: width) @ height].
	posX := newBounds left.
	posY := newBounds top.

	"Compute extra vertical space"
	extra := extent y - height.
	extra := extra max: 0.
	extra > 0 
		ifTrue: 
			[vFill 
				ifTrue: [height := extent y]
				ifFalse: 
					[centering := properties wrapCentering.
					centering == #bottomRight ifTrue: [posY := posY + extra].
					centering == #center ifTrue: [posY := posY + (extra // 2)]]].


	"Compute extra horizontal space"
	extra := extent x - width.
	extra := extra max: 0.
	extraPerCell := 0.
	extra > 0 
		ifTrue: 
			[sum isZero 
				ifTrue: 
					["extra space but no #spaceFillers"

					centering := properties listCentering.
					centering == #bottomRight ifTrue: [posX := posX + extra].
					centering == #center ifTrue: [posX := posX + (extra // 2)]]
				ifFalse: [extraPerCell := extra asFloat / sum asFloat]].
	n := 0.
	extra := last := 0.
	cell := first.
	[cell isNil] whileFalse: 
			[n := n + 1.
			width := cell cellSize.
			(extraPerCell > 0 and: [cell hSpaceFill]) 
				ifTrue: 
					[extra := (last := extra) + (extraPerCell * cell extraSpace).
					amount := extra truncated - last truncated.
					width := width + amount].
			cellRect := (posX @ posY extent: width @ height).
			inset ifNotNil: [cellRect := cellRect insetBy: inset].
			cell target layoutInBounds: cellRect.
			posX := posX + width + gap.
			cell := cell nextCell]! !

!TableLayout methodsFor: 'optimized' stamp: 'mt 8/21/2019 10:26'!
layoutTopToBottom: aMorph in: newBounds 
	"An optimized top-to-bottom list layout"

	| inset insetExtra gap extent block posX posY centering extraPerCell amount minX minY maxX maxY n height extra last cell size width sum vFill first cellRect |
	size := properties minCellSize asPoint.
	minX := size x.
	minY := size y.
	size := properties maxCellSize asPoint.
	maxX := size x.
	maxY := size y.
	inset := properties cellInset.
	insetExtra := inset isRectangle
		ifTrue: [insetExtra := inset left + inset right @ (inset top + inset bottom)]
		ifFalse: [insetExtra := inset*2 asPoint].
	(inset isNumber and: [inset isZero]) ifTrue: [inset := nil].
	gap := properties cellGap asPoint y.
	extent := newBounds extent.
	n := 0.
	vFill := false.
	sum := 0.
	width := height := 0.
	first := last := nil.
	block := 
			[:m | | sizeY sizeX props | 
			props := m layoutProperties ifNil: [m].
			props disableTableLayout 
				ifFalse: 
					[n := n + 1.
					cell := LayoutCell new target: m.
					props vResizing == #spaceFill 
						ifTrue: 
							[cell vSpaceFill: true.
							extra := m spaceFillWeight.
							cell extraSpace: extra.
							sum := sum + extra]
						ifFalse: [cell vSpaceFill: false].
					props hResizing == #spaceFill ifTrue: [vFill := true].
					size := m minExtent + insetExtra.
					sizeX := size x.
					sizeY := size y.
					sizeX < minX ifTrue: [sizeX := minX] ifFalse: [sizeX := sizeX min: maxX].
					sizeY < minY ifTrue: [sizeY := minY] ifFalse: [sizeY := sizeY min: maxY].
					cell cellSize: sizeY.
					first ifNil: [first := cell] ifNotNil: [last nextCell: cell].
					last := cell.
					height := height + sizeY.
					sizeX > width ifTrue: [width := sizeX]]].
	properties reverseTableCells 
		ifTrue: [aMorph submorphsReverseDo: block]
		ifFalse: [aMorph submorphsDo: block].
	n > 1 ifTrue: [height := height + ((n - 1) * gap)].
	(properties vResizing == #shrinkWrap 
		and: [properties rubberBandCells or: [sum isZero]]) 
			ifTrue: [extent := (extent x max: width) @ height].
	(properties hResizing == #shrinkWrap 
		and: [properties rubberBandCells or: [vFill not]]) 
			ifTrue: [extent := width @ (extent y max: height)].
	posX := newBounds left.
	posY := newBounds top.

	"Compute extra horizontal space"
	extra := extent x - width.
	extra := extra max: 0.
	extra > 0 
		ifTrue: 
			[vFill 
				ifTrue: [width := extent x]
				ifFalse: 
					[centering := properties wrapCentering.
					centering == #bottomRight ifTrue: [posX := posX + extra].
					centering == #center ifTrue: [posX := posX + (extra // 2)]]].


	"Compute extra vertical space"
	extra := extent y - height.
	extra := extra max: 0.
	extraPerCell := 0.
	extra > 0 
		ifTrue: 
			[sum isZero 
				ifTrue: 
					["extra space but no #spaceFillers"

					centering := properties listCentering.
					centering == #bottomRight ifTrue: [posY := posY + extra].
					centering == #center ifTrue: [posY := posY + (extra // 2)]]
				ifFalse: [extraPerCell := extra asFloat / sum asFloat]].
	n := 0.
	extra := last := 0.
	cell := first.
	[cell isNil] whileFalse: 
			[n := n + 1.
			height := cell cellSize.
			(extraPerCell > 0 and: [cell vSpaceFill]) 
				ifTrue: 
					[extra := (last := extra) + (extraPerCell * cell extraSpace).
					amount := extra truncated - last truncated.
					height := height + amount].
			cellRect := (posX @ posY extent: width @ height).
			inset ifNotNil: [cellRect := cellRect insetBy: inset].
			cell target layoutInBounds: cellRect.
			posY := posY + height + gap.
			cell := cell nextCell]! !

!TableLayout methodsFor: 'optimized' stamp: 'mt 8/21/2019 09:53'!
minExtentHorizontal: aMorph 
	"Return the minimal size aMorph's children would require given the new bounds"

	| insetExtra gap minX minY maxX maxY n size width height |
	size := properties minCellSize asPoint.
	minX := size x.
	minY := size y.
	size := properties maxCellSize asPoint.
	maxX := size x.
	maxY := size y.
	insetExtra := properties cellInset.
	insetExtra isRectangle
		ifTrue: [insetExtra := insetExtra left + insetExtra right @ (insetExtra top + insetExtra bottom)]
		ifFalse: [insetExtra := insetExtra*2 asPoint].
	gap := properties cellGap asPoint.
	n := 0.
	width := height := 0.
	aMorph submorphsDo: 
			[:m | | sizeX sizeY | 
			m disableTableLayout 
				ifFalse: 
					[n := n + 1.
					size := m minExtent + insetExtra.
					sizeX := size x.
					sizeY := size y.
					sizeX < minX 
						ifTrue: [sizeX := minX]
						ifFalse: [sizeX := sizeX min: maxX].
					sizeY < minY 
						ifTrue: [sizeY := minY]
						ifFalse: [sizeY := sizeY min: maxY].
					width := width + sizeX.
					sizeY > height ifTrue: [height := sizeY]]].
	n > 1 ifTrue: [width := width + ((n - 1) * gap x)].
	^minExtentCache := width @ height! !

!TableLayout methodsFor: 'optimized' stamp: 'mt 8/21/2019 09:53'!
minExtentVertical: aMorph 
	"Return the minimal size aMorph's children would require given the new bounds"

	| insetExtra gap minX minY maxX maxY n size width height |
	size := properties minCellSize asPoint.
	minX := size x.
	minY := size y.
	size := properties maxCellSize asPoint.
	maxX := size x.
	maxY := size y.
	insetExtra := properties cellInset.
	insetExtra isRectangle
		ifTrue: [insetExtra := insetExtra left + insetExtra right @ (insetExtra top + insetExtra bottom)]
		ifFalse: [insetExtra := insetExtra*2 asPoint].
	gap := properties cellGap asPoint.
	n := 0.
	width := height := 0.
	aMorph submorphsDo: 
			[:m | | sizeY sizeX | 
			m disableTableLayout 
				ifFalse: 
					[n := n + 1.
					size := m minExtent + insetExtra.
					sizeX := size x.
					sizeY := size y.
					sizeX < minX 
						ifTrue: [sizeX := minX]
						ifFalse: [sizeX := sizeX min: maxX].
					sizeY < minY 
						ifTrue: [sizeY := minY]
						ifFalse: [sizeY := sizeY min: maxY].
					height := height + sizeY.
					sizeX > width ifTrue: [width := sizeX]]].
	n > 1 ifTrue: [height := height + ((n - 1) * gap y)].
	^minExtentCache := width @ height! !


!TableLayoutProperties methodsFor: 'accessing' stamp: 'mt 8/21/2019 09:07'!
cellGap: aNumber
	cellGap := aNumber!
]style[(8 1 7 10 2 1 7)b,cblack;,c000000126,cblack;,b,cblack;,c000000126! !

!TableLayoutProperties methodsFor: 'initialize' stamp: 'mt 8/21/2019 09:14'!
initialize
	super initialize.
	cellSpacing := listSpacing := wrapDirection := #none.
	cellPositioning := #center.
	listCentering := wrapCentering := #topLeft.
	listDirection := #topToBottom.
	reverseTableCells := rubberBandCells := false.
	layoutInset := cellInset := minCellSize := cellGap := 0.
	maxCellSize := 1073741823. "SmallInteger maxVal"
!
]style[(10 2 5 1 10 15 2 13 2 15 2 1 5 19 2 1 7 17 2 15 2 1 8 17 2 1 12 21 2 17 2 1 5 15 2 11 2 13 2 9 2 1 1 15 2 1 10 2 21 1)b,cblack;,c126000000,cblack;,c000000126,cblack;,b,cblack;,b,cblack;,b,cblack;,c000000126,cblack;,b,cblack;,c000000126,cblack;,b,cblack;,b,cblack;,c000000126,cblack;,b,cblack;,c000000126,cblack;,b,cblack;,b,cblack;,c126000000,cblack;,b,cblack;,b,cblack;,b,cblack;,b,cblack;,c126000000,cblack;,b,cblack;,c126000000,cblack;,c000126126,cblack;! !

!TableLayoutProperties methodsFor: 'table defaults' stamp: 'mt 8/21/2019 09:15'!
cellGap
	"ifNil is just for migration of old instances."
	^ cellGap ifNil: [0]!
]style[(7 2 47 2 1 9 6 2 1 1)b,cblack;,c000126126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;! !


!TextMorph methodsFor: 'accessing' stamp: 'mt 8/10/2019 12:38'!
isAutoFit

	^ autoFit ifNil: [autoFit := true]!
]style[(9 3 1 9 6 10 2 1 4 1)b,cblack;,c126000000,cblack;,c000000126,cblack;,b,cblack;,c126000000,cblack;! !

!TextMorph methodsFor: 'editing' stamp: 'mt 8/10/2019 11:34'!
handleInteraction: interactionBlock fromEvent: evt
	"Perform the changes in interactionBlock, noting any change in selection
	and possibly a change in the size of the paragraph (ar 9/22/2001 - added for TextPrintIts)"

	| oldEditor oldParagraph oldText oldSelection |
	oldEditor := editor.
	oldParagraph := paragraph.
	oldText := oldParagraph text copy.
	oldSelection := oldParagraph selectionRects. "already copy"

	"Note old selection."
	self selectionChanged: oldSelection.
	
	interactionBlock value.

	(oldParagraph == paragraph) ifTrue:[
		"this will not work if the paragraph changed"
		editor := oldEditor.     "since it may have been changed while in block"
	].
	
	"Note new selection."
	paragraph selectionRects in: [:newSelection |
		newSelection ~= oldSelection ifTrue: [
			self selectionChanged: newSelection]].
		
	(oldText = paragraph text and: [ oldText runs = paragraph text runs ])
		ifFalse:[ 
			self paragraph composeAll.
			self updateFromParagraph ].
	self setCompositionWindow.!
]style[(18 1 16 1 10 1 3 2 165 3 1 1 9 1 12 1 7 1 12 1 1 2 9 1 2 10 12 1 2 13 7 1 2 1 12 1 4 1 4 3 12 1 2 1 12 1 14 2 14 3 21 2 4 1 17 1 12 5 16 1 5 5 12 1 2 12 7 4 45 10 2 1 9 6 47 8 21 12 14 1 3 3 12 1 1 3 12 1 2 1 12 1 7 1 1 4 4 1 17 1 12 1 8 7 1 1 11 4 1 4 1 1 1 7 1 4 1 1 11 4 1 4 1 1 4 8 6 4 1 9 1 10 5 4 1 19 5 4 1 20 1)b,cblack;,c000000126,cblack;,b,cblack;,c000000126,cblack;,c000126126,cblack;,cgray;,cblack;,c106106106,cblack;,c106106106,cblack;,c106106106,cblack;,c106106106,cblack;,cgray;,cblack;,c106106106,cblack;,b,cblack;,c106106106,cblack;,b,cblack;,c106106106,cblack;,b,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,b,cblack;,c106106106,cblack;,c000000126,cblack;,c000126126,cblack;,c000126126,cblack;,c126000000,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000126126,cblack;,b,cblack;,c106106106,cblack;,c000126126,cblack;,c000126126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,cgray;,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000126000,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,c000126000,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;! !

!TextMorph methodsFor: 'geometry' stamp: 'mt 8/11/2019 16:12'!
extent: aPoint 
	| newExtent priorEditor |
	bounds extent = aPoint ifTrue: [^ self].
	priorEditor := editor.
	self isAutoFit
		ifTrue: [wrapFlag ifFalse: [^ self].  "full autofit can't change"
				newExtent := aPoint truncated.
				newExtent x = self extent x ifTrue: [^ self].  "No change of wrap width"
				self releaseParagraphReally.  "invalidate the paragraph cache"
				super extent: newExtent.
				priorEditor
					ifNil: [self fit]  "since the width has changed..."
					ifNotNil: [self installEditorToReplace: priorEditor]]
		ifFalse: [super extent: aPoint truncated.
				wrapFlag ifFalse: [^ self].  "no effect on composition"
				self composeToBounds]
! !

!TextMorph methodsFor: 'layout' stamp: 'mt 8/20/2019 14:10'!
doLayoutIn: layoutBounds
	"Compute paragraph here to reduce visual flickering. Also update the layout of any submorphs, which can be added via text anchors.
	
	autoFit + wrapFlag -> hResizing: #rigid + vResizing: #shrinkWrap
	autoFIt + no wrapFlag -> hResizing: #shrinkWrap + vResizing: #shrinkWrap
	no autoFit + wrapFlag -> hResizing: #rigid + vRresizing: #rigid
	no autoFit + no wrapFlag -> hResizing: #rigid + vRresizing: #rigid"
	
	self submorphsDo: [:m | m fullBounds].	
	self paragraph.
	fullBounds := self privateFullBounds.!
]style[(11 1 12 2 406 4 4 1 12 3 1 1 1 1 1 1 10 5 4 1 9 14 2 1 4 1 17 1)b,cblack;,c000000126,cblack;,c000126126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,cgray;,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;! !

!TextMorph methodsFor: 'layout' stamp: 'mt 8/12/2019 11:34'!
layoutExtent: aPoint
	"Overwrite to resize and recompose paragraph. There might be redundant #changed and #layoutChanged calls involved, which is okay because our owner has not yet computed its layout."

	"self assert: self owner layoutComputed not."
	self extent: aPoint.!
]style[(13 1 6 2 180 3 45 2 4 1 7 1 6 1)b,cblack;,c000000126,cblack;,c000126126,cblack;,c000126126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;! !

!TextMorph methodsFor: 'layout' stamp: 'mt 8/20/2019 13:49'!
minHeight

	| result |
	"Layout specific. If either height or width are shrink-wrapping, we have to leave the other dimension as is. Otherwise, those results would be incorrect. Note that you can still set #extent: so smaller values to recompute the paragraph."
	self vResizing == #shrinkWrap
		ifTrue: [self fullBounds. ^ self height].
	
	textStyle ifNil: [^ 16].

	result := (textStyle lineGrid + 2) + (self borderWidth*2).
	margins ifNil: [^ result].
	
	^ margins isRectangle
		ifTrue: [result + margins top + margins bottom]
		ifFalse: [margins isPoint
			ifTrue: [result + margins y + margins y]
			ifFalse: [result + (2*margins)]]!
]style[(9 3 1 1 6 1 1 2 237 2 4 1 9 1 2 1 11 3 7 2 4 1 10 2 1 1 4 1 6 16 6 2 1 1 2 5 6 1 2 12 8 1 1 1 1 2 1 2 4 1 12 1 12 6 2 1 1 6 6 1 9 11 3 7 2 6 1 1 9 3 1 1 9 6 4 8 10 7 4 7 1 1 6 1 1 9 1 1 1 9 1 1 4 8 1 1 6 1 1 1 1 1 1 7 1 1 1)b,cblack;,cgray;,cblack;,c106106106,cblack;,cgray;,cblack;,c000126126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c126000000,cblack;,c106106106,cblack;,b,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c106106106,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,c000126000,cblack;,c000000126,cblack;,c000126000,c106106106,cblack;,c000000126,cblack;,c126000126,c126000000,c000000126,cblack;,c126000126,c000126000,cblack;! !

!TextMorph methodsFor: 'layout' stamp: 'mt 8/20/2019 13:49'!
minWidth

	| result |
	"Layout specific. If either height or width are shrink-wrapping, we have to leave the other dimension as is. Otherwise, those results would be incorrect. Note that you can still set #extent: so smaller values to recompute the paragraph."
	self hResizing == #shrinkWrap
		ifTrue: [self fullBounds. ^ self width].

	textStyle ifNil: [^ 9].

	result := 9 + (self borderWidth*2).
	margins ifNil: [^ result].
	
	^ margins isRectangle
		ifTrue: [result + margins left + margins right]
		ifFalse: [margins isPoint
			ifTrue: [result + margins x + margins x]
			ifFalse: [result + (2*margins)]]!
]style[(8 3 1 1 6 1 1 2 237 2 4 1 9 1 2 1 11 3 7 2 4 1 10 2 1 1 4 1 5 15 6 2 1 1 1 5 6 1 2 1 1 1 1 2 4 1 12 1 12 6 2 1 1 6 6 1 9 11 3 7 2 6 1 1 9 4 1 1 9 5 4 8 10 7 4 7 1 1 6 1 1 9 1 1 1 9 1 1 4 8 1 1 6 1 1 1 1 1 1 7 1 1 1)b,cblack;,cgray;,cblack;,c106106106,cblack;,cgray;,cblack;,c000126126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c126000000,cblack;,c106106106,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c106106106,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,c000126000,cblack;,c000000126,cblack;,c000126000,c106106106,cblack;,c000000126,cblack;,c126000126,c126000000,c000000126,cblack;,c126000126,c000126000,cblack;! !

!TextMorph methodsFor: 'private' stamp: 'mt 8/9/2019 18:01'!
fit
	"Adjust my bounds to fit the text.  Should be a no-op if autoFit is not specified.
	Required after the text changes,
	or if wrapFlag is true and the user attempts to change the extent."

	| newExtent para cBounds lastOfLines heightOfLast |
	self isAutoFit 
		ifTrue: 
			[
			newExtent := self paragraph extent max: 1 @ self defaultLineHeight.
			newExtent := newExtent + (2 * self borderWidth).
			margins 
				ifNotNil: [newExtent := ((0 @ 0 extent: newExtent) expandBy: margins) extent].
			newExtent ~= bounds extent 
				ifTrue: 
					[(container isNil and: [successor isNil]) 
						ifTrue: 
							[para := paragraph.	"Save para (layoutChanged smashes it)"
							super extent: newExtent.
							paragraph := para]].
			container notNil & successor isNil 
				ifTrue: 
					[cBounds := container bounds truncated.
					"23 sept 2000 - try to allow vertical growth"
					lastOfLines := self paragraph lines last.
					heightOfLast := lastOfLines bottom - lastOfLines top.
					(lastOfLines last < text size 
						and: [lastOfLines bottom + heightOfLast >= self bottom]) 
							ifTrue: 
								[container releaseCachedState.
								cBounds := cBounds origin corner: cBounds corner + (0 @ heightOfLast)].
					self privateBounds: cBounds]].

	"These statements should be pushed back into senders"
	self paragraph positionWhenComposed: self position.
	successor ifNotNil: [successor predecessorChanged].
	self changed	"Too conservative: only paragraph composition
					should cause invalidation."! !

!TextMorph methodsFor: 'private' stamp: 'mt 8/10/2019 11:39'!
selectionChanged
	
	self selectionChanged: self paragraph selectionRects.!
]style[(16 4 4 1 17 1 4 1 9 1 14 1)b,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;! !

!TextMorph methodsFor: 'private' stamp: 'mt 8/12/2019 13:20'!
selectionChanged: rects
	"Invalidate all the selection rectangles. By using either fullBounds or outerBounds, we make sure that any drop shadow is accounted for too."
	
	| myBounds |
	rects ifEmpty: [^ self].
	myBounds := fullBounds ifNil: [self outerBounds].
	rects do: [:r | self invalidRect: (r intersect: myBounds)].! !

!TextMorph methodsFor: 'private' stamp: 'mt 8/12/2019 10:11'!
updateFromParagraph
	"A change has taken place in my paragraph, as a result of editing and I must be updated.  If a line break causes recomposition of the current paragraph, or it the selection has entered a different paragraph, then the current editor will be released, and must be reinstalled with the resulting new paragraph, while retaining any editor state, such as selection, undo state, and current typing emphasis."

	| newStyle sel oldLast oldEditor back |
	paragraph ifNil: [^self].
	wrapFlag ifNil: [wrapFlag := true].
	editor ifNotNil: 
			[oldEditor := editor.
			sel := editor selectionInterval.
			editor storeSelectionInParagraph].
	text := paragraph text.
	paragraph textStyle = textStyle 
		ifTrue: [self fit]
		ifFalse: 
			["Broadcast style changes to all morphs"

			newStyle := paragraph textStyle.
			(self firstInChain text: text textStyle: newStyle) recomposeChain.
			editor ifNotNil: [self installEditorToReplace: editor]].
	
	(self isAutoFit and: [self isWrapped not])
		ifTrue: [self extent: self paragraph extent; composeToBounds]
		ifFalse: [self layoutChanged].
	sel ifNil: [^self].

	"If selection is in top line, then recompose predecessor for possible ripple-back"
	predecessor ifNotNil: 
			[sel first <= (self paragraph lines first last + 1) 
				ifTrue: 
					[oldLast := predecessor lastCharacterIndex.
					predecessor paragraph 
						recomposeFrom: oldLast
						to: text size
						delta: 0.
					oldLast = predecessor lastCharacterIndex 
						ifFalse: 
							[predecessor changed.	"really only last line"
							self predecessorChanged]]].
	((back := predecessor notNil 
				and: [sel first <= self paragraph firstCharacterIndex]) or: 
				[successor notNil 
					and: [sel first > (self paragraph lastCharacterIndex + 1)]]) 
		ifTrue: 
			["The selection is no longer inside this paragraph.
		Pass focus to the paragraph that should be in control."

			back ifTrue: [predecessor recomposeChain] ifFalse: [self recomposeChain].
			self firstInChain withSuccessorsDo: 
					[:m | 
					(sel first between: m firstCharacterIndex and: m lastCharacterIndex + 1) 
						ifTrue: 
							[m installEditorToReplace: oldEditor.
							^self passKeyboardFocusTo: m]].
			self error: 'Inconsistency in text editor'	"Must be somewhere in the successor chain"].
	editor ifNil: 
			["Reinstate selection after, eg, style change"

			self installEditorToReplace: oldEditor].
	"self setCompositionWindow."
!
]style[(19 2 402 3 1 1 8 1 3 1 7 1 9 1 4 1 1 12 6 2 5 13 6 11 2 1 4 11 9 6 9 1 2 12 3 1 2 8 17 12 25 9 2 11 4 13 9 1 1 14 7 2 4 1 3 4 8 6 39 5 8 1 2 11 9 5 1 4 1 12 1 5 6 10 1 8 1 1 14 12 9 1 1 4 1 23 7 1 7 4 1 9 1 4 1 1 4 1 9 1 3 1 4 7 2 4 1 7 1 4 1 9 1 6 2 15 4 8 2 4 1 13 4 3 1 6 2 5 5 82 14 9 6 3 1 5 1 2 1 1 4 1 9 1 5 1 5 1 4 1 1 1 1 1 6 7 7 1 7 1 2 13 18 19 9 8 14 1 7 7 3 6 4 7 6 1 1 7 7 1 1 13 18 8 8 9 1 12 7 2 23 8 4 1 18 1 1 5 1 4 1 2 13 6 6 4 1 1 3 1 5 1 2 1 4 1 9 1 19 1 1 1 3 6 1 10 6 7 4 1 1 3 1 5 1 1 1 5 1 9 1 18 1 1 1 2 1 1 5 7 6 108 5 4 1 7 1 1 12 14 1 1 8 1 1 4 1 14 1 5 4 1 12 1 17 7 1 1 1 1 1 7 1 3 1 5 1 8 1 1 1 19 1 4 1 1 1 18 1 1 1 1 1 8 7 9 1 1 1 23 1 9 9 5 1 20 1 1 1 1 5 4 1 6 1 30 1 42 11 6 6 45 5 4 1 23 1 9 4 28 1)b,cblack;,c000125125,cblack;,cgray;,cblack;,c105105105,cblack;,c105105105,cblack;,c105105105,cblack;,c105105105,cblack;,c105105105,cblack;,cgray;,cblack;,c000000125,cblack;,c125000000,cblack;,c000000125,cblack;,b,cblack;,c125000000,cblack;,c000000125,cblack;,c105105105,cblack;,b,cblack;,c105105105,cblack;,b,cblack;,c000000125,cblack;,c000000125,cblack;,b,cblack;,c000000125,cblack;,c000000125,cblack;,c000000125,cblack;,c000000125,cblack;,c125000000,cblack;,c000000125,cblack;,c000000125,cblack;,c000125125,cblack;,c105105105,cblack;,b,cblack;,c000000125,cblack;,c000125000,c125000000,cblack;,c000000125,cblack;,c000000125,cblack;,c000000125,cblack;,c105105105,c000125000,cblack;,c000000125,cblack;,c000000125,cblack;,c000125000,c125000000,cblack;,c000000125,cblack;,c000125000,cblack;,c125000000,cblack;,c000000125,cblack;,c000000125,cblack;,c000125000,c125000000,cblack;,c000000125,cblack;,c000000125,c000125000,cblack;,c000000125,cblack;,c125000000,cblack;,c000000125,cblack;,c125000000,cblack;,c000000125,cblack;,c000000125,cblack;,c000000125,cblack;,c000000125,cblack;,c125000000,cblack;,c000000125,cblack;,c105105105,cblack;,c000000125,cblack;,c125000000,cblack;,c000125125,cblack;,c000000125,cblack;,c105105105,cblack;,c000000125,cblack;,c000000125,cblack;,c000125000,c125000000,cblack;,c000000125,cblack;,c000000125,cblack;,c000000125,cblack;,c000000125,cblack;,c000000125,cblack;,c125000000,c000125000,cblack;,c000000125,cblack;,c000125000,c105105105,cblack;,b,cblack;,c000000125,cblack;,c000000125,cblack;,c000000125,cblack;,c105105105,cblack;,c000000125,cblack;,c000000125,cblack;,c000000125,cblack;,c125000000,cblack;,c105105105,cblack;,c000000125,cblack;,c000000125,cblack;,c000000125,cblack;,c125000125,cblack;,c000000125,cblack;,c000125125,cblack;,c125000000,cblack;,c000000125,c125000125,c000125000,cblack;,c000125000,c105105105,cblack;,b,cblack;,c000000125,cblack;,c000000125,cblack;,c125000125,c105105105,cblack;,c000000125,cblack;,c000000125,cblack;,c125000000,cblack;,c000000125,cblack;,c000000125,c125000125,c000125000,cblack;,c000000125,cblack;,c000125000,cblack;,c000000125,cblack;,c000000125,cblack;,c125000125,c105105105,cblack;,c000000125,cblack;,c000000125,cblack;,c125000000,cblack;,c000000125,cblack;,c000000125,cblack;,c000000125,cblack;,c125000000,c125000125,c000125000,cblack;,c000000125,cblack;,c000125125,cblack;,c105105105,cblack;,c000000125,cblack;,c000125000,cblack;,c000000125,c000125000,cblack;,c000000125,cblack;,c000125000,c125000000,cblack;,c000000125,c000125000,cblack;,c125000000,cblack;,c000000125,cblack;,c000000125,cblack;,c000125000,cblack;,c000000125,cblack;,cgray;,cblack;,c125000125,c105105105,cblack;,c000000125,cblack;,c000000125,cblack;,c000000125,cblack;,c000000125,cblack;,c000000125,cblack;,c000000125,cblack;,c000000125,cblack;,c000000125,cblack;,c125000000,c125000125,cblack;,c000000125,cblack;,c125000125,c000000125,cblack;,c000000125,cblack;,c105105105,cblack;,c125000000,cblack;,c000000125,cblack;,c000000125,c125000125,c000125000,cblack;,c125000000,cblack;,c000000125,cblack;,c125000125n,cblack;,c000125125,cblack;,c000000125,cblack;,c000125125,cblack;,c125000000,cblack;,c000000125,cblack;,c105105105,cblack;,c000125125,cblack;! !

!TextMorph methodsFor: 'layout-properties' stamp: 'mt 8/11/2019 16:01'!
hResizing

	self layoutProperties ifNotNil: [:props |
		^ props hResizing].
	
	(self isAutoFit and: [self isWrapped])
		ifTrue: [^ #rigid]. "or #spaceFill"
	(self isAutoFit and: [self isWrapped not])
		ifTrue: [^ #shrinkWrap].
	(self isAutoFit not and: [self isWrapped])
		ifTrue: [^ #rigid]. "or #spaceFill"
	(self isAutoFit not and: [self isWrapped not])
		ifTrue: [^ #rigid]. "or #spaceFill"!
]style[(9 3 4 1 16 1 9 3 5 1 1 3 1 1 5 1 9 7 4 1 9 1 4 1 1 4 1 9 1 4 7 2 1 1 6 3 15 3 4 1 9 1 4 1 1 4 1 9 1 3 1 4 7 2 1 1 11 5 4 1 9 1 3 1 4 1 1 4 1 9 1 4 7 2 1 1 6 3 15 3 4 1 9 1 3 1 4 1 1 4 1 9 1 3 1 4 7 2 1 1 6 3 15)b,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,cgray;,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c126000000,cblack;,c000000126,c000126000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000126126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c126000000,cblack;,c000000126,cblack;,c000000126,c000126000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c126000000,cblack;,c000000126,c000126000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000126126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c126000000,cblack;,c000000126,cblack;,c000000126,c000126000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000126126! !

!TextMorph methodsFor: 'layout-properties' stamp: 'mt 8/12/2019 10:13'!
hResizing: aSymbol

	super hResizing: aSymbol.
	
	aSymbol == #shrinkWrap
		ifTrue: [self autoFit: true; wrapFlag: false];
		ifFalse: ["#rigid or #spaceFill -- Prefer to not cut out text."
			self autoFit: self vResizing == #shrinkWrap; wrapFlag: true].

	self releaseParagraph.!
]style[(10 1 7 3 5 1 10 1 7 5 7 1 2 1 11 3 7 2 4 1 8 1 4 2 9 1 5 5 8 2 53 4 4 1 8 1 4 1 9 1 2 1 11 2 9 1 4 5 4 1 16 1)b,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000126126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c126000000,cblack;,c000000126,cblack;! !

!TextMorph methodsFor: 'layout-properties' stamp: 'mt 8/11/2019 16:03'!
vResizing

	self layoutProperties ifNotNil: [:props |
		^ props vResizing].
	
	(self isAutoFit and: [self isWrapped])
		ifTrue: [^ #shrinkWrap]. 
	(self isAutoFit and: [self isWrapped not])
		ifTrue: [^ #shrinkWrap].
	(self isAutoFit not and: [self isWrapped])
		ifTrue: [^ #rigid]. "or #spaceFill"
	(self isAutoFit not and: [self isWrapped not])
		ifTrue: [^ #rigid]. "or #spaceFill"!
]style[(9 3 4 1 16 1 9 3 5 1 1 3 1 1 5 1 9 7 4 1 9 1 4 1 1 4 1 9 1 4 7 2 1 1 11 6 4 1 9 1 4 1 1 4 1 9 1 3 1 4 7 2 1 1 11 5 4 1 9 1 3 1 4 1 1 4 1 9 1 4 7 2 1 1 6 3 15 3 4 1 9 1 3 1 4 1 1 4 1 9 1 3 1 4 7 2 1 1 6 3 15)b,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,cgray;,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c126000000,cblack;,c000000126,c000126000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c126000000,cblack;,c000000126,cblack;,c000000126,c000126000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c126000000,cblack;,c000000126,c000126000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000126126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c126000000,cblack;,c000000126,cblack;,c000000126,c000126000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000126126! !

!TextMorph methodsFor: 'layout-properties' stamp: 'mt 8/12/2019 10:13'!
vResizing: aSymbol

	super vResizing: aSymbol.
	
	self autoFit: aSymbol == #shrinkWrap.

	 self wrapDirection: (aSymbol == #shrinkWrap
		ifTrue: [#topToBottom]
		ifFalse: [#none]).
		
	self releaseParagraph.!
]style[(10 1 7 3 5 1 10 1 7 5 4 1 8 1 7 1 2 1 11 5 4 1 14 2 7 1 2 1 11 3 7 1 1 12 1 3 8 1 1 5 1 7 4 1 16 1)b,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c000000126,c000126000,cblack;,c000000126,cblack;,c000126000,c000000126,c000126000,cblack;,c126000000,cblack;,c000000126,cblack;! !

!TextMorph methodsFor: 'layout-properties' stamp: 'mt 8/12/2019 09:39'!
wrapDirection

	self layoutProperties ifNotNil: [:props |
		^ props wrapDirection].
	
	^ self vResizing == #shrinkWrap
		ifTrue: [#topToBottom]
		ifFalse: [#none]!
]style[(13 3 4 1 16 1 9 3 5 1 1 3 1 1 5 1 13 6 1 1 4 1 9 1 2 1 11 3 7 2 12 4 8 2 5 1)b,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,cgray;,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;! !


!TransferMorph methodsFor: 'initialization' stamp: 'mt 8/21/2019 13:41'!
initialize

	super initialize.

	self
		changeTableLayout;
		listDirection: #leftToRight;
		hResizing: #shrinkWrap;
		vResizing: #shrinkWrap;
		layoutInset: 3;
		cellGap: 3;
		wrapCentering: #center;
		cellPositioning: #leftCenter;
		setProperty: #indicateKeyboardFocus toValue: #never.
	
	self doMove.
	
	self on: #keyStroke send: #keyStroke: to: self.
	self on: #keyUp send: #updateFromUserInputEvent: to: self.
	self on: #keyDown send: #updateFromUserInputEvent: to: self.

	self setDefaultParameters.!
]style[(10 3 5 1 10 4 4 3 17 4 14 1 12 4 10 1 11 4 10 1 11 4 12 1 1 4 8 1 1 4 14 1 7 4 16 1 11 4 12 1 22 1 8 1 6 5 4 1 6 5 4 1 3 1 10 1 5 1 11 1 3 1 4 3 4 1 3 1 6 1 5 1 26 1 3 1 4 3 4 1 3 1 8 1 5 1 26 1 3 1 4 4 4 1 20 1)b,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c126000000,cblack;,c000000126,cblack;! !


!TransformMorph methodsFor: 'geometry' stamp: 'mt 8/12/2019 18:00'!
layoutChanged

	"A submorph could have moved, thus changing my localBounds. Invalidate the cache."
	localBounds := nil.
	super layoutChanged.! !


!WorldState methodsFor: 'update cycle' stamp: 'mt 8/8/2019 11:44'!
displayWorld: aWorld submorphs: submorphs
	"Update this world's display."

	| deferredUpdateMode handsToDraw allDamage handDamageRects worldDamageRects |

	aWorld fullBounds. "send #ownerChanged to submorphs."
	submorphs do: [:m | m fullBounds].  "force re-layout if needed"
	self checkIfUpdateNeeded ifFalse: [^ self].  "display is already up-to-date"

	deferredUpdateMode := self doDeferredUpdatingFor: aWorld.
	deferredUpdateMode ifFalse: [self assuredCanvas].

	worldDamageRects := self drawWorld: aWorld submorphs: submorphs invalidAreasOn: self assuredCanvas.  "repair world's damage on canvas"
	"self handsDo:[:h| h noticeDamageRects: worldDamageRects]."
	handsToDraw := self selectHandsToDrawForDamage: worldDamageRects.
	handDamageRects := handsToDraw collect: [:h | h savePatchFrom: canvas].
	allDamage := worldDamageRects, handDamageRects.

	handsToDraw reverseDo: [:h | canvas fullDrawMorph: h].  "draw hands onto world canvas"

	"*make this true to flash damaged areas for testing*"
	Preferences debugShowDamage ifTrue: [aWorld flashRects: allDamage color: Color black].

	canvas finish: allDamage.

	"quickly copy altered rects of canvas to Display:"
	deferredUpdateMode
		ifTrue: [self forceDamageToScreen: allDamage]
		ifFalse: [canvas showAt: aWorld viewBox origin invalidRects: allDamage].
	handsToDraw do: [:h | h restoreSavedPatchOn: canvas].  "restore world canvas under hands"
	Display deferUpdates: false; forceDisplayUpdate.
! !

TextMorphForEditView removeSelector: #updateFromParagraph!

!TextMorph reorganize!
('accessing' asText autoFit: backgroundColor backgroundColor: borderWidth: contents contentsAsIs: contentsWrapped: contents: contents:wrappedTo: crAction crAction: cursor cursorWrapped: editor elementCount fontName:pointSize: fontName:size: font: getFirstCharacter getLastCharacter hasTranslucentColor isAutoFit isWrapped margins margins: newContents: readOnly readOnly: selectAll selectFrom:to: selection setCharacters: setFirstCharacter: setLastCharacter: text textAlignment textAlignmentSymbol textColor textColor: textStyle userString wrapFlag:)
('alignment' centered justified leftFlush rightFlush)
('anchors' adjustTextAnchor: anchorMorph:at:type:)
('caching' loadCachedState releaseCachedState)
('change reporting' ownerChanged)
('classification' isTextMorph)
('containment' avoidsOcclusions fillingOnOff fillsOwner fillsOwner: occlusionsOnOff recognizerArena setContainer:)
('copying' copy veryDeepFixupWith: veryDeepInner:)
('drawing' areasRemainingToFill: debugDrawLineRectsOn: drawNullTextOn: drawOn:)
('editing' acceptContents acceptOnCR cancelEdits chooseAlignment chooseEmphasis chooseEmphasisOrAlignment chooseFont chooseStyle enterClickableRegion: handleEdit: handleInteraction:fromEvent: hasUnacceptedEdits: passKeyboardFocusTo: preferredKeyboardPosition setCompositionWindow xeqLinkText:withParameter:)
('event handling' click: getMenu: handlesKeyboard: handlesMouseDown: handlesMouseOver: hasFocus keyboardFocusChange: keyStroke: mouseDown: mouseEnter: mouseLeave: mouseMove: mouseUp: startDrag: wantsKeyboardFocus wouldAcceptKeyboardFocusUponTab yellowButtonActivity:)
('events-processing' handleKeystroke: handleMouseMove:)
('geometry' bounds container defaultLineHeight extent: maximumContainerExtent privateMoveBy: textBounds)
('geometry testing' containsPoint:)
('initialization' beAllFont: defaultBorderWidth defaultColor initialize setTextStyle: string:fontName:size: string:fontName:size:wrap:)
('layout' acceptDroppingMorph:event: doLayoutIn: layoutExtent: minHeight minWidth)
('linked frames' addPredecessor: addSuccessor: firstCharacterIndex firstInChain isLinkedTo: lastCharacterIndex predecessor recomposeChain startingIndex successor withSuccessorsDo:)
('menu' addCustomMenuItems:hand: autoFitOnOff autoFitString changeMargins: changeTextColor followCurve holderForCharacters reverseCurveDirection setCurveBaseline: wrapOnOff wrapString)
('multi level undo' editHistory)
('objects from disk' convertToCurrentVersion:refStream: fixUponLoad:seg:)
('scripting access' getAllButFirstCharacter insertCharacters: insertContentsOf: setAllButFirstCharacter:)
('submorphs-add/remove' addMorphFront:fromWorldPosition: delete goBehind)
('visual properties' fillStyle fillStyle:)
('*MorphicExtras-accessing' getCharacters)
('*MorphicExtras-copying' updateReferencesUsing:)
('*MorphicExtras-printing' fullPrintOn:)
('private' adjustLineIndicesBy: clippingRectangle composeToBounds compositionRectangle createParagraph editorClass fit installEditorToReplace: paragraph paragraphClass predecessorChanged predecessor:successor: privateOwner: releaseEditor releaseParagraph releaseParagraphReally removedMorph: selectionChanged selectionChanged: setDefaultContentsIfNil setPredecessor: setSuccessor: text:textStyle: text:textStyle:wrap:color:predecessor:successor: updateFromParagraph)
('blinking' blinkStart blinkStart: onBlinkCursor resetBlinkCursor startBlinking stopBlinking)
('*eToys-tiles' basicType)
('*Etoys-support' configureForKids getNumericValue setNumericValue: usePango usePango:)
('*Etoys-card in a stack' couldHoldSeparateDataForEachInstance newContents:fromCard: setNewContentsFrom:)
('*Etoys-player' currentDataValue variableDocks)
('*Etoys-Squeakland-menus' addFitAndWrapItemsTo: addTextMenuItemsTo:event:)
('*Etoys-Squeakland-localization' addTranslationItemsTo: setLocale: toggleTranslatable translatable translatable: translatableString translations)
('*Etoys-Squeakland-scripting access' appendCharacters:)
('*Etoys-Squeakland-menu' changeColorSimply changeTextColorSimply promptForFont)
('*Etoys-Squeakland-accessing' crPassesFocus crPassesFocus: highlightsOnFocus highlightsOnFocus: restoreText:)
('*Etoys-Squeakland-drop outside' mimeTypes)
('*Etoys-Squeakland-property sheet' openAppropriatePropertySheet)
('*Etoys-Squeakland-private' selectionColor selectionColor:)
('layout-properties' hResizing hResizing: vResizing vResizing: wrapDirection)
!

LayoutProperties subclass: #TableLayoutProperties
	instanceVariableNames: 'cellInset cellPositioning cellSpacing cellGap layoutInset listCentering listDirection listSpacing reverseTableCells rubberBandCells wrapCentering wrapDirection minCellSize maxCellSize'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'Morphic-Layouts'!
ScrollPane removeSelector: #borderStyle:!
ScrollPane removeSelector: #borderWidth:!
ScrollPane removeSelector: #extent:!
ScrollPane removeSelector: #handleResizeAction:!

!ScrollPane reorganize!
('accessing' adoptPaneColor: flatColoredScrollBarLook hMargin hScrollBar hScrollBarPolicy hScrollBarPolicy: hasFocus insetColor isAutoFit numSelectionsInView raisedColor scrollBarOnLeft scrollBarOnLeft: scrollBarThickness scrollBarThickness: scroller scroller: vScrollBar vScrollBarPolicy vScrollBarPolicy: wantsSlot)
('event handling' handlesKeyboard: handlesMouseDown: handlesMouseOver: handlesMouseWheel: keyStroke: mouseDown: mouseEnter: mouseLeave: mouseMove: mouseUp: mouseWheel: scrollByKeyboard: wantsKeyboardFocus)
('geometry' extentToFit fit hResizeScrollBar hScrollBarWidth hSetScrollDelta innerBounds resetExtent resizeScrollBars resizeScroller scrollDeltaHeight scrollDeltaWidth setScrollDeltas vResizeScrollBar vScrollBarHeight vSetScrollDelta)
('geometry testing' containsPoint: hIsScrollable hIsScrollbarShowing hIsScrolled isAnyScrollbarShowing vIsScrollable vIsScrollbarShowing vIsScrolled)
('initialization' defaultExtent initialize initializePreferences initializeScrollBars setDefaultParameters)
('menu' addCustomMenuItems:hand: getMenu: leftOrRight menuTitleSelector: wantsYellowButtonMenu)
('scroll bar events' hScrollBarMenuButtonPressed: scrollBarMenuButtonPressed: shiftedTextPaneMenuRequest shiftedYellowButtonActivity unshiftedYellowButtonActivity vScrollBarMenuButtonPressed: yellowButtonActivity:)
('scrolling' adjustOffset hHideOrShowScrollBar hHideScrollBar hIsScrollbarNeeded hideOrShowScrollBars hideScrollBars hScrollBarValue: hShowScrollBar offsetToShow: scrollBy: scrollToBottom scrollToLeft scrollToRight scrollToShow: scrollToTop showScrollBars vHideOrShowScrollBar vHideScrollBar vIsScrollbarNeeded vScrollBarValue: vShowScrollBar)
('layout' doLayoutIn: layoutChanged minScrollbarHeight minScrollbarWidth updateMinimumExtent)
('accessing options' alwaysShowHScrollBar alwaysShowScrollBars alwaysShowVScrollBar hideHScrollBarIndefinitely hideScrollBarsIndefinitely hideVScrollBarIndefinitely showHScrollBarOnlyWhenNeeded showScrollBarsOnlyWhenNeeded showVScrollBarOnlyWhenNeeded)
('support' canBeEncroached isScrolledFromTop scrollBarFills:)
('geometry ranges' hExtraScrollRange hLeftoverScrollRange hTotalScrollRange hUnadjustedScrollRange vExtraScrollRange vLeftoverScrollRange vTotalScrollRange vUnadjustedScrollRange)
('accessing retractable' retractable: retractableOrNot retractableScrollBar)
('*46Deprecated' alwaysShowHScrollBar: alwaysShowScrollBars: alwaysShowVScrollBar: hideHScrollBarIndefinitely: hideScrollBarsIndefinitely: hideVScrollBarIndefinitely: isAScrollbarShowing showHScrollBarOnlyWhenNeeded: showScrollBarsOnlyWhenNeeded: showVScrollBarOnlyWhenNeeded:)
('event filtering' filterEvent:for:)
('updating' applyUserInterfaceTheme)
('*Etoys-Squeakland-menu' hideMenuButton showMenuButton)
('*Etoys-Squeakland-access' scrollHorizontallyToShow:)
('drawing' drawOn: drawOverlayOn:)
('objects from disk' convertToCurrentVersion:refStream:)
('change reporting')
!


!LayoutProperties reorganize!
('accessing' disableLayout disableLayout: disableTableLayout disableTableLayout: hResizing hResizing: vResizing vResizing:)
('converting' asTableLayoutProperties)
('initialize' initialize initializeFrom:)
('table defaults' cellGap cellInset cellPositioning cellSpacing layoutInset listCentering listDirection listSpacing maxCellSize minCellSize reverseTableCells rubberBandCells stringWithLayout wrapCentering wrapDirection)
('testing' includesTableProperties)
('printing' printOn:)
!

"Convert all cell insets to cell gaps."
TableLayoutProperties allInstancesDo: [:ea |
	ea cellInset isZero ifFalse: [
		ea
			cellGap: (ea cellInset isRectangle ifTrue: [ea cellInset topLeft] ifFalse: [ea cellInset]);
			cellInset: 0]].!

