'From Cuis 1.0 of 6 April 2009 [latest update: #169] on 14 April 2009 at 8:32:38 am'!

!HandMorph methodsFor: 'focus handling' stamp: 'jmv 4/9/2009 13:32'!
keyboardFocusNext

	| firstCandidate candidate |
	firstCandidate _ keyboardFocus isNil
		ifTrue: [ World submorphs first ]
		ifFalse: [ keyboardFocus nextMorph ].
	
	candidate _ firstCandidate.
	candidate handlesKeyboard ifFalse: [
		[
			candidate _ candidate nextMorph.
			candidate handlesKeyboard not and: [ candidate ~~ firstCandidate ] ] whileTrue ].

	candidate activateWindowAndSendTopToBack: true.
	self newKeyboardFocus: candidate! !

!HandMorph methodsFor: 'focus handling' stamp: 'jmv 4/9/2009 13:32'!
keyboardFocusPrevious

	| firstCandidate candidate |
	firstCandidate _ keyboardFocus isNil
		ifTrue: [ World ]
		ifFalse: [ keyboardFocus previousMorph ].

	candidate _ firstCandidate.
	candidate handlesKeyboard ifFalse: [
		[
			candidate _ candidate previousMorph.
			candidate handlesKeyboard not and: [ candidate ~~ firstCandidate ] ] whileTrue ].

	candidate activateWindow.
	self newKeyboardFocus: candidate! !


!Preferences class methodsFor: 'standard queries' stamp: 'jmv 4/14/2009 08:31'!
focusIndicatorColor
	^ self
		valueOfFlag: #focusIndicatorColor
		ifAbsent: [Color darkGray]! !

!Preferences class methodsFor: 'standard queries' stamp: 'jmv 4/11/2009 23:16'!
focusIndicatorWidth
	^ self
		valueOfFlag: #focusIndicatorWidth
		ifAbsent: [1]! !


!ScrollPane methodsFor: 'geometry' stamp: 'jmv 4/11/2009 22:51'!
viewableBounds
	| inner |
	inner _ super innerBounds.
	retractableScrollBar | self vIsScrollbarShowing not ifFalse:[
		inner _ (scrollBarOnLeft
					ifTrue: [scrollBar right @ inner top corner: inner bottomRight]
					ifFalse: [inner topLeft corner: scrollBar left @ inner bottom])
	].
	(retractableScrollBar | self hIsScrollbarShowing not)
		ifTrue: [^ inner]
		ifFalse: [^ inner topLeft corner: (inner bottomRight - (0@Preferences scrollbarThickness))]! !

!ScrollPane methodsFor: 'geometry' stamp: 'jmv 4/11/2009 22:51'!
viewableWidth
	"Viewable width.
	Leave room for vertical scrollbar if present"
	| answer |
	answer _ self bounds width - (self borderWidth * 2).
	(retractableScrollBar not and: [ self vIsScrollbarShowing ]) ifTrue: [
		answer _ answer - Preferences scrollbarThickness ].
	^answer! !

!ScrollPane methodsFor: 'change reporting' stamp: 'jmv 4/11/2009 23:19'!
invalidateBorderFeedback

	| r |
	r _ self viewableBounds.
	(r areasOutside: (r insetBy: Preferences focusIndicatorWidth))
		do: [ :rect | self invalidRect: rect ]! !


!PluggableListMorph methodsFor: 'drawing' stamp: 'jmv 4/14/2009 08:30'!
drawOn: aCanvas

	super drawOn: aCanvas.
	self hasKeyboardFocus ifTrue: [
		aCanvas
			frameRectangle: self viewableBounds 
			width: Preferences focusIndicatorWidth 
			color: Preferences focusIndicatorColor ]! !

!PluggableListMorph methodsFor: 'event handling' stamp: 'jmv 4/9/2009 14:29'!
keyboardFocusChange: aBoolean
	"The message is sent to a morph when its keyboard focus changes.
	The given argument indicates that the receiver is gaining (versus losing) the keyboard focus.
	In this case, all we need to do is to redraw border feedback"

	self invalidateBorderFeedback! !


!PluggableTextMorph methodsFor: 'drawing' stamp: 'jmv 4/14/2009 08:30'!
drawOn: aCanvas 
	"Include a thin red inset border for unaccepted edits, or, if the unaccepted edits are known to conflict with a change made somewhere else to the same method (typically), put a thick red frame"

	| bw bc |
	super drawOn: aCanvas.
	bw _ Preferences focusIndicatorWidth.
	bc _ nil.
	self wantsFrameAdornments ifTrue: [
		(model notNil and: [model refusesToAcceptCode])
			ifTrue: [  "Put up feedback showing that code cannot be submitted in this state"
				bc _ Color tan]
			ifFalse: [
				self hasEditingConflicts
					ifTrue: [
						bw _ 3.
						bc _ Color red ] 
					ifFalse: [
						self hasUnacceptedEdits
							ifTrue: [
								model wantsDiffFeedback
									ifTrue: [
										bw _ 4.
										bc _ Color green]
									ifFalse: [
										bc _ Color red]]
							ifFalse: [
								model wantsDiffFeedback
									ifTrue: [
										bc _ Color green]
									ifFalse: []]]]].
					
	textMorph hasKeyboardFocus ifTrue: [
		bc ifNil: [
			bc _ Preferences focusIndicatorColor ]]
	ifFalse: [
		bc ifNotNil: [
			bc _ bc alphaMixed: 0.4 with: Color white ]].
	bc notNil ifTrue: [
		aCanvas frameRectangle: self viewableBounds width: bw color: bc ]! !

