| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313 | Smalltalk createPackage: 'Moka-Layouts'!Object subclass: #MKLayout	instanceVariableNames: 'properties'	package: 'Moka-Layouts'!!MKLayout commentStamp!I am responsible for the layout of a `MKLayoutView`.!!MKLayout methodsFor: 'accessing'!bottom: aNumber	properties 		at: 'bottom' 		put: (self propertyLabelled: 'bottom' value: aNumber).		(self hasProperty: 'top') ifTrue: [		self removeProperty: 'height' ].	self removeProperty: 'centerY'!centerX: aNumber	properties		at: 'centerX'		put: (MKHorizontalCenteringLayoutProperty layout: self value: aNumber).		self 		removeProperty: 'left';		removeProperty: 'right'!centerY: aNumber	properties		at: 'centerY'		put: (MKVerticalCenteringLayoutProperty layout: self value: aNumber).			self 		removeProperty: 'top';		removeProperty: 'bottom'!height	^ properties 		at: 'height' 		ifPresent: [ :property | property value ]		ifAbsent: [ 1 ]!height: aNumber	properties 		at: 'height' 		put: (self propertyLabelled: 'height' value: aNumber).		(self hasProperty: 'top') ifTrue: [		self removeProperty: 'bottom' ]!left: aNumber	properties 		at: 'left' 		put: (self propertyLabelled: 'left' value: aNumber).		(self hasProperty: 'width') ifTrue: [		self removeProperty: 'right' ].	self removeProperty: 'centerX'!right: aNumber	properties 		at: 'right' 		put: (self propertyLabelled: 'right' value: aNumber).		(self hasProperty: 'width') ifTrue: [		self removeProperty: 'left' ].	self removeProperty: 'centerX'!top: aNumber	properties 		at: 'top' 		put: (self propertyLabelled: 'top' value: aNumber).		(self hasProperty: 'height') ifTrue: [		self removeProperty: 'bottom' ].	self removeProperty: 'centerY'!width	^ properties 		at: 'width' 		ifPresent: [ :property | property value ]		ifAbsent: [ 1 ]!width: aNumber	properties 		at: 'width' 		put: (self propertyLabelled: 'width' value: aNumber).		(self hasProperty: 'left') ifTrue: [		self removeProperty: 'right' ]! !!MKLayout methodsFor: 'converting'!asCssString	^ String streamContents: [ :stream |		properties valuesDo: [ :each | 			each printCssOn: stream.			stream << ';' ] ]! !!MKLayout methodsFor: 'factory'!propertyLabelled: aString value: aValue	^ MKLabelledLayoutProperty layout: self label: aString value: aValue! !!MKLayout methodsFor: 'initialization'!initialize	super initialize.	properties := Dictionary new! !!MKLayout methodsFor: 'private'!hasProperty: aString	^ properties includesKey: aString!removeProperty: aString	properties remove: aString ifAbsent: []! !MKLayout subclass: #MKLabelLayout	instanceVariableNames: ''	package: 'Moka-Layouts'!!MKLabelLayout commentStamp!I am a specialized layout for label views. I can set a `textAlign` property, taking a string argument, `'left'`, `'center'` or `'right'`.!!MKLabelLayout methodsFor: 'accessing'!textAlign: aString	"Map to CSS' text-align property. Possible values are `'left'`, `'center'` and `'right'`"		properties 		at: 'text-align' 		put: (self propertyLabelled: 'text-align' value: aString)! !MKLayout subclass: #MKPaneLayout	instanceVariableNames: ''	package: 'Moka-Layouts'!!MKPaneLayout commentStamp!I am a specialized layout for pane views. I can set border widths to my views.!!MKPaneLayout methodsFor: 'accessing'!borderBottom: aNumber	properties 		at: 'border-bottom' 		put: (self propertyLabelled: 'border-bottom-width' value: aNumber asMokaPixelString)!borderLeft: aNumber	properties 		at: 'border-left' 		put: (self propertyLabelled: 'border-left-width' value: aNumber asMokaPixelString)!borderRight: aNumber	properties 		at: 'border-right' 		put: (self propertyLabelled: 'border-right-width' value: aNumber asMokaPixelString)!borderTop: aNumber	properties 		at: 'border-top' 		put: (self propertyLabelled: 'border-top-width' value: aNumber asMokaPixelString)! !Object subclass: #MKLayoutProperty	instanceVariableNames: 'layout value'	package: 'Moka-Layouts'!!MKLayoutProperty commentStamp!I represent a single layout property.!!MKLayoutProperty methodsFor: 'accessing'!layout	^ layout!layout: aLayout	layout := aLayout!value	^ value!value: aValue	value := aValue! !!MKLayoutProperty methodsFor: 'converting'!asCssString	^ String streamContents: [ :stream | 		self printCssOn: stream ]! !!MKLayoutProperty methodsFor: 'printing'!printCssOn: aStream	self subclassResponsibility! !!MKLayoutProperty class methodsFor: 'instance creation'!layout: aLayout value: aValue	^ self new		layout: aLayout;		value: aValue;		yourself! !MKLayoutProperty subclass: #MKHorizontalCenteringLayoutProperty	instanceVariableNames: ''	package: 'Moka-Layouts'!!MKHorizontalCenteringLayoutProperty methodsFor: 'accessing'!marginLeft	^ 0 - ((self layout width / 2) + self value)! !!MKHorizontalCenteringLayoutProperty methodsFor: 'printing'!printCssOn: aStream	aStream << 'left:50%;'.	aStream << 'margin-left:' << self marginLeft asMokaCssString! !MKLayoutProperty subclass: #MKLabelledLayoutProperty	instanceVariableNames: 'label'	package: 'Moka-Layouts'!!MKLabelledLayoutProperty methodsFor: 'accessing'!label	^ label!label: aString	label := aString! !!MKLabelledLayoutProperty methodsFor: 'printing'!printCssOn: aStream	aStream << self label << ':' << self value asMokaCssString! !!MKLabelledLayoutProperty class methodsFor: 'instance creation'!layout: aLayout label: aString value: aValue	^ self new		layout: aLayout;		label: aString;		value: aValue;		yourself! !MKLayoutProperty subclass: #MKVerticalCenteringLayoutProperty	instanceVariableNames: ''	package: 'Moka-Layouts'!!MKVerticalCenteringLayoutProperty methodsFor: 'accessing'!marginTop	^ 0 - ((self layout height / 2) + self value)! !!MKVerticalCenteringLayoutProperty methodsFor: 'printing'!printCssOn: aStream	aStream << 'top:50%;'.	aStream << 'margin-top:' << self marginTop asMokaCssString! !!Number methodsFor: '*Moka-Layouts'!asMokaCssString	^ self abs > 1 			ifTrue: [ self asMokaPixelString ]		ifFalse: [ self asMokaPercentString ]!asMokaPercentString	^ (self * 100) asString, '%'!asMokaPixelString	^ self asString, 'px'! !!String methodsFor: '*Moka-Layouts'!asMokaCssString	^ self! !
 |