'From Cuis 2.3 of 22 March 2010 [latest update: #472] on 5 April 2010 at 10:41:57 am'!

!NewParagraph methodsFor: 'display' stamp: 'jmv 3/31/2010 09:04'!
displayInsertionMarkAtX: x top: top bottom: bottom emphasis: emphasis on: aCanvas
			
	| caretColor e x1 x2 isBold isItalic x0 xtraWidth |
	isBold _ emphasis allMask: 1.
	isItalic _ emphasis allMask: 2.
	caretColor _ self insertionPointColor.
	xtraWidth _ isBold ifTrue: [ 1 ] ifFalse: [ 0 ].
	isItalic ifTrue:
		[x0 _ x - 2.
		x1 _ x0 - 2.
		x2 _ x0 - 6 ]
	ifFalse:
		[x0 _ x.
		x1 _ x0 - 4.
		x2 _ x1 ].
	1 to: 2 do: [ :i | 
		"Draw caret triangles at top and bottom"
		e _ (2 - i) * 2 + 4+xtraWidth @ 1.
		aCanvas fillRectangle: (x1 + i @ (top + i - 1) extent: e)
			color: caretColor.
		aCanvas fillRectangle: (x2 + i @ (bottom - i) extent: e)
			color: caretColor].
	aCanvas fillRectangle: (x0-1 @ top corner: x0+1+xtraWidth @ bottom)
		color: caretColor! !

!NewParagraph methodsFor: 'display' stamp: 'jmv 3/31/2010 08:59'!
displaySelectionInLine: line on: aCanvas
	| leftX rightX idx caretFont t b caretAttributes |
	selectionStart ifNil: [^self].	"No selection"
	selectionStart = selectionStop 
		ifTrue: [
			"Only show caret on line where clicked"
			selectionStart textLine ~= line ifTrue: [^self]
			]
		ifFalse: [
			"Test entire selection before or after here"
			(selectionStop stringIndex < line first 
				or: [selectionStart stringIndex > (line last + 1)])
					ifTrue: [^self].	"No selection on this line"
			(selectionStop stringIndex = line first 
				and: [selectionStop textLine ~= line])
					ifTrue: [^self].	"Selection ends on line above"
			(selectionStart stringIndex = (line last + 1) 
				and: [selectionStop textLine ~= line])
					ifTrue: [^self]].	"Selection begins on line below"
	leftX _ (selectionStart stringIndex < line first 
				ifTrue: [ line ]
				ifFalse: [ selectionStart ]) left.
	rightX _ (selectionStop stringIndex > (line last + 1) or: [
					selectionStop stringIndex = (line last + 1) 
						and: [selectionStop textLine ~= line]]) 
				ifTrue: [line right]
				ifFalse: [selectionStop left].
	selectionStart = selectionStop 
		ifTrue: [
			idx _ selectionStart stringIndex.
			caretAttributes _ editor ifNotNil: [ editor currentAttributes ].
			caretFont _ caretAttributes
				ifNil: [ text fontAt: idx ]
				ifNotNil: [ text fontIfApplying: caretAttributes ].
			b _ line top + line baseline + caretFont descent.
			t _ line top + line baseline - caretFont ascent.
			self
				displayInsertionMarkAtX: leftX
				top: t
				bottom: b
				emphasis: caretFont emphasis
				on: aCanvas
			]
		ifFalse: [
			aCanvas fillRectangle: (leftX @ line top corner: rightX @ line bottom)
				color: self selectionColor]! !

!NewParagraph methodsFor: 'selection' stamp: 'jmv 3/31/2010 09:00'!
selectionRectsFrom: characterBlock1 to: characterBlock2 
	"Return an array of rectangles representing the area between the two character blocks given as arguments."
	| line1 line2 rects cb1 cb2 w |
	characterBlock1 <= characterBlock2
		ifTrue: [cb1 _ characterBlock1.  cb2 _ characterBlock2]
		ifFalse: [cb2 _ characterBlock1.  cb1 _ characterBlock2].
	cb1 = cb2 ifTrue:
		[w _ 6.
		^ Array with: (cb1 topLeft - (w@0) corner: cb1 bottomLeft + ((w+1)@0))].
	line1 _ self lineIndexForCharacter: cb1 stringIndex.
	line2 _ self lineIndexForCharacter: cb2 stringIndex.
	line1 = line2 ifTrue:
		[^ Array with: (cb1 topLeft corner: cb2 bottomRight)].
	rects _ OrderedCollection new.
	rects addLast: (cb1 topLeft corner: (lines at: line1) bottomRight).
	line1+1 to: line2-1 do: [ :i |
		| line |
		line _ lines at: i.
		(line left = rects last left and: [ line right = rects last right ])
			ifTrue: [ "new line has same margins as old one -- merge them, so that the caller gets as few rectangles as possible"
					| lastRect |
					lastRect _ rects removeLast.
					rects add: (lastRect bottom: line bottom) ]
			ifFalse: [ "differing margins; cannot merge"
					rects add: line rectangle ] ].

	rects addLast: ((lines at: line2) topLeft corner: cb2 bottomLeft).
	^ rects! !


!OneLineEditorMorph methodsFor: 'drawing' stamp: 'jmv 3/31/2010 09:09'!
drawCaretOn: aCanvas
	"Essentially copied from #displayInsertionMarkAtX:top:bottom:emphasis:on:"
	|  caretColor top bottom x isBold isItalic xtraWidth x0 x1 x2 e |

	top _ bounds top.
	bottom _ top + self baseFont height.
	x _ (self fontToUse widthOfString: contents from: 1 to: editor startIndex-1) + bounds left.
	isBold _ emphasis allMask: 1.
	isItalic _ emphasis allMask: 2.
	caretColor _ self insertionPointColor.
	xtraWidth _ isBold ifTrue: [ 1 ] ifFalse: [ 0 ].
	isItalic ifTrue:
		[x0 _ x - 2.
		x1 _ x0 - 2.
		x2 _ x0 - 6 ]
	ifFalse:
		[x0 _ x.
		x1 _ x0 - 4.
		x2 _ x1 ].
	1 to: 2 do: [ :i | 
		"Draw caret triangles at top and bottom"
		e _ (2 - i) * 2 + 4+xtraWidth @ 1.
		aCanvas fillRectangle: (x1 + i @ (top + i - 1) extent: e)
			color: caretColor.
		aCanvas fillRectangle: (x2 + i @ (bottom - i) extent: e)
			color: caretColor].
	aCanvas fillRectangle: (x0-1 @ top corner: x0+1+xtraWidth @ bottom)
		color: caretColor! !


!Preferences class methodsFor: 'text highlighting' stamp: 'jmv 3/31/2010 09:14'!
initializeTextHighlightingParameters
	"Preferences initializeTextHighlightingParameters"
	Parameters at: #insertionPointColor put: "(Color r: 0.4 g: 1.0 b: 0)" (Color r: 0.9 g: 0.2 b: 0).
	Parameters at: #textHighlightColor put: (Color r: 0.4 g: 1.0 b: 0).! !

OneLineEditorMorph removeSelector: #caretWidth!
NewParagraph removeSelector: #caretWidth!
NewParagraph removeSelector: #displayInsertionMarkAtX:top:bottom:width:emphasis:on:!
"Postscript:
Leave the line above, and replace the rest of this comment by a useful one.
Executable statements should follow this comment, and should
be separated by periods, with no exclamation points (!!).
Be sure to put any further comments in double-quotes, like this one."
Preferences initializeTextHighlightingParameters!

