'From Squeak3.7 of ''4 September 2004'' [latest update: #5989] on 12 May 2008 at 2:41:55 am'!
!classDefinition: #EntryFieldLW category: #'LightWidgets-Kernel'!
LightWidget subclass: #EntryFieldLW
	instanceVariableNames: 'stringPosition cursorBounds cursorPosition stringBounds selection selectionBounds selectionDirection entryMask color hideValue '
	classVariableNames: ''
	poolDictionaries: ''
	category: 'LightWidgets-Kernel'!

!EntryFieldLW methodsFor: 'accessing'!
backgroundColor
	^ Color white ! !

!EntryFieldLW methodsFor: 'accessing'!
borderColor
	^ Color black ! !

!EntryFieldLW methodsFor: 'accessing'!
borderWidth
	^ 2.0 ! !

!EntryFieldLW methodsFor: 'accessing'!
centered
	stringPosition _ #centered.
	self updateView
 ! !

!EntryFieldLW methodsFor: 'accessing'!
cursorColor
	^ Color green darker! !

!EntryFieldLW methodsFor: 'accessing'!
entryMask: mask
	entryMask _  mask ! !

!EntryFieldLW methodsFor: 'accessing'!
extent: aPoint
	super extent: aPoint.
	self updateView 
	
	
	
! !

!EntryFieldLW methodsFor: 'accessing'!
font
	^ self defaultFont ! !

!EntryFieldLW methodsFor: 'accessing' stamp: 'F Olivero 5/12/2008 02:04'!
hideValue
	hideValue _ true.
	self updateView! !

!EntryFieldLW methodsFor: 'accessing'!
left
	stringPosition _ #left. 
	self updateView
	
! !

!EntryFieldLW methodsFor: 'accessing'!
position: aPoint
	super position: aPoint.
	self updateView 
	
	
! !

!EntryFieldLW methodsFor: 'accessing'!
right
	stringPosition _ #rigth.
	self updateView ! !

!EntryFieldLW methodsFor: 'accessing'!
showValue
	hideValue _ false.
	self updateView! !

!EntryFieldLW methodsFor: 'accessing'!
value
	(self target notNil and:[ aspect notNil] ) ifTrue:[ ^ self targetAspect] ifFalse:[ ^ ''] ! !

!EntryFieldLW methodsFor: 'testing'!
hasSelection
	^ selection extent  >= 0 ! !

!EntryFieldLW methodsFor: 'testing'!
isValid
	^ self value notEmpty "and:[entryMask validate: self value]" ! !

!EntryFieldLW methodsFor: 'user actions'!
backspaceEntered
	| h t string |
	string _ self value.
	(cursorPosition = 1 or:[string isEmpty]) ifTrue:[^self].
	self hasSelection 
		ifTrue:[ 
			h _ string copyFrom: 1 to: selection first -1.
			t _ string copyFrom: selection last + 1 to: string size.
			cursorPosition _  h size + 1.
			selection _ cursorPosition to: (cursorPosition -1)]
		ifFalse:[
			h _ string copyFrom: 1 to: cursorPosition - 2.
			t _  string copyFrom: cursorPosition to: string size.
			self moveCursorBack].
	string _ h , t.
	self performActionWith: string  ! !

!EntryFieldLW methodsFor: 'user actions'!
characterEntered:  char
	| string h t newValue valid |
	string _ self value.
	self hasSelection
		ifTrue:[ h _string copyFrom: 1 to: selection first -1. 
				t _ string copyFrom: selection last +1 to: string size. 
				h _ h , (Array with: char)]
		ifFalse:[	h _ string. t _ Array with: char].
	newValue _ h , t.
	entryMask notNil
				ifTrue:[valid _ entryMask validate: newValue.  valid ifFalse:[ ^ Beeper beep]].
	self hasSelection 
		ifTrue:[cursorPosition _ selection first  +1 ]
		ifFalse:[	cursorPosition _ cursorPosition + 1].
	self clearSelection.
	self performActionWith: newValue 
	
	
	
	
	
	
	

	 
	
	! !

!EntryFieldLW methodsFor: 'user actions'!
clearSelection
	"Juan: if you decide to add updateView here, look out..some senders most likley will send an updateView later, after this...two timer invoked the message updateView..."
	selection _ cursorPosition to: (cursorPosition -1)
	! !

!EntryFieldLW methodsFor: 'user actions'!
deleteEntered
	| h t string |
	string _ self value.
	(string isEmpty or:[cursorPosition = (string size + 1)]) ifTrue:[^self].
	self hasSelection 
		ifTrue:[ 
			h _ string copyFrom: 1 to: selection first -1.
			t _ string copyFrom: selection last + 1 to: string size.
			cursorPosition _  h size + 1.
			selection _ cursorPosition to: (cursorPosition -1)]
		ifFalse:[
			h _ string copyFrom: 1 to: cursorPosition - 1.
			t _  string copyFrom: cursorPosition + 1 to: string size].
	string _ h , t.
	self performActionWith: string
	 ! !

