'From Cuis 2.6 of 10 August 2010 [latest update: #540] on 23 August 2010 at 10:35:10 pm'!
!classDefinition: #MorphExtension category: #'Morphic-Kernel'!
Object subclass: #MorphExtension
	instanceVariableNames: 'locked visible sticky balloonText eventHandler otherProperties layoutSpec '
	classVariableNames: ''
	poolDictionaries: ''
	category: 'Morphic-Kernel'!

!LayoutFrame methodsFor: 'testing' stamp: 'jmv 8/23/2010 13:34'!
is: aSymbol
	^ aSymbol = #LayoutFrame or: [ super is: aSymbol ]! !


!MorphExtension methodsFor: 'accessing - basic properties' stamp: 'jmv 8/23/2010 13:35'!
layoutFrame
	^ layoutSpec ifNotNil: [
		(layoutSpec is: #LayoutFrame) ifTrue: [ layoutSpec ]].! !

!MorphExtension methodsFor: 'accessing - basic properties' stamp: 'jmv 8/23/2010 13:31'!
layoutFrame: aLayoutFrame 

	layoutSpec _ aLayoutFrame! !

!MorphExtension methodsFor: 'accessing - optional properties' stamp: 'jmv 8/23/2010 13:38'!
balloonText
	^self valueOfProperty: #balloonText ifAbsent: nil! !

!MorphExtension methodsFor: 'accessing - optional properties' stamp: 'jmv 8/23/2010 13:39'!
balloonText: newValue
	newValue
		ifNil: [ self removeProperty: #balloonText ]
		ifNotNil: [ self setProperty: #balloonText toValue: newValue ]! !

!MorphExtension methodsFor: 'accessing - optional properties' stamp: 'jmv 8/23/2010 13:27'!
locked
	^self valueOfProperty: #locked ifAbsent: [ false ]! !

!MorphExtension methodsFor: 'accessing - optional properties' stamp: 'jmv 8/23/2010 13:27'!
locked: aBoolean
	aBoolean
		ifFalse: [ self removeProperty: #locked ]
		ifTrue: [ self setProperty: #locked toValue: aBoolean ]! !

!MorphExtension methodsFor: 'accessing - optional properties' stamp: 'jmv 8/23/2010 13:13'!
sticky
	^self valueOfProperty: #sticky ifAbsent: [ false ]! !

!MorphExtension methodsFor: 'accessing - optional properties' stamp: 'jmv 8/23/2010 13:14'!
sticky: aBoolean
	aBoolean
		ifFalse: [ self removeProperty: #sticky ]
		ifTrue: [ self setProperty: #sticky toValue: aBoolean ]! !

!MorphExtension methodsFor: 'accessing - optional properties' stamp: 'jmv 8/23/2010 13:16'!
visible
	^self valueOfProperty: #visible ifAbsent: [ true ]! !

!MorphExtension methodsFor: 'accessing - optional properties' stamp: 'jmv 8/23/2010 13:26'!
visible: aBoolean
	aBoolean
		ifTrue: [ self removeProperty: #visible ]
		ifFalse: [ self setProperty: #visible toValue: aBoolean ]! !

!MorphExtension methodsFor: 'accessing - other properties' stamp: 'jmv 8/23/2010 13:10'!
hasProperty: aSymbol
	"Answer whether the receiver has the property named aSymbol"
	| property |
	otherProperties ifNil: [ ^ false ].
	property _ otherProperties
		at: aSymbol
		ifAbsent: nil.
	property ifNil: [ ^ false ].
	property == false ifTrue: [ ^ false ].
	^ true! !

!MorphExtension methodsFor: 'accessing - other properties' stamp: 'jmv 8/23/2010 13:10'!
removeProperty: aSymbol
	"removes the property named aSymbol if it exists"
	otherProperties ifNil: [ ^ self ].
	otherProperties
		removeKey: aSymbol
		ifAbsent: nil.
	otherProperties isEmpty ifTrue: [ otherProperties _ nil ]! !

!MorphExtension methodsFor: 'accessing - other properties' stamp: 'jmv 8/23/2010 13:10'!
valueOfProperty: aSymbol ifAbsent: aBlock
	"if the receiver possesses a property of the given name, answer  
	its value. If not then evaluate aBlock and answer the result of  
	this block evaluation"
	otherProperties ifNil: [ ^ aBlock value ].
	^ otherProperties
		at: aSymbol
		ifAbsent: [ ^ aBlock value ].! !

!MorphExtension methodsFor: 'copying' stamp: 'jmv 8/23/2010 13:36'!
veryDeepInner: deepCopier
	"Copy all of my instance variables. Some need to be not copied at 
	all, but shared. This is special code for the dictionary. See  
	DeepCopier."
	super veryDeepInner: deepCopier.
	eventHandler _ eventHandler veryDeepCopyWith: deepCopier.
	otherProperties ifNotNil: [
		"This copies all of them. If there are some that should not be copied, handle them here.
		See for example how Squeak does it"
		otherProperties _ otherProperties veryDeepCopyWith: deepCopier ].! !

!MorphExtension methodsFor: 'initialization' stamp: 'jmv 8/23/2010 13:27'!
initialize
	"Init all booleans to default values"
! !

!MorphExtension methodsFor: 'objects from disk' stamp: 'jmv 8/23/2010 13:28'!
comeFullyUpOnReload: smartRefStream
	"inst vars have default booplean values."

	^ self! !

!MorphExtension methodsFor: 'other' stamp: 'jmv 8/23/2010 11:53'!
inspectElement
	"Create and schedule an Inspector on the otherProperties and the 
	named properties."
	| key obj |
	key _ (SelectionMenu selections: self sortedPropertyNames) startUpWithCaption: 'Inspect which property?'.
	key ifNil: [ ^ self ].
	obj _ otherProperties
		at: key
		ifAbsent: [ 'nOT a vALuE' ].
	obj = 'nOT a vALuE'
		ifTrue: [ (self perform: key) inspect
			"named properties" ]
		ifFalse: [ obj inspect ].! !

!MorphExtension methodsFor: 'other' stamp: 'jmv 8/23/2010 13:37'!
isDefault
	"Return true if the receiver is a default and can be omitted"
	layoutSpec ifNotNil: [ ^ false ].
	eventHandler ifNotNil: [ ^ false ].
	otherProperties ifNotNil: [
		otherProperties isEmpty ifFalse: [ ^ false ]].
	^ true.! !

!MorphExtension methodsFor: 'printing' stamp: 'jmv 8/23/2010 13:37'!
printOn: aStream
	"Append to the argument, aStream, a sequence of characters that 
	identifies the receiver."
	super printOn: aStream.
	aStream nextPutAll: ' ' , self identityHashPrintString.
	layoutSpec ifNotNil: [ aStream nextPutAll: ' [layoutSpec = ] ' , layoutSpec printString , '] ' ].
	eventHandler ifNotNil: [ aStream nextPutAll: ' [eventHandler = ' , eventHandler printString , '] ' ].
	(otherProperties isNil or: [ otherProperties isEmpty ]) ifTrue: [ ^ self ].
	aStream nextPutAll: ' [other: '.
	otherProperties keysDo: [ :aKey |
		aStream nextPutAll: ' (' , aKey , ' -> ' , (otherProperties at: aKey) printString , ')' ].
	aStream nextPut: $].! !

!MorphExtension methodsFor: 'private' stamp: 'jmv 8/23/2010 13:09'!
assureOtherProperties
	"creates an otherProperties for the receiver if needed"
	otherProperties ifNil: [ otherProperties _ IdentityDictionary new ].
	^ otherProperties! !

!MorphExtension methodsFor: 'private' stamp: 'jmv 8/23/2010 13:38'!
sortedPropertyNames
	"answer the receiver's property names in a sorted way"
	| props |
	props _ WriteStream on: (Array new: 10).
	layoutSpec ifNotNil: [ props nextPut: #layoutSpec ].
	eventHandler ifNotNil: [ props nextPut: #eventHandler ].
	otherProperties ifNotNil: [
		otherProperties associationsDo: [ :a |
			props nextPut: a key ]].
	^ props contents sort: [ :s1 :s2 |
		s1 <= s2 ]! !

MorphExtension removeSelector: #hasOtherProperties!
MorphExtension removeSelector: #initializeOtherProperties!
MorphExtension removeSelector: #otherProperties!
MorphExtension removeSelector: #privateOtherProperties:!
MorphExtension removeSelector: #removeOtherProperties!
!classDefinition: #MorphExtension category: #'Morphic-Kernel'!
Object subclass: #MorphExtension
	instanceVariableNames: 'layoutSpec eventHandler otherProperties'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'Morphic-Kernel'!

!MorphExtension reorganize!
('accessing - basic properties' eventHandler eventHandler: layoutFrame layoutFrame:)
('accessing - optional properties' balloonText balloonText: locked locked: sticky sticky: visible visible:)
('accessing - other properties' hasProperty: removeProperty: setProperty:toValue: valueOfProperty: valueOfProperty:ifAbsent: valueOfProperty:ifAbsentPut:)
('copying' veryDeepInner:)
('initialization' initialize)
('objects from disk' comeFullyUpOnReload:)
('other' inspectElement isDefault)
('printing' printOn:)
('private' assureOtherProperties sortedPropertyNames)
!

Morph removeSelector: #otherProperties!
