'From Squeak3.7 of ''4 September 2004'' [latest update: #5989] on 27 January 2009 at 12:34:20 pm'!
!classDefinition: #CellStyleEntryFieldLW category: #'LightWidgets-Kernel'!
EntryField2LW subclass: #CellStyleEntryFieldLW
	instanceVariableNames: ''
	classVariableNames: ''
	poolDictionaries: ''
	category: 'LightWidgets-Kernel'!

!CellStyleEntryFieldLW commentStamp: '<historical>' prior: 0!
An entry field that uses numeric input to simulate letters, like cell phones do!

!classDefinition: #CellStyleEditor category: #'System-Text'!
SimpleEditor subclass: #CellStyleEditor
	instanceVariableNames: 'lastKeystroke lastTime storeLastTime'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'System-Text'!

!CellStyleEditor commentStamp: '<historical>' prior: 0!
A simple editor that uses digits to enter alphabetic characters, like cell phones do.!


!EntryField2LW methodsFor: 'accessing' stamp: 'jmv 1/22/2009 10:57'!
editorClass
	^SimpleEditor! !

!EntryField2LW methodsFor: 'accessing' stamp: 'jmv 1/22/2009 10:57'!
installEditorToReplace: priorEditor
	"Install an editor for my contents.  This constitutes 'hasFocus'.
	If priorEditor is not nil, then initialize the new editor from its state.
	We may want to rework this so it actually uses the prior editor."

	| stateArray |
	priorEditor ifNotNil: [stateArray := priorEditor stateArray].
	editor := self editorClass new morph: self.
	editor changeString: contents.
	priorEditor ifNotNil: [editor stateArrayPut: stateArray].
	self changed.
	^editor! !

!EntryField2LW methodsFor: 'drawing' stamp: 'jmv 1/22/2009 11:11'!
drawOn: aCanvas

	aCanvas frameAndFillRectangle: bounds fillColor: self backColor borderWidth: 2 borderColor: Color black.
	self hasSelection ifTrue: [
		self drawSelectionOn: aCanvas ].
	self hasVisibleCaret ifTrue: [
		self drawCaretOn: aCanvas].
	aCanvas drawString: contents in: (bounds insetBy: 5) font: font color: self foreColor! !

!EntryField2LW methodsFor: 'testing' stamp: 'jmv 1/22/2009 11:11'!
hasVisibleCaret

	^ self hasKeyboardFocus and: [editor hasCaret]! !


!CellStyleEntryFieldLW methodsFor: 'accessing' stamp: 'jmv 1/22/2009 10:57'!
editorClass
	^CellStyleEditor! !

!CellStyleEntryFieldLW methodsFor: 'stepping and presenter' stamp: 'jmv 1/22/2009 12:39'!
step
	editor isInCellShiftMode ifFalse: [
		self changed.
		self stopStepping ]! !

!CellStyleEntryFieldLW methodsFor: 'editing' stamp: 'jmv 1/22/2009 12:41'!
handleInteraction: interactionBlock fromEvent: evt

	super handleInteraction: interactionBlock fromEvent: evt.
	editor isInCellShiftMode ifTrue: [
		self startStepping ]! !

!CellStyleEntryFieldLW methodsFor: 'drawing' stamp: 'jmv 1/22/2009 13:59'!
drawCaretOn: aCanvas

	| top bottom leftX rightX caretColor |
	editor isInCellShiftMode not ifTrue: [
		^super drawCaretOn: aCanvas ].
	
	top _ bounds top + 4.
	bottom _ top + font height + 1.
	leftX _ (font widthOfString: contents from: 1 to: editor startIndex-2) + bounds left + 4.
	rightX _ (font widthOfString: contents from: 1 to: editor stopIndex-1) + bounds left + 6.
	caretColor := self insertionPointColor.

	aCanvas fillRectangle: (leftX @ top corner: rightX @ bottom)
		color: caretColor! !


!OldOneLineEditorMorph methodsFor: 'drawing' stamp: 'jmv 1/22/2009 13:55'!
drawOn: aCanvas
	self hasSelection ifTrue: [
		self drawSelectionOn: aCanvas ].
	self hasVisibleCaret ifTrue: [
		self drawCaretOn: aCanvas].
	aCanvas drawString: contents in: bounds font: self fontToUse color: color! !

!OldOneLineEditorMorph methodsFor: 'testing' stamp: 'jmv 1/22/2009 13:55'!
hasVisibleCaret

	^ self hasKeyboardFocus and: [editor hasCaret]! !