!EntryFieldLW methodsFor: 'user actions'!
escapeEntered
	self clearSelection; updateView! !

!EntryFieldLW methodsFor: 'user actions'!
moveCursorBack
	cursorPosition _ 1 max: cursorPosition - 1.
	self clearSelection. 
	self updateView ! !

!EntryFieldLW methodsFor: 'user actions'!
moveCursorForth
	cursorPosition  = (self value size + 1) ifTrue:[ ^self].
	cursorPosition _ cursorPosition + 1.
	self clearSelection; updateView
 ! !

!EntryFieldLW methodsFor: 'user actions'!
moveCursorSelectionBack
	| end start |
	start _ selection first.
	end _ selection last.
	selectionDirection == #right 
			ifTrue:[ end _ end - 1]
			ifFalse:[	start _ 1 max:  start  - 1].
	selection _ start to: end.
	cursorPosition _ 1 max: cursorPosition - 1.
	self updateView 
				  
				 ! !

!EntryFieldLW methodsFor: 'user actions'!
moveCursorToBeggining
	self clearSelection.
	cursorPosition _ 1.
	self updateView 
! !

!EntryFieldLW methodsFor: 'user actions'!
moveCursorToEnd
	self clearSelection.
	cursorPosition _ self value size + 1.
	self updateView 
! !

!EntryFieldLW methodsFor: 'user actions'!
separatorEntered: char
	char = Character space
		ifTrue:[ self characterEntered: char] 
		ifFalse:[ Beeper beep]
 ! !

!EntryFieldLW methodsFor: 'events-processing'!
keyStroke: evt
	| c |
	super  keyStroke: evt.
	evt commandKeyPressed  ifTrue:[^self].
	target isNil ifTrue:[ ^ self].
	c _ evt keyCharacter.
	( evt shiftPressed and:[ c isLetter not] ) ifTrue:[^ self selectionChanged: evt].
	c = Character arrowRight ifTrue:[^ self moveCursorForth].
	c = Character arrowLeft ifTrue:[ ^ self moveCursorBack].
	c = Character backspace ifTrue:[^ self backspaceEntered].
	c = Character delete ifTrue:[^self deleteEntered].
	c = Character end ifTrue:[ ^ self moveCursorToEnd].
	c = Character home ifTrue:[ ^ self moveCursorToBeggining].
	c  = Character escape ifTrue:[^ self escapeEntered].
	c isSeparator ifTrue:[^self separatorEntered:c].	
	self characterEntered: c
 
! !