!PluggableTextMorph methodsFor: 'geometry' stamp: 'jmv 4/11/2009 23:11'!
extent: newExtent
	super extent: (newExtent max: 36@16).
	textMorph ifNotNil:
		[textMorph extent: (self viewableWidth-6)@self height].
	self setScrollDeltas! !

!PluggableTextMorph methodsFor: 'model access' stamp: 'jmv 4/11/2009 23:10'!
setText: aText
	scrollBar setValue: 0.0.
	textMorph
		ifNil: [textMorph _ TextMorphForEditView new
						contents: aText wrappedTo: self viewableWidth-6.
				textMorph setEditView: self.
				scroller addMorph: textMorph]
		ifNotNil: [textMorph newContents: aText].
	self hasUnacceptedEdits: false.
	self setScrollDeltas.! !


!SimpleHierarchicalListMorph methodsFor: 'drawing' stamp: 'jmv 4/14/2009 08:31'!
drawOn: aCanvas

	super drawOn: aCanvas.
	self hasKeyboardFocus ifTrue: [
		aCanvas
			frameRectangle: self viewableBounds 
			width: Preferences focusIndicatorWidth
			color: Preferences focusIndicatorColor ].

	selectedMorph ifNotNil:
		[aCanvas fillRectangle:
			(((scroller transformFrom: self) invertBoundsRect: selectedMorph bounds)
						intersect: scroller bounds)
				color: color blacker].

	Preferences showLinesInHierarchyViews ifTrue:[
		self drawLinesOn: aCanvas.
	].


! !

!SimpleHierarchicalListMorph methodsFor: 'event handling' stamp: 'jmv 4/9/2009 14:59'!
keyboardFocusChange: aBoolean
	"The message is sent to a morph when its keyboard focus changes.
	The given argument indicates that the receiver is gaining (versus losing) the keyboard focus.
	In this case, all we need to do is to redraw border feedback"

	self invalidateBorderFeedback! !


!SystemWindow methodsFor: 'top window' stamp: 'jmv 4/9/2009 13:33'!
activate
	"Bring me to the front and make me able to respond to mouse and keyboard"

	| candidate |
	self activateAndSendTopToBack: false.
	
	candidate _ self.
	candidate handlesKeyboard ifFalse: [
		[
			candidate _ candidate nextMorph.
			candidate handlesKeyboard not and: [ candidate ~~  self ] ] whileTrue ].

	candidate handlesKeyboard ifTrue: [
		self world primaryHand newKeyboardFocus: candidate ]! !


!TextMorphForEditView methodsFor: 'event handling' stamp: 'jmv 4/9/2009 14:21'!
keyboardFocusChange: aBoolean
	"The message is sent to a morph when its keyboard focus changes.
	The given argument indicates that the receiver is gaining (versus losing) the keyboard focus.
	In this case, all we need to do is to redraw border feedback"

	super keyboardFocusChange: aBoolean.
	editView invalidateBorderFeedback! !


!PluggableListMorph reorganize!
('accessing' highlightSelector itemFromPoint: rowAtLocation:)
('as yet unclassified' listMorph listMorphClass)
('drag and drop' acceptDroppingMorph:event: potentialDropItem potentialDropRow resetPotentialDropRow startDrag:)
('drawing' drawOn: highlightSelection unhighlightSelection)
('dropping/grabbing' wantsDroppedMorph:event:)
('event handling' handlesKeyboard handlesMouseOverDragging: keyStroke: keyboardFocusChange: mouseEnter:)
('events' doubleClick: handlesBasicKeys mouseDown: mouseEnterDragging: mouseLeaveDragging: mouseMove: mouseUp:)
('events-processing' handleMouseMove:)
('geometry' extent: scrollDeltaHeight scrollDeltaWidth)
('initialization' autoDeselect: doubleClickSelector: font font: getListElementSelector: initForKeystrokes keystrokeActionSelector: listItemHeight on:list:selected:changeSelected:menu:keystroke: textColor textColor: textHighlightColor textHighlightColor:)
('menu' getMenu:)
('menus' addCustomMenuItems:hand: copyListToClipboard copySelectionToClipboard setListFont)
('model access' basicKeyPressed: changeModelSelection: commandKeyTypedIntoMenu: getCurrentSelectionIndex getList getListItem: getListSize itemSelectedAmongMultiple: modifierKeyPressed: specialKeyPressed:)
('obsolete' mouseEnterDragging:onItem: mouseUp:onItem: removeObsoleteEventHandlers)
('scrolling' hExtraScrollRange hUnadjustedScrollRange vUnadjustedScrollRange)
('selection' getListSelector maximumSelection minimumSelection numSelectionsInView scrollSelectionIntoView selectedMorph: selection selection: selectionIndex selectionIndex: setGetListSelector: setSelectedMorph:)
('updating' update: updateList verifyContents)
('change reporting')
!

