--- a/EditField.st Mon May 08 17:19:27 1995 +0200
+++ b/EditField.st Tue May 09 03:57:16 1995 +0200
@@ -10,14 +10,15 @@
hereby transferred.
"
-'From Smalltalk/X, Version:2.10.5 on 4-may-1995 at 8:46:55 am'!
+'From Smalltalk/X, Version:2.10.5 on 9-may-1995 at 12:09:38 pm'!
EditTextView subclass:#EditField
- instanceVariableNames:'leaveAction enabled enableAction crAction tabAction
- converter acceptAction leaveKeys alwaysAccept acceptOnLeave acceptOnReturn'
+ instanceVariableNames:'leaveAction enabled enableAction crAction tabAction converter
+ leaveKeys immediateAccept acceptOnLeave acceptOnReturn
+ lengthLimit'
classVariableNames:'DefaultForegroundColor DefaultBackgroundColor
- DefaultSelectionForegroundColor DefaultSelectionBackgroundColor
- DefaultFont'
+ DefaultSelectionForegroundColor DefaultSelectionBackgroundColor
+ DefaultFont'
poolDictionaries:''
category:'Views-Text'
!
@@ -26,7 +27,7 @@
COPYRIGHT (c) 1990 by Claus Gittinger
All Rights Reserved
-$Header: /cvs/stx/stx/libwidg/EditField.st,v 1.20 1995-05-07 00:15:56 claus Exp $
+$Header: /cvs/stx/stx/libwidg/EditField.st,v 1.21 1995-05-09 01:55:33 claus Exp $
'!
!EditField class methodsFor:'documentation'!
@@ -47,7 +48,7 @@
version
"
-$Header: /cvs/stx/stx/libwidg/EditField.st,v 1.20 1995-05-07 00:15:56 claus Exp $
+$Header: /cvs/stx/stx/libwidg/EditField.st,v 1.21 1995-05-09 01:55:33 claus Exp $
"
!
@@ -56,9 +57,6 @@
an editable text-field. Realized by using an EditTextView,
and forcing its size to 1 line - disabling cursor movement
in the vertical direction.
- An action (leaveAction) is performed when the field is left
- by either Return or a cursor movement, or if 'accept' is
- performed from the menu.
Instance variables:
@@ -70,7 +68,10 @@
enabled <Boolean> if false, input is ignored.
- enableAction <Block | nil>
+ enableAction <Block | nil> action performed if the field is
+ enabled via an explicit click.
+ (this is used by the group to
+ set the active field to the clicked upon field)
crAction <Block | nil> if non-nil, keyboard input of a cr are not
handled specially, instead this block is evaluated
@@ -85,15 +86,13 @@
the object and its printed representation.
Defaults to nil i.e. assume that strings are edited.
- acceptAction <Block | nil> if non-nil, this is performed in addition to
- the leaveAction.
-
leaveKeys <Collection> keys which are interpreted as 'leving the field'
- alwaysAccept <Boolean> if true, every change of the text is immediately
- forwardd to the model/acceptBlock.
- Default is false i.e. only forward changes
- on accept.
+ immediateAccept <Boolean> if true, every change of the text is immediately
+ forwarded to the model/acceptBlock. If false,
+ the changed value is only stored in the model
+ if the field is left or accepted.
+ Default is false.
acceptOnLeave <Boolean> if true, leaving the field (via cursor keys)
automatically accepts the value into the model.
@@ -123,7 +122,9 @@
top open
- forward input in topView to field:
+ forward input in topView to the field:
+ (currently, the field does not know this - therefore,
+ its been told here ... this may change)
|top field|
@@ -134,10 +135,11 @@
field width:1.0. 'let its height as-is'.
top delegate:(KeyboardForwarder toView:field).
+ field hasKeyboardFocus:true.
top open
- just to make it look better: set some inset:
+ to make it look better: set some inset:
|top field|
@@ -168,7 +170,7 @@
top open
- and have it preselected:
+ have it preselected:
|top field|
@@ -201,8 +203,25 @@
top open
+ set a size limit:
+
+ |top field|
+
+ top := StandardSystemView new.
+ top extent:200@100.
+
+ field := EditField origin:0.0@ViewSpacing in:top.
+ field width:1.0.
+ field leftInset:ViewSpacing;
+ rightInset:ViewSpacing.
+ field editValue:'hello';
+ maxChars:8.
+
+ top open
+
+
use a converter:
- - numbers:
+ - numbers (default to 0):
|top field|
@@ -234,13 +253,14 @@
field converter:(PrintConverter new initForDate).
field editValue:Date today.
- field acceptAction:[:value | Transcript show:value class name; space; showCr:value].
+ field acceptAction:[:value | Transcript showCr:value class name , ' ' , value printString].
field crAction:[field accept. top destroy].
top open.
- setting alwaysAccept, makes the field update with every key:
- - numbers:
+ setting immediateAccept, makes the field update with every key:
+
+ - immediate accept numbers, defaulting to nil:
|top field|
@@ -252,8 +272,8 @@
field leftInset:ViewSpacing;
rightInset:ViewSpacing.
- field converter:(PrintConverter new initForNumber).
- field alwaysAccept:true.
+ field converter:(PrintConverter new initForNumberOrNil).
+ field immediateAccept:true.
field editValue:1234.
field acceptAction:[:value | Transcript showCr:value].
field crAction:[field accept. top destroy].
@@ -304,6 +324,27 @@
field2 model:model.
top2 open.
+ with immediate accept:
+
+ |top1 top2 field1 field2 model|
+
+ model := 'hello world' asValue.
+
+ top1 := StandardSystemView new.
+ top1 extent:200@100.
+ field1 := EditField origin:0.0@ViewSpacing in:top1.
+ field1 width:1.0.
+ field1 leftInset:ViewSpacing; rightInset:ViewSpacing.
+ field1 model:model; immediateAccept:true.
+ top1 open.
+
+ top2 := StandardSystemView new.
+ top2 extent:200@100.
+ field2 := EditField origin:0.0@ViewSpacing in:top2.
+ field2 width:1.0.
+ field2 leftInset:ViewSpacing; rightInset:ViewSpacing.
+ field2 model:model; immediateAccept:true.
+ top2 open.
just an example; a checkBox and an editField on the same model:
@@ -329,11 +370,97 @@
top2 open.
model inspect.
+
+
+ connecting fields:
+ update field2 wehenever field1 is changed.
+ (normally, the processing below (xChanged) is done in your application
+ class, or in a complex model. For the demonstration below, we use
+ a Plug to simulate the protocol.)
+
+ |application top field1 field2 value1 value2|
+
+ application := Plug new.
+ application respondTo:#value1Changed
+ with:[value2 value:(value1 value isNil ifTrue:[nil]
+ ifFalse:[value1 value squared])].
+
+ value1 := 1 asValue.
+ value2 := 1 asValue.
+
+ top := Dialog new.
+ top extent:200@200.
+
+ (top addTextLabel:'some number:') layout:#left.
+ top addVerticalSpace.
+
+ (top addInputFieldOn:value1 tabable:false)
+ converter:(PrintConverter new initForNumberOrNil);
+ immediateAccept:true.
+ top addVerticalSpace.
+
+ (top addTextLabel:'squared:') layout:#left.
+ top addVerticalSpace.
+ (top addInputFieldOn:value2 tabable:false)
+ converter:(PrintConverter new initForNumberOrNil).
+
+ value1 onChangeSend:#value1Changed to:application.
+
+ top openModeless.
+
+
+ two-way connect:
+ each field updates the other (notice, that we have to turn off
+ onChange: notification, to avoid an endless notification cycle)
+
+ |application top field1 field2 value1 value2|
+
+ application := Plug new.
+ application respondTo:#value1Changed
+ with:[value2 retractInterrestFor:application.
+ value2 value:(value1 value isNil ifTrue:[nil]
+ ifFalse:[value1 value squared]).
+ value2 onChangeSend:#value2Changed to:application.
+ ].
+ application respondTo:#value2Changed
+ with:[value1 retractInterrestFor:application.
+ value1 value:(value2 value isNil ifTrue:[nil]
+ ifFalse:[value2 value sqrt]).
+ value1 onChangeSend:#value1Changed to:application.
+ ].
+
+ value1 := 1 asValue.
+ value2 := 1 asValue.
+
+ top := Dialog new.
+ top extent:200@200.
+
+ (top addTextLabel:'some number:') layout:#left.
+ top addVerticalSpace.
+
+ (top addInputFieldOn:value1 tabable:false)
+ converter:(PrintConverter new initForNumberOrNil);
+ immediateAccept:true.
+ top addVerticalSpace.
+
+ (top addTextLabel:'squared:') layout:#left.
+ top addVerticalSpace.
+ (top addInputFieldOn:value2 tabable:false)
+ converter:(PrintConverter new initForNumberOrNil).
+
+ value1 onChangeSend:#value1Changed to:application.
+ value2 onChangeSend:#value2Changed to:application.
+
+ top openModeless.
"
! !
!EditField class methodsFor:'defaults'!
+defaultLeaveKeys
+ ^ #(Return CursorUp CursorDown Next Previous Accept)
+!
+
updateStyleCache
DefaultForegroundColor := StyleSheet colorAt:'editFieldForegroundColor' default:Black.
DefaultBackgroundColor := StyleSheet colorAt:'editFieldBackgroundColor' default:White.
@@ -346,32 +473,275 @@
"
!
-defaultLeaveKeys
- ^ #(Return CursorUp CursorDown Next Previous Accept)
-!
-
defaultNumberOfLines
"the number of lines in the field"
^ 1
! !
-!EditField methodsFor:'initialization'!
+!EditField methodsFor:'private'!
+
+textChanged
+ "this is sent by mySelf (somewhere in a superclass) whenever
+ my contents has changed.
+ A good place to add immediateAccept functionality and check for the
+ lengthLimit."
+
+ |string|
+
+ super textChanged.
+ string := self contents.
+ lengthLimit notNil ifTrue:[
+ string size > lengthLimit ifTrue:[
+ self contents:(string := string copyTo:lengthLimit).
+ self flash.
+ ]
+ ].
+ immediateAccept ifTrue:[
+ self accept
+ ]
+!
+
+getListFromModel
+ "redefined to aquire the text via the aspectMsg - not the listMsg,
+ and to ignore updates resulting from my own change."
+
+ "
+ ignore updates from my own change
+ "
+ lockUpdates ifTrue:[
+ lockUpdates := false.
+ ^ self
+ ].
+
+ (model notNil and:[aspectMsg notNil]) ifTrue:[
+ self editValue:(model perform:aspectMsg).
+ ]
+!
+
+startAutoScrollUp:y
+ "no vertical scrolling in editfields"
+
+ ^ self
+!
+
+startAutoScrollDown:y
+ "no vertical scrolling in editfields"
+
+ ^ self
+! !
+
+!EditField methodsFor:'accessing'!
+
+contents
+ "return contents as a string
+ - redefined since EditFields hold only one line of text.
+ In your application, please use #editValue;
+ it uses a converter (if any) and is compatible to ST-80."
+
+ list isNil ifTrue:[^ ''].
+ (list size == 0) ifTrue:[^ ''].
+ ^ list at:1
+!
+
+leaveAction:aBlock
+ "define an action to be evaluated when field is left by return key"
+
+ leaveAction := aBlock
+!
+
+list:someText
+ "redefined to force text to 1 line, and notify dependents
+ of any changed extent-wishes."
+
+ |l oldWidth|
+
+ l := someText.
+ l size > 1 ifTrue:[
+ l := OrderedCollection with:(l at:1)
+ ].
+ oldWidth := self widthOfContents.
+ super list:l.
+ self widthOfContents ~~ oldWidth ifTrue:[
+ self changed:#preferedExtent
+ ]
+!
+
+contents:someText
+ "set the contents from a string
+ - redefined to place the cursor to the end.
+ In your application, please use #editValue:;
+ it uses a converter (if any) and is compatible to ST-80."
+
+ super contents:someText.
+ self cursorCol:(someText size + 1).
+!
+
+enable
+ "enable the field; show cursor and allow input"
+
+ enabled ifFalse:[
+"/ enableAction notNil ifTrue:[
+"/ enableAction value
+"/ ].
+ enabled := true.
+ super showCursor
+ ]
+!
+
+immediateAccept:aBoolean
+ "set/clear the immediateAccept flag. The default is false."
+
+ immediateAccept := aBoolean
+!
+
+editValue
+ "if the field edits a string, this is a name alias for #contents.
+ Otherwise, if there is a converter, return the edited string
+ converted to an appropriate object."
+
+ |string|
+
+ string := self contents.
+ converter isNil ifTrue:[^ string].
+ string isNil ifTrue:[string := ''].
+ ^ converter readValueFrom:string
+!
-initialize
- super initialize.
- self height:(font height + font descent + (topMargin * 2)).
- enabled := true.
- fixedSize := true.
- nFullLinesShown := 1.
- nLinesShown := 1.
- alwaysAccept := false.
- acceptOnLeave := false.
- acceptOnReturn := true.
- leaveKeys := self class defaultLeaveKeys.
- cursorShown := true
+leaveKeys:aCollectionOfKeySymbols
+ "define the set of keys which are interpreted as leaveKeys.
+ I.e. those that make the field inactive and accept (if acceptOnLeave is true).
+ The default is a set of #CursorUp, #CursorDown, #Next, #Prior and #Return."
+
+ leaveKeys := aCollectionOfKeySymbols
+!
+
+initialText:aString selected:aBoolean
+ "set the initialText and select it if aBoolean is true"
+
+ |len s|
+
+ leftOffset := 0.
+ aString isNil ifTrue:[
+ s := nil
+ ] ifFalse:[
+ s := aString asString
+ ].
+ self contents:s.
+ aBoolean ifTrue:[
+ (len := s size) ~~ 0 ifTrue:[
+ self selectFromLine:1 col:1 toLine:1 col:len
+ ]
+ ]
+!
+
+crAction:aBlock
+ "define an action to be evaluated when the return key is pressed."
+
+ crAction := aBlock
+!
+
+tabAction:aBlock
+ "define an action to be evaluated when the tabulator key is pressed."
+
+ tabAction := aBlock
+!
+
+acceptOnReturn:aBoolean
+ "set/clear the acceptOnReturn flag. The default is true."
+
+ acceptOnReturn := aBoolean
+!
+
+initialText:aString
+ "set the initialText and select it"
+
+ self initialText:aString selected:true
+!
+
+editValue:aStringOrObject
+ "set the contents. If there is a converter, use it to convert
+ the object into a printed representation.
+ Otherwise, the argument is supposed to be a string like object,
+ and used directly (i.e. this is equivalent to sending #contents:)."
+
+ self editValue:aStringOrObject selected:false
!
+disable
+ "disable the field; hide cursor and ignore input"
+
+ enabled ifTrue:[
+ enabled := false.
+ self hideCursor
+ ]
+!
+
+editValue:aStringOrObject selected:aBoolean
+ "set the contents. If there is a converter, use it to convert
+ the object into a printed representation.
+ Otherwise, the argument is supposed to be a string like object,
+ and used directly (i.e. this is equivalent to sending #contents:)."
+
+ |string|
+
+ converter notNil ifTrue:[
+ string := converter printStringFor:aStringOrObject
+ ] ifFalse:[
+ string := aStringOrObject.
+ ].
+ self contents:string.
+ aBoolean ifTrue:[
+ self selectFromLine:1 col:1 toLine:1 col:string size
+ ]
+!
+
+acceptOnLeave:aBoolean
+ "set/clear the acceptOnLeave flag. The default is false."
+
+ acceptOnLeave := aBoolean
+!
+
+converter:aConverter
+ "set the converter. If non-nil,
+ the converter is applied to the text to convert from the string
+ representation to the actual object value and vice versa.
+ The default converter is nil, meaning no-conversion
+ (i.e. the edited object is the string itself."
+
+ converter := aConverter
+!
+
+enableAction:aBlock
+ "define an action to be evaluated when enabled by clicking upon"
+
+ enableAction := aBlock
+!
+
+converter
+ "return the converter (if any)."
+
+ ^ converter
+!
+
+maxChars:aNumberOrNil
+ "set the maximum number of characters that are allowed in
+ the field. Additional input will be ignored by the field.
+ A limit of nil means: unlimited. This is the default.
+ This method has been renamed from #lengthLimit: for ST-80
+ compatibility."
+
+ lengthLimit := aNumberOrNil
+!
+
+stringValue
+ "alias for #contents - for ST-80 compatibility"
+
+ ^ self contents
+! !
+
+!EditField methodsFor:'initialization'!
+
initStyle
super initStyle.
@@ -388,6 +758,19 @@
]
!
+initialize
+ super initialize.
+ self height:(font height + font descent + (topMargin * 2)).
+ enabled := true.
+ fixedSize := true.
+ nFullLinesShown := 1.
+ nLinesShown := 1.
+ immediateAccept := acceptOnLeave := false.
+ acceptOnReturn := true.
+ cursorShown := true.
+ leaveKeys := self class defaultLeaveKeys.
+!
+
editMenu
|labels selectors m|
@@ -433,43 +816,6 @@
super realize
! !
-!EditField methodsFor:'private'!
-
-getListFromModel
- "redefined to aquire the text via the aspectMsg - not the listMsg"
-
- |savedCursorCol|
-
- (model notNil and:[aspectMsg notNil]) ifTrue:[
- "
- kludge: editValue positions cursor to beginning
- "
- savedCursorCol := cursorCol.
- self editValue:(model perform:aspectMsg).
- savedCursorCol ~~ 1 ifTrue:[self cursorLine:1 col:savedCursorCol].
- cursorVisibleLine := 1.
- ]
-!
-
-textChanged
- super textChanged.
- alwaysAccept ifTrue:[
- self accept
- ]
-!
-
-startAutoScrollUp:y
- "no vertical scrolling in editfields"
-
- ^ self
-!
-
-startAutoScrollDown:y
- "no vertical scrolling in editfields"
-
- ^ self
-! !
-
!EditField methodsFor:'queries'!
preferedExtent
@@ -488,211 +834,6 @@
^ w @ self height
! !
-!EditField methodsFor:'accessing'!
-
-list:someText
- "redefined to force text to 1 line, and notify dependents
- of any changed extent-wishes."
-
- |l oldWidth|
-
- l := someText.
- l size > 1 ifTrue:[
- l := OrderedCollection with:(l at:1)
- ].
- oldWidth := self widthOfContents.
- super list:l.
- self widthOfContents ~~ oldWidth ifTrue:[
- self changed:#preferedExtent
- ]
-!
-
-contents:someText
- "set the contents from a string
- - redefined to place the cursor to the end.
- In your application, please use #editValue:;
- it uses a converter (if any) and is compatible to ST-80."
-
- super contents:someText.
- self cursorCol:(someText size + 1).
-!
-
-contents
- "return contents as a string
- - redefined since EditFields hold only one line of text.
- In your application, please use #editValue;
- it uses a converter (if any) and is compatible to ST-80."
-
- list isNil ifTrue:[^ ''].
- (list size == 0) ifTrue:[^ ''].
- ^ list at:1
-!
-
-enable
- "enable the field; show cursor and allow input"
-
- enabled ifFalse:[
- enableAction notNil ifTrue:[
- enableAction value
- ].
- enabled := true.
- super showCursor
- ]
-!
-
-leaveAction:aBlock
- "define an action to be evaluated when field is left by return key"
-
- leaveAction := aBlock
-!
-
-leaveKeys:aCollectionOfKeySymbols
- "define the set of keys which are interpreted as leaveKeys.
- I.e. those that make the field inactive and accept (if acceptOnLeave is true).
- The default is a set of #CursorUp, #CursorDown, #Next, #Prior and #Return."
-
- leaveKeys := aCollectionOfKeySymbols
-!
-
-crAction:aBlock
- "define an action to be evaluated when the return key is pressed."
-
- crAction := aBlock
-!
-
-acceptAction:aBlock
- "define an action to be evaluated when accepted."
-
- acceptAction := aBlock
-!
-
-tabAction:aBlock
- "define an action to be evaluated when the tabulator key is pressed."
-
- tabAction := aBlock
-!
-
-alwaysAccept:aBoolean
- "set/clear the alwaysAccept flag. The default is false."
-
- alwaysAccept := aBoolean
-!
-
-acceptOnReturn:aBoolean
- "set/clear the acceptOnReturn flag. The default is true."
-
- acceptOnReturn := aBoolean
-!
-
-acceptOnLeave:aBoolean
- "set/clear the acceptOnLeave flag. The default is false."
-
- acceptOnLeave := aBoolean
-!
-
-converter
- "return the converter (if any)."
-
- ^ converter
-!
-
-editValue
- "if the field edits a string, this is a name alias for #contents.
- Otherwise, if there is a converter, return the edited string
- converted to an appropriate object."
-
- |text|
-
- text := self contents.
- converter isNil ifTrue:[^ text].
- ^ converter readValueFrom:text withoutSpaces
-!
-
-editValue:aStringOrObject
- "set the contents. If there is a converter, use it to convert
- the object into a printed representation.
- Otherwise, the argument is supposed to be a string like object,
- and used directly (i.e. this is equivalent to sending #contents:)."
-
- self editValue:aStringOrObject selected:false
-!
-
-editValue:aStringOrObject selected:aBoolean
- "set the contents. If there is a converter, use it to convert
- the object into a printed representation.
- Otherwise, the argument is supposed to be a string like object,
- and used directly (i.e. this is equivalent to sending #contents:)."
-
- |text|
-
- converter notNil ifTrue:[
- text := converter printStringFor:aStringOrObject
- ] ifFalse:[
- text := aStringOrObject.
- ].
- self contents:text.
- aBoolean ifTrue:[
- self selectFromLine:1 col:1 toLine:1 col:text size
- ]
-!
-
-converter:aConverter
- "set the converter. If non-nil,
- the converter is applied to the text to convert from the string
- representation to the actual object value and vice versa.
- The default converter is nil, meaning no-conversion
- (i.e. the edited object is the string itself."
-
- converter := aConverter
-!
-
-
-disable
- "disable the field; hide cursor and ignore input"
-
- enabled ifTrue:[
- enabled := false.
- self hideCursor
- ]
-!
-
-enableAction:aBlock
- "define an action to be evaluated when enabled by clicking upon"
-
- enableAction := aBlock
-!
-
-initialText:aString selected:aBoolean
- "set the initialText and select it if aBoolean is true"
-
- |len s|
-
- leftOffset := 0.
- self contents:(s := aString asString).
- aBoolean ifTrue:[
- (len := s size) ~~ 0 ifTrue:[
- self selectFromLine:1 col:1 toLine:1 col:len
- ]
- ]
-!
-
-initialText:aString
- "set the initialText and select it"
-
- self initialText:aString selected:true
-! !
-
-!EditField methodsFor:'editing'!
-
-paste:someText
- "redefined to force text to 1 line"
-
- super paste:someText.
- list size > 1 ifTrue:[
- self deleteFromLine:2 toLine:(list size)
- ]
-! !
-
!EditField methodsFor:'cursor drawing'!
showCursor
@@ -704,6 +845,21 @@
!EditField methodsFor:'cursor movement'!
+cursorCol:col
+ "redefined to lock the cursor at the end, if I have a lngthLimit"
+
+ |c sz|
+
+ c := col.
+ lengthLimit notNil ifTrue:[
+ sz := lengthLimit.
+ c > sz ifTrue:[
+ c := sz+1.
+ ]
+ ].
+ super cursorCol:c
+!
+
cursorLine:line col:col
"catch cursor movement"
@@ -720,19 +876,105 @@
!EditField methodsFor:'event handling'!
-accept
- "accept the fields contents - perform the leave action as if
- return was pressed."
+keyPress:key x:x y:y
+ "if keyHandler is defined, pass input; otherwise check for leave
+ keys"
+
+ |leave xCol newOffset oldWidth newWidth|
+
+ enabled ifFalse:[
+ ^ self
+ ].
+
+ (key == #DeleteLine) ifTrue:[
+ Smalltalk at:#CopyBuffer put:(self contents).
+ self contents:''. ^ self
+ ].
- |value|
+ (key == #Tab) ifTrue:[
+ tabAction notNil ifTrue:[tabAction value. ^ self].
+ ].
+ (key == #Return) ifTrue:[
+ crAction notNil ifTrue:[crAction value. ^ self].
+ ].
+ leave := leaveKeys includes:key.
+ leave ifTrue:[
+ leaveAction notNil ifTrue:[
+ leaveAction value:key
+ ].
- value := self editValue.
- acceptAction notNil ifTrue:[
- acceptAction value:value
+ ((key == #Return and:[acceptOnReturn])
+ or:[key ~~ #Return and:[acceptOnLeave]]) ifTrue:[
+ self accept.
+ ].
+
+ x >= 0 ifTrue:[
+ "
+ let superview know about the leave ...
+ This is a temporary kludge for the tableWidget -
+ it is no clean coding style. Should make the tableWidget
+ a proper model and handle it via the changed mechanism ....
+ "
+ (superView notNil and:[superView canHandle:key from:self]) ifTrue:[
+ superView keyPress:key x:x y:y.
+ ].
+ ].
+ ^ self
].
- "model-view behavior"
- self sendChangeMessageWith:value.
+ "
+ ignore some keys (if not a leaveKey) ...
+ "
+ (key == #Find) ifTrue:[^self].
+ (key == #FindNext) ifTrue:[^self].
+ (key == #FindPrev) ifTrue:[^self].
+ (key == #GotoLine) ifTrue:[^self].
+
+ "
+ a normal key - let superclass's method insert it
+ "
+ oldWidth := self widthOfContents.
+ super keyPress:key x:x y:y.
+
+ "
+ for end-of-text, also move to end-of-line
+ "
+ key == #EndOfText ifTrue:[
+ super keyPress:#EndOfLine x:x y:y.
+ ].
+ newWidth := self widthOfContents.
+
+ "
+ should (& can) we resize ?
+ "
+ xCol := (self xOfCol:cursorCol inVisibleLine:cursorLine) - leftOffset.
+ (xCol > (width * (5/6))) ifTrue:[
+ self changed:#preferedExtent
+ ] ifFalse:[
+ newWidth < (width * (1/6)) ifTrue:[
+ self changed:#preferedExtent
+ ]
+ ].
+
+ "
+ did someone react ?
+ (if not, we scroll horizontally)
+ "
+ xCol := (self xOfCol:cursorCol inVisibleLine:cursorLine) - leftOffset.
+ (xCol > (width * (5/6))) ifTrue:[
+ newOffset := leftOffset + (width // 2).
+ ] ifFalse:[
+ (xCol < (width * (1/6))) ifTrue:[
+ newOffset := 0 max: leftOffset - (width // 2).
+ ] ifFalse:[
+ newOffset := leftOffset
+ ]
+ ].
+ newOffset ~~ leftOffset ifTrue:[
+ leftOffset := newOffset.
+ self clear.
+ self redraw
+ ]
!
buttonPress:button x:x y:y
@@ -749,98 +991,18 @@
]
!
-keyPress:key x:x y:y
- "if keyHandler is defined, pass input; otherwise check for leave
- keys"
-
- |leave xCol newOffset oldWidth newWidth|
+focusIn
+ "got the explicit focus"
enabled ifFalse:[
- ^ self
- ].
-
- (key == #DeleteLine) ifTrue:[
- Smalltalk at:#CopyBuffer put:(self contents).
- self contents:''. ^ self
- ].
-
- (key == #Tab) ifTrue:[
- tabAction notNil ifTrue:[tabAction value. ^ self].
- ].
- (key == #Return) ifTrue:[
- crAction notNil ifTrue:[crAction value. ^ self].
- ].
- leave := leaveKeys includes:key.
- leave ifTrue:[
- leaveAction notNil ifTrue:[
- leaveAction value:key
- ].
-
- ((key == #Return and:[acceptOnReturn])
- or:[key ~~ #Return and:[acceptOnLeave]]) ifTrue:[
- self accept.
- ].
-
- x >= 0 ifTrue:[
- "
- let superview know about the leave ...
- This is a temporary kludge for the tableWidget -
- it is no clean coding style. Should make the tableWidget
- a proper model and handle it via the changed mechanism ....
- "
- (superView notNil and:[superView canHandle:key from:self]) ifTrue:[
- superView keyPress:key x:x y:y.
- ].
- ].
- ^ self
+ enabled := true.
+ super focusIn.
+ enableAction notNil ifTrue:[
+ enableAction value
+ ]
+ ] ifTrue:[
+ super focusIn
].
-
- "
- ignore some keys (if not a leaveKey) ...
- "
- (key == #Find) ifTrue:[^self].
- (key == #FindNext) ifTrue:[^self].
- (key == #FindPrev) ifTrue:[^self].
- (key == #GotoLine) ifTrue:[^self].
-
- "
- a normal key - let superclass's method insert it
- "
- oldWidth := self widthOfContents.
- super keyPress:key x:x y:y.
- newWidth := self widthOfContents.
-
- "
- should (& can) we resize ?
- "
- xCol := (self xOfCol:cursorCol inVisibleLine:cursorLine) - leftOffset.
- (xCol > (width * (5/6))) ifTrue:[
- self changed:#preferedExtent
- ] ifFalse:[
- newWidth < (width * (1/6)) ifTrue:[
- self changed:#preferedExtent
- ]
- ].
-
- "
- did someone react ?
- (if not, we scroll horizontally)
- "
- xCol := (self xOfCol:cursorCol inVisibleLine:cursorLine) - leftOffset.
- (xCol > (width * (5/6))) ifTrue:[
- newOffset := leftOffset + (width // 2).
- ] ifFalse:[
- (xCol < (width * (1/6))) ifTrue:[
- newOffset := 0 max: leftOffset - (width // 2).
- ] ifFalse:[
- newOffset := leftOffset
- ]
- ].
- newOffset ~~ leftOffset ifTrue:[
- leftOffset := newOffset.
- self clear.
- self redraw
- ]
!
canHandle:aKey
@@ -848,7 +1010,20 @@
(usually from another view, when the receiver is part of
a more complex dialog box).
We do return true here, since the editfield will handle
- all keys."
+ all keys.
+ OBSOLETE: dont use this anymore - its a leftover for the tableWidget"
^ true
! !
+
+!EditField methodsFor:'editing'!
+
+paste:someText
+ "redefined to force text to 1 line"
+
+ super paste:someText.
+ list size > 1 ifTrue:[
+ self deleteFromLine:2 toLine:(list size)
+ ]
+! !
+