!EntryFieldLW methodsFor: 'events-processing'!
selectionChanged: evt
	| c string |
	c _ evt keyCharacter.
	string _ self value.
	self hasSelection 
		ifTrue:[
				c == Character arrowRight ifTrue:[self moveCursorSelectionForth].
				c == Character arrowLeft ifTrue:[ self moveCursorSelectionBack]]
		 ifFalse:[			
				(c == Character arrowRight and:[cursorPosition ~= (string size + 1)] )
					ifTrue:[ selectionDirection _ #right.  self moveCursorSelectionForth ].
				(c == Character arrowLeft and:[ cursorPosition ~= 1])
					ifTrue:[ selectionDirection _ #left. self moveCursorSelectionBack]] .
		
	c == Character end
		ifTrue:[	selectionDirection _ #right. 
				selection  _ selection first to: string size. 
				cursorPosition _ self value size + 1].
			
	c == Character home 
		 ifTrue:[ selectionDirection _ #left. 
				selection  _ 1 to: selection last.
				 cursorPosition _ 1].
			
	 self updateView

		! !

!EntryFieldLW methodsFor: 'event handling'!
handlesKeyboard: evt
	^ true ! !

!EntryFieldLW methodsFor: 'private'!
stringPosition
	| xOffset  bw f string |
	bw _ self borderWidth.
	f _ self font.
	string _ self value.
	stringPosition = #rigth ifTrue:[xOffset _  bounds extent x - bw - (f widthOfString: string)].
	stringPosition = #left ifTrue:[xOffset _  bw + 1].
	stringPosition = #centered ifTrue:[	xOffset  _ bw  + ((f widthOfString: string) /2)].
	^  bounds origin  +  (xOffset@bw)	 
		

		

	! !

!EntryFieldLW methodsFor: 'private'!
wantsKeyboardFocusFor:  stringMorph
	^true ! !

!EntryFieldLW methodsFor: 'initialization'!
initialize
	super initialize.
	bounds _ 20@20 extent: 100@(self font height + (2 * self borderWidth)).
	cursorPosition _ 1.
	selection _ 1 to: 0. 
	stringPosition _ #left.
	color _ Color black.
	hideValue _ false! !

!EntryFieldLW methodsFor: 'drawing'!
drawOn: aCanvas
	| string leftX w cColor borderWidth  stringBounds font xOffset xExtent selectionBounds orig ext cursorBounds str |
	borderWidth _ self borderWidth.
	aCanvas frameAndFillRectangle: bounds fillColor: self backgroundColor borderWidth: borderWidth borderColor: self borderColor.

	self isValid ifFalse:[aCanvas fillRectangle: bounds  color: (Color red alpha:0.4)].
 
	string _ self value.
	stringBounds _ self stringPosition extent: bounds extent - (2* borderWidth). 
	hideValue ifTrue:[ str _ string collect:[:char| $*]] ifFalse:[ str_ string].
	aCanvas drawString: str in: stringBounds font: self font color: color.

	self hasSelection
		ifTrue:[ 
			font _ self font.
			xOffset _ 0.
			(1 to: selection first - 1) do:[:i| xOffset _  xOffset + (font widthOf: (string at:i))].
			xExtent _ 0.
			 selection do:[:i|  xExtent _ xExtent + (font widthOf: (string at:i))]. 
			selectionBounds _  (stringBounds origin +(xOffset@0) ) extent: (xExtent@ stringBounds extent y).
			aCanvas fillRectangle: selectionBounds color: (Color green lighter alpha:0.5)]. 
	
	
	xOffset _ 0. 
	font _ self font.
	(string notNil and:[string notEmpty ])
		ifTrue:[	(0 to: cursorPosition -2 ) do:[:i|  xOffset _ xOffset + (font widthOf: (string at:i+1))]].	
	orig _ self stringPosition + (xOffset@0).
	ext _  2@ stringBounds extent y.
	cursorBounds _ orig extent: ext.
	leftX _ cursorBounds origin x + (cursorBounds extent x / 2).
	w := 4.
	cColor :=  self cursorColor.
	1 to: w
		do: 
			[:i | 
				aCanvas fillRectangle: ((leftX - w + i - 1) @ (cursorBounds origin y + i - 1) 
								extent: ((w - i) * 2 + 3) @ 1)
						color: cColor.
					aCanvas fillRectangle: ((leftX - w + i - 1) @ (cursorBounds origin y + cursorBounds extent y - i) 
								extent: ((w - i) * 2 + 3) @ 1)
						color: cColor].
			aCanvas fillRectangle: cursorBounds color: cColor
	
			
	! !


!NameEntryLW methodsFor: 'event handlers' stamp: 'F Olivero 5/12/2008 02:21'!
centered
	entry centered! !

!NameEntryLW methodsFor: 'event handlers'!
leftJustified
	entry left! !

!NameEntryLW methodsFor: 'event handlers' stamp: 'F Olivero 5/12/2008 02:21'!
rightJustified
	entry right! !

!NameEntryLW methodsFor: 'initialization'!
addSubmorphs
	| l left c right |
	entry _ EntryFieldLW new.
	entry position: 30@15; extent:200@30.
	self addMorph: entry.

	left _ ButtonLW target: self action: #leftJustified label:  'left justified'.
	left position: 15@(15+30+10); extent: 150@25.
	self addMorph: left.

	c _ ButtonLW target: self action: #centered label:  'centered'.
	c position: (15+155)@(15+30+10); extent: 100@25.
	self addMorph: c.

	right _ ButtonLW target: self action: #rightJustified label:  'right justified'.
	right position: (15+155+105)@(15+30+10); extent: 150@25.
	self addMorph: right.

	l _ LabelLW label:  'Entered name:'.
	l position: 15@(15+30+10+30); extent: 200@25.
	self addMorph: l.
	
	name _ LabelLW new target:  target  aspect: #name.
	name position: 30@(15+30+10+30+30); extent: 200@25.
	self addMorph: name.
	
	self updateView
	
	! !

!NameEntryLW methodsFor: 'initialization'!
initialize
	super initialize.
	bounds _ 10@10 extent: 450@150.
	self addSubmorphs. 
	! !


!NameEntryLW reorganize!
('updating' updateEntry updateName updateView)
('event handlers' centered leftJustified rightJustified)
('initialization' addSubmorphs initialize)
!

EntryFieldLW removeSelector: #updateCursor!
EntryFieldLW removeSelector: #updateSelection!
EntryFieldLW removeSelector: #updateString!
EntryFieldLW removeSelector: #updateView!
!classDefinition: #EntryFieldLW category: #'LightWidgets-Kernel'!
LightWidget subclass: #EntryFieldLW
	instanceVariableNames: 'stringPosition cursorPosition selection selectionDirection color entryMask hideValue'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'LightWidgets-Kernel'!

!EntryFieldLW reorganize!
('accessing' backgroundColor borderColor borderWidth centered cursorColor entryMask: extent: font hideValue left position: right showValue value)
('testing' hasSelection isValid)
('user actions' backspaceEntered characterEntered: clearSelection deleteEntered escapeEntered moveCursorBack moveCursorForth moveCursorSelectionBack moveCursorSelectionForth moveCursorToBeggining moveCursorToEnd separatorEntered:)
('events-processing' keyStroke: selectionChanged:)
('event handling' handlesKeyboard:)
('private' stringPosition wantsKeyboardFocusFor:)
('initialization' initialize)
('drawing' drawOn:)
!