!PositionableStream methodsFor: 'testing' stamp: 'jmv 1/22/2009 11:24'!
notEmpty
	"Answer whether the receiver contains any elements."

	^ self isEmpty not! !


!SimpleEditor methodsFor: 'typing support' stamp: 'jmv 1/22/2009 12:49'!
dispatchOnCharacter: char with: typeAheadStream
	"Carry out the action associated with this character, if any.
	Type-ahead is passed so some routines can flush or use it."

	| honorCommandKeys |
	"We don't support multiple lines. Therefore, we don't process cr as a #normalCharacter:"
	((char == Character cr) "and: [morph acceptOnCR]")
		ifTrue: [
			sensor keyboard.  "Gobble cr -- probably unnecessary."
			self closeTypeIn.
			^ true].

	char asciiValue = 13 ifTrue: [
		^ sensor controlKeyPressed
			ifTrue: [self normalCharacter: typeAheadStream]
			ifFalse: [self crWithIndent: typeAheadStream]].

	((honorCommandKeys _ Preferences cmdKeysInText) and: [char = Character enter])
		ifTrue: [^ self dispatchOnEnterWith: typeAheadStream].

	"Special keys overwrite crtl+key combinations - at least on Windows. To resolve this
	conflict, assume that keys other than cursor keys aren't used together with Crtl." 
	((self class specialShiftCmdKeys includes: char asciiValue) and: [char asciiValue < 27])
		ifTrue: [^ sensor controlKeyPressed
			ifTrue: [self perform: (ShiftCmdActions at: char asciiValue + 1) with: typeAheadStream]
			ifFalse: [self perform: (CmdActions at: char asciiValue + 1) with: typeAheadStream]].

	"backspace, and escape keys (ascii 8 and 27) are command keys"
	((honorCommandKeys and: [sensor commandKeyPressed]) or: [self class specialShiftCmdKeys includes: char asciiValue]) ifTrue:
		[^ sensor leftShiftDown
			ifTrue: [
				self perform: (ShiftCmdActions at: char asciiValue + 1) with: typeAheadStream]
			ifFalse: [
				self perform: (CmdActions at: char asciiValue + 1) with: typeAheadStream]].

	"the control key can be used to invoke shift-cmd shortcuts"
	(honorCommandKeys and: [sensor controlKeyPressed])
		ifTrue:
			[^ self perform: (ShiftCmdActions at: char asciiValue + 1) with: typeAheadStream].

	^ self normalCharacter: typeAheadStream! !

!SimpleEditor methodsFor: 'typing support' stamp: 'jmv 1/22/2009 10:50'!
readKeyboard
	"Key struck on the keyboard. Find out which one and, if special, carry 
	out the associated special action. Otherwise, add the character to the 
	stream of characters.  Undoer & Redoer: see closeTypeIn."

	| typeAhead char |
	typeAhead _ WriteStream on: (String new: 128).
	"Seems that can be converted into an ifTrue: if sensor is an OldKeyboardBuffer... All this should be cleande. This old compatibility with a Sensor that is never there..."
	[ sensor keyboardPressed ] whileTrue: [
		self deselect.
		[ sensor keyboardPressed ] whileTrue: [
			char _ sensor keyboardPeek.
			(self dispatchOnCharacter: char with: typeAhead) ifTrue: [
				self doneTyping.
				^self].
			self openTypeIn ].
		self zapSelectionWith: typeAhead contents.
		typeAhead reset.
		self unselect ]! !


!CellStyleEditor methodsFor: 'typing/selecting keys' stamp: 'jmv 1/22/2009 12:22'!
nextCellCharFor: keystroke after: toBeReplaced
	| line |
	line _ #(
		' 0'
		'.,?!!"1-()@/:_'
		'abc2ABC'
		'def3DEF'
		'ghi4GHI'
		'jkl5JKL'
		'mno6MNO'
		'pqrs7PQRS'
		'tuv8TUV'
		'wxyz9WXYZ'
	) at: keystroke digitValue + 1.

	toBeReplaced isNil ifTrue: [
		^line first ].
	^line after: toBeReplaced ifNone: [ line first ]! !

