'From Squeak5.3alpha of 7 August 2019 [latest update: #18738] on 12 August 2019 at 6:23:47 pm'!
Warning subclass: #MorphicLayoutWarning
	instanceVariableNames: ''
	classVariableNames: ''
	poolDictionaries: ''
	category: 'Morphic-Layouts'!

!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: 'printing' stamp: 'mt 8/12/2019 15:42'!
printOn: stream

	stream
		print: self class; cr; cr;
		nextPutAll: 'hResizing: '; store: self hResizing; cr;
		nextPutAll: 'vResizing: '; store: self vResizing; cr; cr;

		nextPutAll: 'listDirection: '; store: self listDirection; cr;
		nextPutAll: 'cellPositioning: '; store: self cellPositioning; cr; cr;

		nextPutAll: 'layoutInset: '; store: self layoutInset; cr;
		nextPutAll: 'cellInset: '; store: self cellInset; cr; cr;
		
		nextPutAll: 'wrapDirection: '; store: self wrapDirection; cr;
		nextPutAll: 'listCentering: '; store: self listCentering; cr; cr;
		
		nextPutAll: 'listSpacing: '; store: self listSpacing; cr;
		nextPutAll: 'cellSpacing: '; store: self cellSpacing; cr;
		nextPutAll: 'wrapCentering: '; store: self wrapCentering.!
]style[(8 1 6 3 6 3 6 1 4 1 5 2 2 2 2 4 11 1 13 2 6 1 4 1 9 2 2 4 11 1 13 2 6 1 4 1 9 2 2 2 2 5 11 1 17 2 6 1 4 1 13 2 2 4 11 1 19 2 6 1 4 1 15 2 2 2 2 5 11 1 15 2 6 1 4 1 11 2 2 4 11 1 13 2 6 1 4 1 9 2 2 2 2 7 11 1 17 2 6 1 4 1 13 2 2 4 11 1 17 2 6 1 4 1 13 2 2 2 2 7 11 1 15 2 6 1 4 1 11 2 2 4 11 1 15 2 6 1 4 1 11 2 2 4 11 1 17 2 6 1 4 1 13 1)b,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126n,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126n,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126n,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126n,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126n,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126n,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126n,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126n,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126n,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126n,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126n,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;! !


!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/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!
]style[(8 1 8 3 57 13 5 1 4 1 8 1 2 7 2 1 1 4 4 4 1 7 1 2 1 8 1 7 2 1 1 4 6 4 1 7 3 4 1 15 1 8 1 8 3 4 1 7)b,cblack;,c000000126,cblack;,c000126126,cblack;,c000000126,cblack;,c000000126,c000126000,c000000126,c000126000,cblack;,c000000126,cblack;,c126000000,cblack;,c126000000,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c126000000,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126! !

!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/9/2019 13:55'!
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.
	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.

	"Re-computation needed?"
	"Another run needed for shrink-wrapping the space-fills."
	"myBox ~= box ifTrue: [
		| any |
		any := false.
		self setProperty: #lastBox toValue: myBox.
		self submorphsDo: [:m |
			(m hResizing == #spaceFill or: [m vResizing == #spaceFill])
				ifTrue: [any := true. m layoutChanged]].

		any ifTrue: [self doLayoutIn: myBox]]."! !

!Morph methodsFor: 'layout' stamp: 'mt 8/12/2019 17:03'!
doLayoutIn: layoutBounds 
	"Compute a new layout based on the given layout bounds."

	| box priorBounds c |
	"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 | | layoutBoundsToUse |
		
		"1.1) #shrinkWrap with space-fill children is tricky. So reduce cell sizes so that space-fill children can both shrink and expand."
		layoutBoundsToUse := layoutBounds origin extent:
			((self hResizing == #shrinkWrap and: [self wrapDirection = #none]) ifTrue: [1] ifFalse: [layoutBounds width]) @
			((self vResizing == #shrinkWrap and: [self wrapDirection = #none]) ifTrue: [1] ifFalse: [layoutBounds height]).
		
		"1.2) Compute the new layout."
		self removeProperty: #doLayoutAgain.		
		layout layout: self in: layoutBoundsToUse.
		
		"1.3) Do additional runs on the layout if requested in #layoutInBounds:."
		c := 0.
		[c < 5 and: [self hasProperty: #doLayoutAgain]] whileTrue: [
			c := c + 1.
			self removeProperty: #doLayoutAgain.		
			layout flushLayoutCache.
			layout layout: self in: layoutBoundsToUse].
		c = 5 ifTrue: [MorphicLayoutWarning signal: 'Cannot find a stable layout for "', self printString, '".', String cr, String cr, self layoutProperties printString]].
	
	"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)].!
]style[(11 1 12 3 56 3 1 1 3 1 11 1 1 1 1 2 150 2 4 1 12 1 8 2 1 12 2 1 4 1 11 6 198 2 11 1 2 1 4 1 11 4 153 2 4 1 12 1 9 3 6 1 1 1 1 1 17 1 1 6 131 3 17 1 2 1 12 1 6 1 7 4 1 1 4 1 9 1 2 1 11 1 4 1 5 1 13 1 1 1 5 1 1 1 7 1 1 1 1 1 8 1 1 12 1 5 1 1 1 1 4 1 1 4 1 9 1 2 1 11 1 4 1 5 1 13 1 1 1 5 1 1 1 7 1 1 1 1 1 8 1 1 12 1 6 1 1 7 30 3 4 1 15 1 14 6 6 1 7 1 4 1 3 1 17 7 73 3 1 1 2 1 1 4 1 1 1 1 1 1 1 4 1 1 4 1 12 1 14 1 1 1 10 1 1 4 1 1 2 1 1 1 1 1 1 5 4 1 15 1 14 7 6 1 16 5 6 1 7 1 4 1 3 1 17 1 4 1 1 1 1 1 1 7 1 1 21 7 1 35 1 1 4 1 12 1 4 1 8 3 8 3 1 4 1 16 1 11 1 6 159 2 4 1 12 3 1 1 1 1 1 1 12 6 68 2 4 1 18 5 81 13 2 1 4 1 17 5 14 2 3 1 2 1 4 1 11 3 3 1 1 1 11 1 8 5 4 1 12 1 1 11 1 11 1 3 1 2)b,cblack;,c000000126,cblack;,c000126126,cblack;,cgray;,cblack;,c106106106,cblack;,c106106106,cblack;,c106106106,cblack;,cgray;,cblack;,c000126126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c000126126,cblack;,c106106106,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c000126126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,cgray;,cblack;,cgray;,cblack;,cgray;,cblack;,cgray;,cblack;,c000126126,cblack;,cgray;,cblack;,b,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c126000126,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,c126000000,c126000126,cblack;,c000000126,cblack;,c126000126,c126000000,c126000126,cblack;,c000000126,cblack;,c126000126,c000000126,cblack;,c000000126,c126000126,c000126000,cblack;,c000000126,cblack;,c000126000,c126000126,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,c126000000,c126000126,cblack;,c000000126,cblack;,c126000126,c126000000,c126000126,cblack;,c000000126,cblack;,c126000126,c000000126,cblack;,c000000126,c126000126,c000126000,cblack;,c000126126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,cgray;,cblack;,c000126126,cblack;,c106106106,cblack;,b,cblack;,c126000000,cblack;,c000126000,c106106106,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000126,c126000000,cblack;,c000000126,cblack;,c000000126,c126000126,c000126000,cblack;,c000000126,cblack;,c000126000,cblack;,c106106106,cblack;,b,cblack;,c106106106,cblack;,c000000126,cblack;,c126000000,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,cgray;,c000126000,cblack;,c106106106,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000126000,cblack;,c000000126,cblack;,c126000126n,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000126n,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,c000126000,cblack;,c000126126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,cgray;,cblack;,c000000126,cblack;,c000000126,cblack;,c000126126,cblack;,c126000000,cblack;,c000000126,cblack;,c000126126,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c000126126,cblack;,c106106106,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000126000,c106106106,cblack;,c000000126,cblack;,c106106106,c000126000,cblack;! !

!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/8/2019 14:53'!
layoutExtent: aPoint
	"Sets the extent for laying out children of the receiver. We avoid triggering #layoutChanged again. This implementation is based on #extent:."
		
	(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 6 4 1 6 1 8 1 6 2 7 2 1 1 4 5 4 1 12 1 4 1 11 10 2 8 7 1 7 1 6 5 4 1 15 1 11 3 4 1 12 1 4 1 11 1)b,cblack;,c000000126,cblack;,c000126126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c126000000,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,b,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;! !

!Morph methodsFor: 'layout' stamp: 'mt 8/12/2019 11:13'!
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.! !

!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/12/2019 11:09'!
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.

	"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!
]style[(9 2 1034 3 1 1 6 1 9 1 5 1 4 1 4 1 1 2 4 1 2 1 4 1 9 3 4 1 2 1 4 1 9 4 272 3 4 1 2 1 10 1 3 1 1 4 1 2 1 10 1 5 8 2 4 1 10 2 1 1 4 1 6 1 6 5 57 2 6 1 2 1 4 1 12 3 6 1 5 4 7 2 9 1 2 1 1 1 1 4 8 2 9 1 2 1 6 1 12 1 4 1 3 1 4 1 12 5 38 3 4 1 2 1 6 4 7 2 9 1 2 1 4 1 5 1 1 1 9 1 1 4 4 1 2 1 6 4 7 2 9 1 2 1 9 1 1 1 1 1 4 1 6 5 56 2 4 1 2 1 10 3 7 6 1 4 1 2 1 11 1 4 1 1 4 1 13 1 2 1 5 1 1 5 7 1 1 9 1 2 1 1 1 1 1 9 1 1 1 47 1 5 8 1 1 6 5 1 2 1 4 1 6 1 5 1 1 1 4 1 12 1 5 7 9 1 2 1 1 9 1 1 1 1 1 5 1 1 1 1 9 1 1 1 4 4 1 2 1 10 3 7 6 1 4 1 2 1 11 1 4 1 1 4 1 13 1 2 1 5 1 1 5 7 1 1 9 1 2 1 9 1 1 1 1 1 1 1 47 1 5 8 1 1 6 5 1 2 1 4 1 6 1 6 1 1 1 4 1 12 1 6 7 9 1 2 1 9 1 1 1 1 1 1 9 1 1 1 1 1 5 1 1 5 79 3 4 1 2 1 11 1 4 1 1 6 1 6 1 4 7 6 4 1 10 2 49 4 9 1 2 1 4 1 5 1 1 1 9 1 1 5 4 1 2 1 11 1 4 1 1 6 1 6 1 4 7 6 4 1 10 2 50 4 9 1 2 1 9 1 1 1 1 1 4 1 6 5 113 2 1 1 9 1 4 1 4 1 8 1 1 1 4 1 9)b,cblack;,c000126126,cblack;,cgray;,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;,c000126126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c106106106,cblack;,c000000126,cblack;,c000000126,c000126000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000126126,cblack;,c106106106,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,b,cblack;,c126000000,c000000126,c126000000,cblack;,c000000126,cblack;,c106106106,cblack;,b,cblack;,c106106106,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000126126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,b,cblack;,c126000000,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;,c126000000,cblack;,c000000126,cblack;,c000126126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,c126000126,c000126000,cblack;,c000000126,cblack;,c000126000,c106106106,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000126126,c000126000,cblack;,c000000126,cblack;,c000126000,cblack;,c106106106,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,b,cblack;,c126000126,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,c126000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,c000126000,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,c126000126,c000126000,cblack;,c000000126,cblack;,c000126000,c106106106,cblack;,b,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000126126,c000126000,cblack;,c000000126,cblack;,c000126000,cblack;,c106106106,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,b,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,c126000126,c000126000,cblack;,c000126126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c106106106,cblack;,c000000126,c000126000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000126126,cblack;,c106106106,cblack;,b,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000126000,c106106106,cblack;,c000000126,c000126000,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000126126,cblack;,c106106106,cblack;,b,cblack;,c106106106,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000126126,cblack;,c126000000,cblack;,c106106106,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126! !

!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-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;! !


!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/9/2019 17:42'!
createBody

	| body |
	body := Morph new
		name: 'Body';
		changeTableLayout;
		hResizing: #shrinkWrap;
		vResizing: #shrinkWrap;
		listDirection: #topToBottom;
		layoutInset: (10@5 corner: 10@10);
		cellInset: 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 14 1 12 4 12 2 2 1 1 1 7 1 2 1 2 5 10 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;,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/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.!
]style[(12 1 7 3 46 4 1 1 3 1 11 1 10 1 1 2 3 1 2 7 3 3 5 1 6 4 17 4 14 1 12 4 8 16 2 1 7 1 6 1 7 1 4 4 11 1 2 20 3 3 6 7 11 4 7 1 4 4 7 1 2 1 2 4 15 1 13 4 12 1 20 1 10 4 12 1 1 4 13 14 13 4 7 14 13 1 6 4 8 1 4 1 5 1 18 4 8 4 10 1 2 20 3 3 6 7 11 4 7 1 4 4 15 1 16 4 12 1 13 1 10 4 12 1 1 4 13 14 12 4 7 14 12 1 6 4 8 1 4 1 5 1 18 4 8 5 3 1 13 2 11 14 10 6 4 1 13 1 3 3 4 1 18 1)b,cblack;,c000000126,cblack;,c000126126,cblack;,cgray;,cblack;,c106106106,cblack;,c106106106,cblack;,c106106106,cblack;,cgray;,cblack;,c106106106,cblack;,b,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,b,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c106106106,cblack;,b,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c126000000,c000000126,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126n,cblack;,c000000126,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;,c106106106,cblack;,b,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,cblack;,c000000126,cblack;,c126000126n,cblack;,c000000126,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;,c106106106,cblack;,c000000126,cblack;,c106106106,cblack;,c106106106,cblack;,c126000000,cblack;,c000000126,cblack;,c106106106,cblack;,c126000000,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/12/2019 15:45'!
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;
			cellInset: 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 10 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! !


!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;! !


!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;! !


!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/12/2019 14:37'!
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]
			doWhileTrue: [self hasProperty: #doLayoutAgain].
	
	super doLayoutIn: layoutBounds.!
]style[(11 1 12 2 87 5 4 1 15 1 14 3 4 3 16 4 14 4 12 4 15 5 12 2 4 1 12 1 14 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;,c000000126,cblack;,c126000000,cblack;,c000000126,cblack;,c000000126,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;! !


!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/10/2019 12:11'!
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 outerBounds.!
]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 11 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: '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;! !


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

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: hInitScrollBarTEMPORARY 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' cellInset cellPositioning cellSpacing layoutInset listCentering listDirection listSpacing maxCellSize minCellSize reverseTableCells rubberBandCells stringWithLayout wrapCentering wrapDirection)
('testing' includesTableProperties)
('printing' printOn:)
!

