.
--- a/DialogBox.st Sat May 06 16:18:13 1995 +0200
+++ b/DialogBox.st Sun May 07 02:16:56 1995 +0200
@@ -25,7 +25,7 @@
version
"
-$Header: /cvs/stx/stx/libwidg/DialogBox.st,v 1.10 1995-05-06 14:16:36 claus Exp $
+$Header: /cvs/stx/stx/libwidg/DialogBox.st,v 1.11 1995-05-07 00:15:45 claus Exp $
"
!
@@ -41,6 +41,9 @@
in a top-to-bottom fashion, and also keep track of added text-fields and,
since they are most common, automatically create an EnterFieldGroup for
them.
+ Caveat: more adding support is required - especially for row-wise
+ construction.
+
instance variables:
@@ -97,6 +100,10 @@
DialogBox new addAbortButton; addOkButton; open
+ with different ok-label:
+
+ DialogBox new addAbortButton; addOkButtonLabelled:'yeah'; open
+
adding a textlabel gives an infoBox:
DialogBox new
@@ -122,6 +129,18 @@
addOkButton;
open
+ with modified buttons:
+
+ |box|
+
+ box := DialogBox new.
+ (box addTextLabel:'are you certain ?') adjust:#left.
+ box addAbortButtonLabelled:'not really'.
+ (box addOkButtonLabelled:'yes, absolutely')
+ activeBackgroundColor:Color red.
+ box open
+
+
two textlabels:
DialogBox new
@@ -164,7 +183,6 @@
DialogBox new
addTextLabel:(Image fromFile:'bitmaps/garfield.gif');
- addAbortButton;
addOkButton;
open
@@ -202,6 +220,7 @@
(DialogBox new
addTextLabel:'Please enter your name:';
addInputFieldOn:firstName;
+ addVerticalSpace;
addInputFieldOn:lastName;
addAbortButton;
addOkButton;
@@ -234,6 +253,7 @@
(DialogBox new
addTextLabel:'Please enter your name:';
addInputFieldOn:firstName;
+ addVerticalSpace;
addInputFieldOn:lastName;
addAbortButton;
addOkButton;
@@ -680,7 +700,7 @@
"user pressed ok-button; make myself invisible and if an action was
specified do it"
- okButton turnOffWithoutRedraw.
+ okButton notNil ifTrue:[okButton turnOffWithoutRedraw].
self accept.
self hideAndEvaluate:okAction.
!
@@ -713,43 +733,71 @@
buttonPanel subViews size > 1 ifTrue:[
buttonPanel layout:#fitSpace.
].
+ ^ aButton
!
-addOkButton:action
+addOkButtonLabelled:buttonLabel
+ "create an okButton with a label - to be sent from redefined initialize
+ methods in subclasses or when creating a box programmatically.
+ A nil argument creates one with the default text.
+ Returns the button."
+
+ okButton := Button okButton.
+ okButton model:self; change:#okPressed.
+ buttonLabel notNil ifTrue:[okButton label:buttonLabel].
+ okButton isReturnButton:acceptReturnAsOK.
+ ^ self addButton:okButton.
+!
+
+XXaddOkButton:action
"create an okButton - to be sent from redefined initialize
- methods in subclasses."
+ methods in subclasses or when creating a box programmatically."
okButton := Button okButton.
action notNil ifTrue:[okButton action:action].
okButton model:self; change:#okPressed.
okButton isReturnButton:acceptReturnAsOK.
- self addButton:okButton.
+ ^ self addButton:okButton.
!
addOkButton
"create an okButton - to be sent from redefined initialize
- methods in subclasses."
+ methods in subclasses or when creating a box programmatically.
+ Returns the button."
- self addOkButton:nil
+ ^ self addOkButtonLabelled:nil
!
addButton:aButton
- "add a button in the buttonPanel"
+ "add a button into the buttonPanel.
+ Returns the button."
+
+ ^ self addButton:aButton after:nil
+!
- self addButton:aButton after:nil
+addAbortButtonLabelled:buttonLabel
+ "create an abortButton with a label - to be sent from redefined initialize
+ methods in subclasses or when creating a box programmatically.
+ A nil argument creates one with the default label.
+ Returns the button."
+
+ abortButton := Button abortButton.
+ abortButton model:self; change:#abortPressed.
+ buttonLabel notNil ifTrue:[abortButton label:buttonLabel].
+ ^ self addButton:abortButton.
!
addAbortButton
"create an abortButton - to be sent from redefined initialize
- methods in subclasses."
+ methods in subclasses or when creating a box programmatically.
+ Returns the button."
- abortButton := Button abortButton.
- abortButton model:self; change:#abortPressed.
- self addButton:abortButton.
+ ^ self addAbortButtonLabelled:nil
!
addComponent:aComponent withHeight:height
- "add a component with some given height and full width"
+ "add a component with some given height and full width.
+ Returns the component."
self basicAddComponent:aComponent.
aComponent height:height.
@@ -758,10 +806,12 @@
leftInset:leftIndent+ViewSpacing;
rightInset:ViewSpacing.
yPosition := yPosition + aComponent height.
+ ^ aComponent
!
addComponent:aComponent withExtent:ext
- "add a component with some given extent"
+ "add a component with some given extent.
+ Returns the component."
self basicAddComponent:aComponent.
aComponent extent:ext.
@@ -769,18 +819,21 @@
leftInset:leftIndent;
rightInset:ViewSpacing.
yPosition := yPosition + aComponent height.
+ ^ aComponent
!
addComponent:aComponent
- "add a component with its prefered height and full width"
+ "add a component with its prefered height and full width.
+ Returns the component."
- self addComponent:aComponent
+ ^ self addComponent:aComponent
withHeight:(aComponent preferedExtent y).
!
addTextLabel:aString
"create a text label - the name has been choosen for ST-80 compatibility;
- however, ST/X labels allow image labels too."
+ however, ST/X labels allow image labels too.
+ Returns the label."
|l|
@@ -844,6 +897,9 @@
!
addCheckBox:label on:aModel
+ "create a checkBox with label on aModel and add it.
+ Returns the box."
+
|b|
b := CheckBox on:aModel.
@@ -852,23 +908,10 @@
^ b
!
-addVerticalSpace:nPixel
- yPosition := yPosition + nPixel.
-!
-
-yPosition
- ^ yPosition
-!
+addInputField:aField
+ "add an already created input field; return the field.
+ Returns the field."
-yPosition:aNumber
- yPosition := aNumber.
-!
-
-leftIndent:aNumber
- leftIndent := aNumber.
-!
-
-addInputField:aField
self addComponent:aField.
inputFieldGroup isNil ifTrue:[
inputFieldGroup := EnterFieldGroup new.
@@ -881,6 +924,9 @@
!
addInputFieldOn:aModel
+ "create an input field on aModel and add it.
+ Returns the field."
+
|f|
f := EditField new.
@@ -901,6 +947,39 @@
dialog open.
ok ifTrue:[Transcript showCr:model value].
"
+!
+
+addVerticalSpace
+ "add a default vertical space (1 mm)"
+
+ self addVerticalSpace:(ViewSpacing).
+!
+
+addVerticalSpace:nPixel
+ "add some pixels of space to the next component"
+
+ yPosition := yPosition + nPixel.
+!
+
+yPosition
+ "return the current y position (thats where the next component
+ will be located)."
+
+ ^ yPosition
+!
+
+yPosition:aNumber
+ "set the current y position (thats where the next component
+ will be located)."
+
+ yPosition := aNumber.
+!
+
+leftIndent:aNumber
+ "set the left indent (current x position - thats where the next component
+ will be located)."
+
+ leftIndent := aNumber.
! !
!DialogBox methodsFor:'initialization'!
@@ -925,7 +1004,7 @@
borderWidth:0;
layout:#spread.
- yPosition := 0.
+ yPosition := ViewSpacing.
leftIndent := 0.
"
@@ -1006,8 +1085,7 @@
] ifFalse:[
w := super preferedExtent x.
].
- h := ViewSpacing
- + yPosition
+ h := yPosition
+ ViewSpacing.
okButton notNil ifTrue:[
@@ -1145,4 +1223,3 @@
shown ifTrue:[self resize]
]
! !
-
--- a/EFGroup.st Sat May 06 16:18:13 1995 +0200
+++ b/EFGroup.st Sun May 07 02:16:56 1995 +0200
@@ -11,7 +11,8 @@
"
Object subclass:#EnterFieldGroup
- instanceVariableNames:'fields currentField leaveAction'
+ instanceVariableNames:'fields currentField leaveAction
+ wrap'
classVariableNames:''
poolDictionaries:''
category:'Views-Support'
@@ -21,7 +22,7 @@
COPYRIGHT (c) 1992 by Claus Gittinger
All Rights Reserved
-$Header: /cvs/stx/stx/libwidg/Attic/EFGroup.st,v 1.8 1995-05-06 14:16:40 claus Exp $
+$Header: /cvs/stx/stx/libwidg/Attic/EFGroup.st,v 1.9 1995-05-07 00:15:50 claus Exp $
'!
!EnterFieldGroup class methodsFor:'documentation'!
@@ -42,7 +43,7 @@
version
"
-$Header: /cvs/stx/stx/libwidg/Attic/EFGroup.st,v 1.8 1995-05-06 14:16:40 claus Exp $
+$Header: /cvs/stx/stx/libwidg/Attic/EFGroup.st,v 1.9 1995-05-07 00:15:50 claus Exp $
"
!
@@ -58,12 +59,38 @@
field of the group is left (by cursor-down or cr).
Usually this block triggers accept on the fields and/or performs some
followup processing and closes the topview (for example: in a dialog).
+
+ EnterFieldGroups can be used as a delegate (of the topView) to forward
+ input (entered into the topView) to the currently active field.
+
+ Stepping to previous field is via CursorUp/PreviousField,
+ to next field via CursorDown/NextField/Tab.
+ Notice, that by default, the editField takes the tab-character as
+ a normal character. To step using tab, you have to add the Tab key to the
+ fields leaveKeys.
+
+ Instance variables:
+
+ fields <Collection of EditField> the fields of the group
+
+ currentField <EditField> the active field
+
+ leaveAction <nil|Block> action to perform, when the
+ last field is left by a non-wrap
+
+ wrap <Boolean> if true, non-return next-keys wrap
+ back to the first field.
+ If false (the default), next in
+ the last field is taken as return.
+ This is ignored, if no leaveAction was
+ defined.
"
!
examples
"
- without a group - user has to click on next field to activate it:
+ without a group - user has to enter mouse into the next field to activate it;
+ Cursor-keys dont work:
|top panel field1 field2 field3|
@@ -80,6 +107,8 @@
with a group - Return-key or CursorKey enables next field:
+ (but still, mouse pointer has to be moved into any of the fields,
+ because the topView does not forward its input into the fields)
|top panel group field1 field2 field3|
@@ -99,7 +128,74 @@
- with a group - close the box when the last field is left:
+ same, enables tabbing via the Tab key:
+
+ |top panel group field1 field2 field3|
+
+ top := StandardSystemView new.
+ top extent:200@200.
+
+ panel := VerticalPanelView origin:0.0@0.0 corner:1.0@1.0 in:top.
+
+ panel add:(field1 := EditField extent:(1.0 @ nil)).
+ panel add:(field2 := EditField extent:(1.0 @ nil)).
+ panel add:(field3 := EditField extent:(1.0 @ nil)).
+
+ group := EnterFieldGroup new.
+ group add:field1; add:field2; add:field3.
+
+ field1 leaveKeys:(EditField defaultLeaveKeys copyWith:#Tab).
+ field2 leaveKeys:(EditField defaultLeaveKeys copyWith:#Tab).
+ field3 leaveKeys:(EditField defaultLeaveKeys copyWith:#Tab).
+ top open
+
+
+
+ with a group - Return-key or CursorKey enables next field:
+ input into topView is forwarded to the group:
+
+ |top panel group field1 field2 field3|
+
+ top := StandardSystemView new.
+ top extent:200@200.
+
+ panel := VerticalPanelView origin:0.0@0.0 corner:1.0@1.0 in:top.
+
+ panel add:(field1 := EditField extent:(1.0 @ nil)).
+ panel add:(field2 := EditField extent:(1.0 @ nil)).
+ panel add:(field3 := EditField extent:(1.0 @ nil)).
+
+ group := EnterFieldGroup new.
+ group add:field1; add:field2; add:field3.
+
+ top delegate:group.
+ top open
+
+
+
+ as above, but close the box when the last field is left:
+
+ |top panel group field1 field2 field3|
+
+ top := StandardSystemView new.
+ top extent:200@200.
+
+ panel := VerticalPanelView origin:0.0@0.0 corner:1.0@1.0 in:top.
+
+ panel add:(field1 := EditField extent:(1.0 @ nil)).
+ panel add:(field2 := EditField extent:(1.0 @ nil)).
+ panel add:(field3 := EditField extent:(1.0 @ nil)).
+
+ group := EnterFieldGroup new.
+ group add:field1; add:field2; add:field3.
+ group leaveAction:[top destroy].
+
+ top delegate:group.
+ top open
+
+
+
+ same as above, with Tab-key stepping:
|top panel group field1 field2 field3|
@@ -116,14 +212,122 @@
group add:field1; add:field2; add:field3.
group leaveAction:[top destroy].
+ field1 leaveKeys:(EditField defaultLeaveKeys copyWith:#Tab).
+ field2 leaveKeys:(EditField defaultLeaveKeys copyWith:#Tab).
+ field3 leaveKeys:(EditField defaultLeaveKeys copyWith:#Tab).
+
+ top delegate:group.
top open
+
+
+
+ the next example shows that the input order is defined by the
+ order in the group; NOT by the physical layout of the fields in the superview:
+
+ |top panel group field1 field2 field3|
+
+ top := StandardSystemView new.
+ top extent:200@200.
+
+ panel := VerticalPanelView origin:0.0@0.0 corner:1.0@1.0 in:top.
+
+ panel add:(field1 := EditField extent:(1.0 @ nil)).
+ panel add:(field2 := EditField extent:(1.0 @ nil)).
+ panel add:(field3 := EditField extent:(1.0 @ nil)).
+
+ group := EnterFieldGroup new.
+ group add:field3; add:field2; add:field1.
+ group leaveAction:[top destroy].
+
+ top delegate:group.
+ top open
+
+
+
+ using a single model for all fields:
+ (here, we use a Plug to simulate a more complex model):
+
+ |top panel group field1 field2 field3 model
+ value1 value2 value3|
+
+ top := StandardSystemView new.
+ top extent:200@200.
+
+ panel := VerticalPanelView origin:0.0@0.0 corner:1.0@1.0 in:top.
+
+ panel add:(field1 := EditField extent:(1.0 @ nil)).
+ panel add:(field2 := EditField extent:(1.0 @ nil)).
+ panel add:(field3 := EditField extent:(1.0 @ nil)).
+
+ group := EnterFieldGroup new.
+ group add:field1; add:field2; add:field3.
+ group leaveAction:[top destroy].
+
+ value1 := 'one'. value2 := 'two'. value3 := 'three'.
+
+ model := Plug new.
+ model respondTo:#value1 with:[value1].
+ model respondTo:#value1: with:[:arg | value1 := arg].
+ model respondTo:#value2 with:[value2].
+ model respondTo:#value2: with:[:arg | value2 := arg].
+ model respondTo:#value3 with:[value3].
+ model respondTo:#value3: with:[:arg | value3 := arg].
+
+ field1 model:model; aspect:#value1; change:#value1:.
+ field2 model:model; aspect:#value2; change:#value2:.
+ field3 model:model; aspect:#value3; change:#value3:.
+
+ top delegate:group.
+ top openModal.
+
+ Transcript showCr:'value1: ' , value1.
+ Transcript showCr:'value2: ' , value2.
+ Transcript showCr:'value3: ' , value3.
+
+
+ the above is done automatically for you, if you add inputFields
+ to a dialogBox:
+
+ |box model
+ value1 value2 value3|
+
+ box := DialogBox new.
+ box extent:200@200.
+
+ value1 := 'one'. value2 := 'two'. value3 := 'three'.
+
+ model := Plug new.
+ model respondTo:#value1 with:[value1].
+ model respondTo:#value1: with:[:arg | value1 := arg].
+ model respondTo:#value2 with:[value2].
+ model respondTo:#value2: with:[:arg | value2 := arg].
+ model respondTo:#value3 with:[value3].
+ model respondTo:#value3: with:[:arg | value3 := arg].
+
+ (box addInputFieldOn:model) aspect:#value1; change:#value1:.
+ box addVerticalSpace.
+ (box addInputFieldOn:model) aspect:#value2; change:#value2:.
+ box addVerticalSpace.
+ (box addInputFieldOn:model) aspect:#value3; change:#value3:.
+
+ box open.
+
+ Transcript showCr:'value1: ' , value1.
+ Transcript showCr:'value2: ' , value2.
+ Transcript showCr:'value3: ' , value3.
"
! !
+!EnterFieldGroup class methodsFor:'instance creation'!
+
+new
+ ^ self basicNew wrap:false
+! !
+
!EnterFieldGroup methodsFor:'adding / removing'!
add:aField
- |thisIndex next|
+ |thisIndex next action|
fields isNil ifTrue:[
fields := OrderedCollection new
@@ -153,6 +357,8 @@
currentField disable.
currentField hideCursor.
].
+
+ action := key.
((key == #CursorUp) or:[key == #PreviousField]) ifTrue:[
(thisIndex == 1) ifTrue:[
next := fields size
@@ -160,14 +366,20 @@
next := thisIndex - 1
]
].
- ((key == #CursorDown) or:[key == #NextField]) ifTrue:[
+ ((key == #CursorDown)
+ or:[key == #NextField
+ or:[key == #Tab]]) ifTrue:[
(thisIndex == (fields size)) ifTrue:[
- next := 1
+ wrap ifFalse:[
+ action := #Return.
+ ] ifTrue:[
+ next := 1
+ ].
] ifFalse:[
next := thisIndex + 1
]
].
- (key == #Return) ifTrue:[
+ (action == #Return) ifTrue:[
(thisIndex == (fields size)) ifTrue:[
leaveAction notNil ifTrue:[
leaveAction value.
@@ -181,8 +393,6 @@
].
next notNil ifTrue:[
self makeActive:(fields at:next)
-"/ (fields at:next) enable.
-"/ currentField := fields at:next
]
].
@@ -194,6 +404,13 @@
!EnterFieldGroup methodsFor:'accessing'!
+wrap:aBoolean
+ "specifies if leaveing the last field via non-Return
+ should wrap back to the first, or leave the group"
+
+ wrap := aBoolean
+!
+
leaveAction:aBlock
"set the action to perform when the last field is left.
Usually, this is to accept the values of all fields and perform
@@ -259,15 +476,6 @@
]
!
-keyPress:key x:x y:y
- "key-press in an enclosing view (via delegation)
- forward the key to the active field"
-
- currentField notNil ifTrue:[
- currentField keyPress:key x:-1 y:-1
- ]
-!
-
buttonPress:button x:x y:y view:aView
"clicking on a field activates it and forwards the click to it"
--- a/EditField.st Sat May 06 16:18:13 1995 +0200
+++ b/EditField.st Sun May 07 02:16:56 1995 +0200
@@ -13,8 +13,8 @@
'From Smalltalk/X, Version:2.10.5 on 4-may-1995 at 8:46:55 am'!
EditTextView subclass:#EditField
- instanceVariableNames:'leaveAction enabled enableAction alwaysAccept crAction tabAction
- converter acceptAction leaveKeys'
+ instanceVariableNames:'leaveAction enabled enableAction crAction tabAction
+ converter acceptAction leaveKeys alwaysAccept acceptOnLeave acceptOnReturn'
classVariableNames:'DefaultForegroundColor DefaultBackgroundColor
DefaultSelectionForegroundColor DefaultSelectionBackgroundColor
DefaultFont'
@@ -26,7 +26,7 @@
COPYRIGHT (c) 1990 by Claus Gittinger
All Rights Reserved
-$Header: /cvs/stx/stx/libwidg/EditField.st,v 1.19 1995-05-06 14:16:58 claus Exp $
+$Header: /cvs/stx/stx/libwidg/EditField.st,v 1.20 1995-05-07 00:15:56 claus Exp $
'!
!EditField class methodsFor:'documentation'!
@@ -47,7 +47,7 @@
version
"
-$Header: /cvs/stx/stx/libwidg/EditField.st,v 1.19 1995-05-06 14:16:58 claus Exp $
+$Header: /cvs/stx/stx/libwidg/EditField.st,v 1.20 1995-05-07 00:15:56 claus Exp $
"
!
@@ -71,10 +71,6 @@
enabled <Boolean> if false, input is ignored.
enableAction <Block | nil>
- 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.
crAction <Block | nil> if non-nil, keyboard input of a cr are not
handled specially, instead this block is evaluated
@@ -93,12 +89,28 @@
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.
+
+ acceptOnLeave <Boolean> if true, leaving the field (via cursor keys)
+ automatically accepts the value into the model.
+ Default is false.
+
+ acceptOnReturn <Boolean> if true, leaving the field via return
+ automatically accepts the value into the model.
+ Default is true.
"
!
examples
"
- basic field:
+ see more examples in EnterFieldGroup>>examples.
+
+
+ basic field in a view:
|top field|
@@ -110,6 +122,21 @@
top open
+
+ forward input in topView to field:
+
+ |top field|
+
+ top := StandardSystemView new.
+ top extent:200@100.
+
+ field := EditField origin:0.0@0.0 in:top.
+ field width:1.0. 'let its height as-is'.
+
+ top delegate:(KeyboardForwarder toView:field).
+ top open
+
+
just to make it look better: set some inset:
|top field|
@@ -124,6 +151,7 @@
top open
+
give it an initial contents:
|top field|
@@ -139,6 +167,7 @@
top open
+
and have it preselected:
|top field|
@@ -154,6 +183,7 @@
top open
+
have part of it preselected:
|top field|
@@ -170,6 +200,7 @@
top open
+
use a converter:
- numbers:
@@ -207,6 +238,7 @@
field crAction:[field accept. top destroy].
top open.
+
setting alwaysAccept, makes the field update with every key:
- numbers:
@@ -227,6 +259,7 @@
field crAction:[field accept. top destroy].
top open.
+
use a model:
(see changing model value in inspector when return is pressed in the field)
@@ -246,6 +279,7 @@
top open.
model inspect.
+
two views on the same model:
|top1 top2 field1 field2 model|
@@ -270,6 +304,7 @@
field2 model:model.
top2 open.
+
just an example; a checkBox and an editField on the same model:
|top1 top2 field1 box model|
@@ -331,6 +366,8 @@
nFullLinesShown := 1.
nLinesShown := 1.
alwaysAccept := false.
+ acceptOnLeave := false.
+ acceptOnReturn := true.
leaveKeys := self class defaultLeaveKeys.
cursorShown := true
!
@@ -472,7 +509,9 @@
contents:someText
"set the contents from a string
- - redefined to place the cursor to the end"
+ - 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).
@@ -480,7 +519,9 @@
contents
"return contents as a string
- - redefined since EditFields hold only one line of text"
+ - 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:[^ ''].
@@ -505,6 +546,14 @@
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."
@@ -524,11 +573,23 @@
!
alwaysAccept:aBoolean
- "set/clear the alwaysAccept flag"
+ "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)."
@@ -715,7 +776,11 @@
leaveAction value:key
].
- self accept.
+ ((key == #Return and:[acceptOnReturn])
+ or:[key ~~ #Return and:[acceptOnLeave]]) ifTrue:[
+ self accept.
+ ].
+
x >= 0 ifTrue:[
"
let superview know about the leave ...
--- a/EnterBox.st Sat May 06 16:18:13 1995 +0200
+++ b/EnterBox.st Sun May 07 02:16:56 1995 +0200
@@ -37,7 +37,7 @@
version
"
-$Header: /cvs/stx/stx/libwidg/EnterBox.st,v 1.22 1995-05-06 14:17:02 claus Exp $
+$Header: /cvs/stx/stx/libwidg/EnterBox.st,v 1.23 1995-05-07 00:16:00 claus Exp $
"
!
@@ -300,7 +300,7 @@
"
forward keyboard input to the enterfield
"
- self delegate:(KeyboardForwarder to:enterField condition:#noFocus).
+ self delegate:(KeyboardForwarder toView:enterField condition:#noFocus).
enterField hasKeyboardFocus:true.
!
--- a/EnterFieldGroup.st Sat May 06 16:18:13 1995 +0200
+++ b/EnterFieldGroup.st Sun May 07 02:16:56 1995 +0200
@@ -11,7 +11,8 @@
"
Object subclass:#EnterFieldGroup
- instanceVariableNames:'fields currentField leaveAction'
+ instanceVariableNames:'fields currentField leaveAction
+ wrap'
classVariableNames:''
poolDictionaries:''
category:'Views-Support'
@@ -21,7 +22,7 @@
COPYRIGHT (c) 1992 by Claus Gittinger
All Rights Reserved
-$Header: /cvs/stx/stx/libwidg/EnterFieldGroup.st,v 1.8 1995-05-06 14:16:40 claus Exp $
+$Header: /cvs/stx/stx/libwidg/EnterFieldGroup.st,v 1.9 1995-05-07 00:15:50 claus Exp $
'!
!EnterFieldGroup class methodsFor:'documentation'!
@@ -42,7 +43,7 @@
version
"
-$Header: /cvs/stx/stx/libwidg/EnterFieldGroup.st,v 1.8 1995-05-06 14:16:40 claus Exp $
+$Header: /cvs/stx/stx/libwidg/EnterFieldGroup.st,v 1.9 1995-05-07 00:15:50 claus Exp $
"
!
@@ -58,12 +59,38 @@
field of the group is left (by cursor-down or cr).
Usually this block triggers accept on the fields and/or performs some
followup processing and closes the topview (for example: in a dialog).
+
+ EnterFieldGroups can be used as a delegate (of the topView) to forward
+ input (entered into the topView) to the currently active field.
+
+ Stepping to previous field is via CursorUp/PreviousField,
+ to next field via CursorDown/NextField/Tab.
+ Notice, that by default, the editField takes the tab-character as
+ a normal character. To step using tab, you have to add the Tab key to the
+ fields leaveKeys.
+
+ Instance variables:
+
+ fields <Collection of EditField> the fields of the group
+
+ currentField <EditField> the active field
+
+ leaveAction <nil|Block> action to perform, when the
+ last field is left by a non-wrap
+
+ wrap <Boolean> if true, non-return next-keys wrap
+ back to the first field.
+ If false (the default), next in
+ the last field is taken as return.
+ This is ignored, if no leaveAction was
+ defined.
"
!
examples
"
- without a group - user has to click on next field to activate it:
+ without a group - user has to enter mouse into the next field to activate it;
+ Cursor-keys dont work:
|top panel field1 field2 field3|
@@ -80,6 +107,8 @@
with a group - Return-key or CursorKey enables next field:
+ (but still, mouse pointer has to be moved into any of the fields,
+ because the topView does not forward its input into the fields)
|top panel group field1 field2 field3|
@@ -99,7 +128,74 @@
- with a group - close the box when the last field is left:
+ same, enables tabbing via the Tab key:
+
+ |top panel group field1 field2 field3|
+
+ top := StandardSystemView new.
+ top extent:200@200.
+
+ panel := VerticalPanelView origin:0.0@0.0 corner:1.0@1.0 in:top.
+
+ panel add:(field1 := EditField extent:(1.0 @ nil)).
+ panel add:(field2 := EditField extent:(1.0 @ nil)).
+ panel add:(field3 := EditField extent:(1.0 @ nil)).
+
+ group := EnterFieldGroup new.
+ group add:field1; add:field2; add:field3.
+
+ field1 leaveKeys:(EditField defaultLeaveKeys copyWith:#Tab).
+ field2 leaveKeys:(EditField defaultLeaveKeys copyWith:#Tab).
+ field3 leaveKeys:(EditField defaultLeaveKeys copyWith:#Tab).
+ top open
+
+
+
+ with a group - Return-key or CursorKey enables next field:
+ input into topView is forwarded to the group:
+
+ |top panel group field1 field2 field3|
+
+ top := StandardSystemView new.
+ top extent:200@200.
+
+ panel := VerticalPanelView origin:0.0@0.0 corner:1.0@1.0 in:top.
+
+ panel add:(field1 := EditField extent:(1.0 @ nil)).
+ panel add:(field2 := EditField extent:(1.0 @ nil)).
+ panel add:(field3 := EditField extent:(1.0 @ nil)).
+
+ group := EnterFieldGroup new.
+ group add:field1; add:field2; add:field3.
+
+ top delegate:group.
+ top open
+
+
+
+ as above, but close the box when the last field is left:
+
+ |top panel group field1 field2 field3|
+
+ top := StandardSystemView new.
+ top extent:200@200.
+
+ panel := VerticalPanelView origin:0.0@0.0 corner:1.0@1.0 in:top.
+
+ panel add:(field1 := EditField extent:(1.0 @ nil)).
+ panel add:(field2 := EditField extent:(1.0 @ nil)).
+ panel add:(field3 := EditField extent:(1.0 @ nil)).
+
+ group := EnterFieldGroup new.
+ group add:field1; add:field2; add:field3.
+ group leaveAction:[top destroy].
+
+ top delegate:group.
+ top open
+
+
+
+ same as above, with Tab-key stepping:
|top panel group field1 field2 field3|
@@ -116,14 +212,122 @@
group add:field1; add:field2; add:field3.
group leaveAction:[top destroy].
+ field1 leaveKeys:(EditField defaultLeaveKeys copyWith:#Tab).
+ field2 leaveKeys:(EditField defaultLeaveKeys copyWith:#Tab).
+ field3 leaveKeys:(EditField defaultLeaveKeys copyWith:#Tab).
+
+ top delegate:group.
top open
+
+
+
+ the next example shows that the input order is defined by the
+ order in the group; NOT by the physical layout of the fields in the superview:
+
+ |top panel group field1 field2 field3|
+
+ top := StandardSystemView new.
+ top extent:200@200.
+
+ panel := VerticalPanelView origin:0.0@0.0 corner:1.0@1.0 in:top.
+
+ panel add:(field1 := EditField extent:(1.0 @ nil)).
+ panel add:(field2 := EditField extent:(1.0 @ nil)).
+ panel add:(field3 := EditField extent:(1.0 @ nil)).
+
+ group := EnterFieldGroup new.
+ group add:field3; add:field2; add:field1.
+ group leaveAction:[top destroy].
+
+ top delegate:group.
+ top open
+
+
+
+ using a single model for all fields:
+ (here, we use a Plug to simulate a more complex model):
+
+ |top panel group field1 field2 field3 model
+ value1 value2 value3|
+
+ top := StandardSystemView new.
+ top extent:200@200.
+
+ panel := VerticalPanelView origin:0.0@0.0 corner:1.0@1.0 in:top.
+
+ panel add:(field1 := EditField extent:(1.0 @ nil)).
+ panel add:(field2 := EditField extent:(1.0 @ nil)).
+ panel add:(field3 := EditField extent:(1.0 @ nil)).
+
+ group := EnterFieldGroup new.
+ group add:field1; add:field2; add:field3.
+ group leaveAction:[top destroy].
+
+ value1 := 'one'. value2 := 'two'. value3 := 'three'.
+
+ model := Plug new.
+ model respondTo:#value1 with:[value1].
+ model respondTo:#value1: with:[:arg | value1 := arg].
+ model respondTo:#value2 with:[value2].
+ model respondTo:#value2: with:[:arg | value2 := arg].
+ model respondTo:#value3 with:[value3].
+ model respondTo:#value3: with:[:arg | value3 := arg].
+
+ field1 model:model; aspect:#value1; change:#value1:.
+ field2 model:model; aspect:#value2; change:#value2:.
+ field3 model:model; aspect:#value3; change:#value3:.
+
+ top delegate:group.
+ top openModal.
+
+ Transcript showCr:'value1: ' , value1.
+ Transcript showCr:'value2: ' , value2.
+ Transcript showCr:'value3: ' , value3.
+
+
+ the above is done automatically for you, if you add inputFields
+ to a dialogBox:
+
+ |box model
+ value1 value2 value3|
+
+ box := DialogBox new.
+ box extent:200@200.
+
+ value1 := 'one'. value2 := 'two'. value3 := 'three'.
+
+ model := Plug new.
+ model respondTo:#value1 with:[value1].
+ model respondTo:#value1: with:[:arg | value1 := arg].
+ model respondTo:#value2 with:[value2].
+ model respondTo:#value2: with:[:arg | value2 := arg].
+ model respondTo:#value3 with:[value3].
+ model respondTo:#value3: with:[:arg | value3 := arg].
+
+ (box addInputFieldOn:model) aspect:#value1; change:#value1:.
+ box addVerticalSpace.
+ (box addInputFieldOn:model) aspect:#value2; change:#value2:.
+ box addVerticalSpace.
+ (box addInputFieldOn:model) aspect:#value3; change:#value3:.
+
+ box open.
+
+ Transcript showCr:'value1: ' , value1.
+ Transcript showCr:'value2: ' , value2.
+ Transcript showCr:'value3: ' , value3.
"
! !
+!EnterFieldGroup class methodsFor:'instance creation'!
+
+new
+ ^ self basicNew wrap:false
+! !
+
!EnterFieldGroup methodsFor:'adding / removing'!
add:aField
- |thisIndex next|
+ |thisIndex next action|
fields isNil ifTrue:[
fields := OrderedCollection new
@@ -153,6 +357,8 @@
currentField disable.
currentField hideCursor.
].
+
+ action := key.
((key == #CursorUp) or:[key == #PreviousField]) ifTrue:[
(thisIndex == 1) ifTrue:[
next := fields size
@@ -160,14 +366,20 @@
next := thisIndex - 1
]
].
- ((key == #CursorDown) or:[key == #NextField]) ifTrue:[
+ ((key == #CursorDown)
+ or:[key == #NextField
+ or:[key == #Tab]]) ifTrue:[
(thisIndex == (fields size)) ifTrue:[
- next := 1
+ wrap ifFalse:[
+ action := #Return.
+ ] ifTrue:[
+ next := 1
+ ].
] ifFalse:[
next := thisIndex + 1
]
].
- (key == #Return) ifTrue:[
+ (action == #Return) ifTrue:[
(thisIndex == (fields size)) ifTrue:[
leaveAction notNil ifTrue:[
leaveAction value.
@@ -181,8 +393,6 @@
].
next notNil ifTrue:[
self makeActive:(fields at:next)
-"/ (fields at:next) enable.
-"/ currentField := fields at:next
]
].
@@ -194,6 +404,13 @@
!EnterFieldGroup methodsFor:'accessing'!
+wrap:aBoolean
+ "specifies if leaveing the last field via non-Return
+ should wrap back to the first, or leave the group"
+
+ wrap := aBoolean
+!
+
leaveAction:aBlock
"set the action to perform when the last field is left.
Usually, this is to accept the values of all fields and perform
@@ -259,15 +476,6 @@
]
!
-keyPress:key x:x y:y
- "key-press in an enclosing view (via delegation)
- forward the key to the active field"
-
- currentField notNil ifTrue:[
- currentField keyPress:key x:-1 y:-1
- ]
-!
-
buttonPress:button x:x y:y view:aView
"clicking on a field activates it and forwards the click to it"
--- a/LSelBox.st Sat May 06 16:18:13 1995 +0200
+++ b/LSelBox.st Sun May 07 02:16:56 1995 +0200
@@ -21,7 +21,7 @@
COPYRIGHT (c) 1990 by Claus Gittinger
All Rights Reserved
-$Header: /cvs/stx/stx/libwidg/Attic/LSelBox.st,v 1.10 1995-05-03 00:29:49 claus Exp $
+$Header: /cvs/stx/stx/libwidg/Attic/LSelBox.st,v 1.11 1995-05-07 00:16:17 claus Exp $
'!
!ListSelectionBox class methodsFor:'documentation'!
@@ -42,7 +42,7 @@
version
"
-$Header: /cvs/stx/stx/libwidg/Attic/LSelBox.st,v 1.10 1995-05-03 00:29:49 claus Exp $
+$Header: /cvs/stx/stx/libwidg/Attic/LSelBox.st,v 1.11 1995-05-07 00:16:17 claus Exp $
"
!
@@ -166,7 +166,7 @@
mhm: the lists keyboard functions are disabled,
and input passed to the enterfield
"
- selectionList delegate:(KeyboardForwarder to:enterField condition:#noFocus)
+ selectionList delegate:(KeyboardForwarder toView:enterField condition:#noFocus)
!
updateList
--- a/ListSelectionBox.st Sat May 06 16:18:13 1995 +0200
+++ b/ListSelectionBox.st Sun May 07 02:16:56 1995 +0200
@@ -21,7 +21,7 @@
COPYRIGHT (c) 1990 by Claus Gittinger
All Rights Reserved
-$Header: /cvs/stx/stx/libwidg/ListSelectionBox.st,v 1.10 1995-05-03 00:29:49 claus Exp $
+$Header: /cvs/stx/stx/libwidg/ListSelectionBox.st,v 1.11 1995-05-07 00:16:17 claus Exp $
'!
!ListSelectionBox class methodsFor:'documentation'!
@@ -42,7 +42,7 @@
version
"
-$Header: /cvs/stx/stx/libwidg/ListSelectionBox.st,v 1.10 1995-05-03 00:29:49 claus Exp $
+$Header: /cvs/stx/stx/libwidg/ListSelectionBox.st,v 1.11 1995-05-07 00:16:17 claus Exp $
"
!
@@ -166,7 +166,7 @@
mhm: the lists keyboard functions are disabled,
and input passed to the enterfield
"
- selectionList delegate:(KeyboardForwarder to:enterField condition:#noFocus)
+ selectionList delegate:(KeyboardForwarder toView:enterField condition:#noFocus)
!
updateList
--- a/Make.proto Sat May 06 16:18:13 1995 +0200
+++ b/Make.proto Sun May 07 02:16:56 1995 +0200
@@ -1,4 +1,4 @@
-# $Header: /cvs/stx/stx/libwidg/Make.proto,v 1.18 1995-05-03 00:39:07 claus Exp $
+# $Header: /cvs/stx/stx/libwidg/Make.proto,v 1.19 1995-05-07 00:16:56 claus Exp $
#
# -------------- no need to change anything below ----------
@@ -145,8 +145,8 @@
BUTTON=$(I)/Button.H $(LABEL)
CONTROLLER=$(I)/Controll.H $(OBJECT)
-RButtGrp.$(O): RButtGrp.st $(I)/VarArray.H $(OBJECT)
-EFGroup.$(O): EFGroup.st $(I)/VarArray.H $(OBJECT)
+RButtGrp.$(O): RButtGrp.st $(I)/OrdColl.H $(OBJECT)
+EFGroup.$(O): EFGroup.st $(OBJECT)
DialogBox.$(O): DialogBox.st $(MODALBOX)
InfoBox.$(O): InfoBox.st $(DIALOGBOX)
--- a/ScrView.st Sat May 06 16:18:13 1995 +0200
+++ b/ScrView.st Sun May 07 02:16:56 1995 +0200
@@ -22,7 +22,7 @@
COPYRIGHT (c) 1989 by Claus Gittinger
All Rights Reserved
-$Header: /cvs/stx/stx/libwidg/Attic/ScrView.st,v 1.15 1995-05-03 00:37:26 claus Exp $
+$Header: /cvs/stx/stx/libwidg/Attic/ScrView.st,v 1.16 1995-05-07 00:16:36 claus Exp $
'!
!ScrollableView class methodsFor:'documentation'!
@@ -43,7 +43,7 @@
version
"
-$Header: /cvs/stx/stx/libwidg/Attic/ScrView.st,v 1.15 1995-05-03 00:37:26 claus Exp $
+$Header: /cvs/stx/stx/libwidg/Attic/ScrView.st,v 1.16 1995-05-07 00:16:36 claus Exp $
"
!
@@ -511,7 +511,7 @@
pass my keyboard input (and other subviews input)
to the scrolled view ...
"
- self delegate:(KeyboardForwarder to:scrolledView).
+ self delegate:(KeyboardForwarder toView:scrolledView).
]
!
@@ -663,7 +663,7 @@
pass my keyboard input (and other subviews input)
to the scrolled view ...
"
- self delegate:(KeyboardForwarder to:scrolledView).
+ self delegate:(KeyboardForwarder toView:scrolledView).
realized ifTrue:[
self sizeChanged:nil.
--- a/ScrollableView.st Sat May 06 16:18:13 1995 +0200
+++ b/ScrollableView.st Sun May 07 02:16:56 1995 +0200
@@ -22,7 +22,7 @@
COPYRIGHT (c) 1989 by Claus Gittinger
All Rights Reserved
-$Header: /cvs/stx/stx/libwidg/ScrollableView.st,v 1.15 1995-05-03 00:37:26 claus Exp $
+$Header: /cvs/stx/stx/libwidg/ScrollableView.st,v 1.16 1995-05-07 00:16:36 claus Exp $
'!
!ScrollableView class methodsFor:'documentation'!
@@ -43,7 +43,7 @@
version
"
-$Header: /cvs/stx/stx/libwidg/ScrollableView.st,v 1.15 1995-05-03 00:37:26 claus Exp $
+$Header: /cvs/stx/stx/libwidg/ScrollableView.st,v 1.16 1995-05-07 00:16:36 claus Exp $
"
!
@@ -511,7 +511,7 @@
pass my keyboard input (and other subviews input)
to the scrolled view ...
"
- self delegate:(KeyboardForwarder to:scrolledView).
+ self delegate:(KeyboardForwarder toView:scrolledView).
]
!
@@ -663,7 +663,7 @@
pass my keyboard input (and other subviews input)
to the scrolled view ...
"
- self delegate:(KeyboardForwarder to:scrolledView).
+ self delegate:(KeyboardForwarder toView:scrolledView).
realized ifTrue:[
self sizeChanged:nil.