| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457 | Smalltalk createPackage: 'Moka-Controllers'!MKSingleAspectController subclass: #MKAnyKeyInputController	instanceVariableNames: 'lastValue'	package: 'Moka-Controllers'!!MKAnyKeyInputController commentStamp!I am the default controller for `MKTextAreaView`. Actions are performed on any key press if the view's value changes.!!MKAnyKeyInputController methodsFor: 'accessing'!inputText	^ self view value! !!MKAnyKeyInputController methodsFor: 'actions'!onKeyUp: anEvent	self setNewValue!setNewValue	| newValue |		newValue := self inputText.	newValue = lastValue ifTrue: [ ^ self ].		lastValue := newValue.	self performAspectActionWith: newValue! !MKAnyKeyInputController subclass: #MKEnterInputController	instanceVariableNames: ''	package: 'Moka-Controllers'!!MKEnterInputController commentStamp!I am the default controller for `MKInputView`. Actions are performed on 'enter' key press.!!MKEnterInputController methodsFor: 'actions'!onKeyDown: anEvent	anEvent keyCode = String cr asciiValue ifTrue: [		self setNewValue ]!onKeyUp: anEvent! !MKSingleAspectController subclass: #MKButtonController	instanceVariableNames: ''	package: 'Moka-Controllers'!!MKButtonController commentStamp!I am the default controller for `MKButtonView`.!!MKButtonController methodsFor: 'actions'!onClick: anEvent	self performAspectAction! !MKSingleAspectController subclass: #MKCheckboxController	instanceVariableNames: ''	package: 'Moka-Controllers'!!MKCheckboxController commentStamp!I am the default controller for `MKCheckboxView`.!!MKCheckboxController methodsFor: 'actions'!onClick: anEvent	self toggle!onKeyDown: anEvent	"Avoid scrolling in scrollable views"		anEvent stopPropagation!onKeyPress: anEvent	anEvent charCode = ' ' asciiValue ifTrue: [ 		self toggle.		anEvent stopPropagation; preventDefault ]!toggle	self performAspectActionWith: self view checked not! !MKAspectsController subclass: #MKDropdownController	instanceVariableNames: ''	package: 'Moka-Controllers'!!MKDropdownController commentStamp!I am the default controller for `MKDropdownView`.!!MKDropdownController methodsFor: 'actions'!onClick: anEvent	self view popupList!onKeyDown: anEvent	anEvent keyCode = String cr asciiValue ifTrue: [		self view popupList ]! !MKAspectsController subclass: #MKListController	instanceVariableNames: 'downRepeater upRepeater'	package: 'Moka-Controllers'!!MKListController commentStamp!I am the default controller for `MKListView`.!!MKListController methodsFor: 'accessing'!activeItem	^ self view activeItem!collection	^ self view collection!downRepeater	^ downRepeater ifNil: [ downRepeater := MKRepeater new ]!upRepeater	^ upRepeater ifNil: [ upRepeater := MKRepeater new ]! !!MKListController methodsFor: 'actions'!activateItem: anItem	"On item activation, change the model selection"		self selectItem: anItem!onClick: anEvent	self selectItem: (self itemForTarget: anEvent target)!onKeyDown: anEvent	"Down"	anEvent keyCode = 40 ifTrue: [ 		anEvent preventDefault; stopPropagation.		self upRepeater stopRepeating.		self downRepeater repeat: [ 			self activateItem: self nextItem ] ].	"Up"	anEvent keyCode = 38 ifTrue: [ 		anEvent preventDefault; stopPropagation.		self downRepeater stopRepeating.		self upRepeater repeat: [ 			self activateItem: self previousItem ] ].!onKeyUp: anEvent	self downRepeater stopRepeating.	self upRepeater stopRepeating!selectItem: anItem	self 		performAspectAction: self view selectionAspect 		with: anItem! !!MKListController methodsFor: 'private'!itemForTarget: aDOMElement	^ self view findItemFor: aDOMElement!nextItem	^ self collection 		at: (self collection indexOf: self activeItem) + 1		ifAbsent: [ self collection last ]!previousItem	^ self view collection 		at: (self view collection indexOf: self activeItem) - 1		ifAbsent: [ self view collection first ]! !MKListController subclass: #MKDropdownListController	instanceVariableNames: ''	package: 'Moka-Controllers'!!MKDropdownListController commentStamp!I am the default controller for `MKDropdownView`'s popup list.!!MKDropdownListController methodsFor: 'actions'!activateItem: anItem	"Select the list item in the view.	No change is done to the model"		self view activateItem: anItem!onKeyDown: anEvent	super onKeyDown: anEvent.		anEvent keyCode = String cr asciiValue ifTrue: [		self selectItem: self view activeItem ]!onMouseMove: anEvent	(self upRepeater isRepeating or: [ self downRepeater isRepeating ])		ifTrue: [ ^ self ].			self activateItem: (self itemForTarget: anEvent target)! !MKSingleAspectController subclass: #MKModalController	instanceVariableNames: ''	package: 'Moka-Controllers'!!MKModalController commentStamp!I am the default controller for `MKModalDecorator`.!!MKModalController methodsFor: 'actions'!onClick: anEvent	self view closeOnClick ifTrue: [ self removeView ]!onKeyDown: anEvent	self view closeOnEnter ifTrue: [		anEvent keyCode = String cr asciiValue ifTrue: [			self removeView.			anEvent 				stopPropagation;				preventDefault ] ].		"ESC"	anEvent keyCode = 27 ifTrue: [		self removeView ]!removeView	self view overlay remove! !MKSingleAspectController subclass: #MKOverlayController	instanceVariableNames: ''	package: 'Moka-Controllers'!!MKOverlayController commentStamp!I am the default controller for `MKOverlayView`.On a click to the overlay, it is removed together with it's content view.!!MKOverlayController methodsFor: 'actions'!onClick: anEvent	self view remove! !Object subclass: #MKRepeater	instanceVariableNames: 'repeatInterval interval delay'	package: 'Moka-Controllers'!!MKRepeater commentStamp!I am an internal class used by controllers to repeat block actions after a `delay` and with an `interval`.!!MKRepeater methodsFor: 'accessing'!repeatInterval	^ repeatInterval ifNil: [ self defaultRepeatInterval ]!repeatInterval: aNumber	repeatInterval := aNumber! !!MKRepeater methodsFor: 'actions'!repeat: aBlock	self isRepeating ifTrue: [ ^ self ].	aBlock value.	delay := [ interval := aBlock valueWithInterval: self repeatInterval ] 		valueWithTimeout: 300!stopRepeating	interval ifNotNil: [ interval clearInterval ].	delay ifNotNil: [ delay clearTimeout ].	interval := delay := nil! !!MKRepeater methodsFor: 'defaults'!defaultRepeatInterval	^ 70! !!MKRepeater methodsFor: 'testing'!isRepeating	^ delay notNil! !MKController subclass: #MKScrollController	instanceVariableNames: ''	package: 'Moka-Controllers'!!MKScrollController commentStamp!I am the default controller for `MKScrollDecorator`.!!MKScrollController methodsFor: 'actions'!onDecoratedScroll	self view updateScrollbarsPosition!onHorizontalDrag: anEvent	(self view decorated asJQuery get: 0) at: 'scrollLeft' put: self view domScrollPosition x!onMousewheel: anEvent	anEvent deltaY ~= 0 ifTrue: [		self view scrollDeltaY: anEvent deltaY * 10 ].		anEvent deltaX ~= 0 ifTrue: [		self view scrollDeltaX: anEvent deltaX * 10 ]!onResize	self view resized!onVerticalDrag: anEvent	(self view decorated asJQuery get: 0) at: 'scrollTop' put: self view domScrollPosition y! !MKController subclass: #MKSplitController	instanceVariableNames: ''	package: 'Moka-Controllers'!!MKSplitController commentStamp!I am the abstract controller for `MKSplitView`.!!MKSplitController methodsFor: 'actions'!onResize: anEvent helper: aJQuery	self placeSplitter: (self positionForSplitter: aJQuery)!placeSplitter: aJQuery	self subclassResponsibility! !!MKSplitController methodsFor: 'private'!positionForSplitter: aJQuery	^ self subclassResponsibility! !MKSplitController subclass: #MKBottomFixedVerticalSplitController	instanceVariableNames: ''	package: 'Moka-Controllers'!!MKBottomFixedVerticalSplitController commentStamp!I am an alternative controller for `MKVerticalSplitView`.When the splitter is moved, the second view is set a fixed size, thus resizing will preserve the height of the second view, while the first view will be resized.!!MKBottomFixedVerticalSplitController methodsFor: 'actions'!placeSplitter: aNumber	| splitter |	splitter := self view splitter asJQuery.	self view secondView asJQuery 		css: 'height' put: aNumber asMokaCssString;		css: 'bottom' put: 0.	splitter 		css: 'top' put: 'auto';		css: 'bottom' put: (aNumber - splitter height) asMokaCssString.	self view firstView asJQuery css: 'bottom' put: aNumber asMokaCssString! !!MKBottomFixedVerticalSplitController methodsFor: 'private'!positionForSplitter: aJQuery	^ ((self view domSize y - aJQuery position top) 		max: self view minimumThickness) min: (self view domSize y - self view minimumThickness)! !MKSplitController subclass: #MKLeftFixedHorizontalSplitController	instanceVariableNames: ''	package: 'Moka-Controllers'!!MKLeftFixedHorizontalSplitController commentStamp!I am the controller for `MKHorizontalSplitView`.When the splitter is moved, the left view is set a fixed size, thus resizing will preserve the width of the first view, while the second view will be resized.!!MKLeftFixedHorizontalSplitController methodsFor: 'actions'!placeSplitter: aNumber	self view firstView asJQuery css: 'width' put: aNumber asMokaCssString.	self view splitter asJQuery css: 'left' put: aNumber asMokaCssString.	self view secondView asJQuery css: 'left' put: aNumber asMokaCssString! !!MKLeftFixedHorizontalSplitController methodsFor: 'private'!positionForSplitter: aJQuery	^ (aJQuery position left max: self view minimumThickness)		min: (self view domSize x - self view minimumThickness)! !MKSplitController subclass: #MKRightFixedHorizontalSplitController	instanceVariableNames: ''	package: 'Moka-Controllers'!!MKRightFixedHorizontalSplitController commentStamp!I am an alternative controller for `MKHorizontalSplitView`.When the splitter is moved, the second view is set a fixed size, thus resizing will preserve the width of the second view, while the first view will be resized.!!MKRightFixedHorizontalSplitController methodsFor: 'actions'!placeSplitter: aNumber	| splitter |	splitter := self view splitter asJQuery.	self view secondView asJQuery 		css: 'width' put: aNumber asMokaCssString;		css: 'right' put: 0.	splitter 		css: 'left' put: 'auto';		css: 'right' put: (aNumber - splitter width) asMokaCssString.	self view firstView asJQuery css: 'right' put: aNumber asMokaCssString! !!MKRightFixedHorizontalSplitController methodsFor: 'private'!positionForSplitter: aJQuery	^ ((self view domSize x - aJQuery position left)		max: self view minimumThickness)			min: (self view domSize x - self view minimumThickness)! !MKSplitController subclass: #MKTopFixedVerticalSplitController	instanceVariableNames: ''	package: 'Moka-Controllers'!!MKTopFixedVerticalSplitController commentStamp!I am the controller for `MKVerticalSplitView`.When the splitter is moved, the top view is set a fixed size, thus resizing will preserve the height of the first view, while the second view will be resized.!!MKTopFixedVerticalSplitController methodsFor: 'actions'!placeSplitter: aNumber	self view firstView asJQuery css: 'height' put: aNumber asMokaCssString.	self view splitter asJQuery css: 'top' put: aNumber asMokaCssString.	self view secondView asJQuery css: 'top' put: aNumber asMokaCssString! !!MKTopFixedVerticalSplitController methodsFor: 'private'!positionForSplitter: aJQuery	^ (aJQuery position top max: self view minimumThickness)		min: (self view domSize y - self view minimumThickness)! !
 |