| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457 | 
							- Smalltalk current 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)
 
- ! !
 
 
  |