!CellStyleEditor methodsFor: 'typing/selecting keys' stamp: 'jmv 1/22/2009 12:55'!
normalCharacter: characterStream
	"A nonspecial character is to be added to the stream of characters."
	
	| keystroke char |
	keystroke _ sensor keyboard.
	keystroke isDigit
		ifTrue: [
			(keystroke = lastKeystroke and: [ self isInCellShiftMode ])
				ifTrue: [
					char _ self nextCellCharFor: keystroke after: (string at: markIndex - 1).
					self backTo: markIndex - 1]
				ifFalse: [ 
					char _ self nextCellCharFor: keystroke after: nil ].
			storeLastTime _ true ]
		ifFalse: [
			char _ keystroke ].
	characterStream nextPut: char.
	lastKeystroke _ keystroke.
	^false! !

!CellStyleEditor methodsFor: 'initialize-release' stamp: 'jmv 1/22/2009 11:42'!
initialize
	"Initialize the state of the receiver. Subclasses should include 'super 
	initialize' when redefining this message to insure proper initialization."

	super initialize.
	lastTime _ 0! !

!CellStyleEditor methodsFor: 'testing' stamp: 'jmv 1/22/2009 12:24'!
isInCellShiftMode
	^Time millisecondClockValue - lastTime < 700 and: [ markIndex > 1 ]! !

!CellStyleEditor methodsFor: 'typing support' stamp: 'jmv 1/22/2009 12:54'!
dispatchOnCharacter: char with: typeAheadStream
	| answer |
	storeLastTime _ false.
	answer _ super dispatchOnCharacter: char with: typeAheadStream.
	lastTime _ storeLastTime
		ifTrue: [Time millisecondClockValue]
		ifFalse: [0].
	^ answer! !

!CellStyleEditor methodsFor: 'events' stamp: 'jmv 1/22/2009 13:03'!
mouseDown: evt index: index
	"Change the selection in response to moue-down drag"
	
	lastTime _ 0.
	^super mouseDown: evt index: index! !

!CellStyleEditor methodsFor: 'events' stamp: 'jmv 1/22/2009 13:03'!
mouseMove: evt index: index
	"Change the selection in response to moue-down drag"
	
	lastTime _ 0.
	^super mouseMove: evt index: index! !


!TextEditor methodsFor: 'typing support' stamp: 'jmv 1/22/2009 12:49'!
dispatchOnCharacter: char with: typeAheadStream
	"Carry out the action associated with this character, if any.
	Type-ahead is passed so some routines can flush or use it."

	| honorCommandKeys |
	((char == Character cr) and: [morph acceptOnCR])
		ifTrue: [
			sensor keyboard.  "Gobble cr -- probably unnecessary."
			self closeTypeIn.
			^ true].

	self clearParens.
  
	char asciiValue = 13 ifTrue: [
		^ sensor controlKeyPressed
			ifTrue: [self normalCharacter: typeAheadStream]
			ifFalse: [self crWithIndent: typeAheadStream]].

	((honorCommandKeys _ Preferences cmdKeysInText) and: [char = Character enter])
		ifTrue: [^ self dispatchOnEnterWith: typeAheadStream].

	"Special keys overwrite crtl+key combinations - at least on Windows. To resolve this
	conflict, assume that keys other than cursor keys aren't used together with Crtl." 
	((self class specialShiftCmdKeys includes: char asciiValue) and: [char asciiValue < 27])
		ifTrue: [^ sensor controlKeyPressed
			ifTrue: [self perform: (ShiftCmdActions at: char asciiValue + 1) with: typeAheadStream]
			ifFalse: [self perform: (CmdActions at: char asciiValue + 1) with: typeAheadStream]].

	"backspace, and escape keys (ascii 8 and 27) are command keys"
	((honorCommandKeys and: [sensor commandKeyPressed]) or: [self class specialShiftCmdKeys includes: char asciiValue]) ifTrue:
		[^ sensor leftShiftDown
			ifTrue: [
				self perform: (ShiftCmdActions at: char asciiValue + 1) with: typeAheadStream]
			ifFalse: [
				self perform: (CmdActions at: char asciiValue + 1) with: typeAheadStream]].

	"the control key can be used to invoke shift-cmd shortcuts"
	(honorCommandKeys and: [sensor controlKeyPressed])
		ifTrue: [
			^ self perform: (ShiftCmdActions at: char asciiValue + 1) with: typeAheadStream].

	(')]}' includes: char)
		ifTrue: [self blinkPrevParen].

	^ self normalCharacter: typeAheadStream! !

OldOneLineEditorMorph removeSelector: #hasCaret!

!CellStyleEntryFieldLW reorganize!
('accessing' editorClass)
('testing')
('stepping and presenter' step)
('editing' handleInteraction:fromEvent:)
('drawing' drawCaretOn:)
!

EntryField2LW removeSelector: #hasCaret!
