examples
authorClaus Gittinger <cg@exept.de>
Sat, 27 Apr 1996 19:55:59 +0200
changeset 589 4644afc9f0ae
parent 588 2d6fc80017df
child 590 8392a7c03352
examples
EFGroup.st
EnterFieldGroup.st
--- a/EFGroup.st	Sat Apr 27 10:12:28 1996 +0200
+++ b/EFGroup.st	Sat Apr 27 19:55:59 1996 +0200
@@ -11,7 +11,7 @@
 "
 
 Object subclass:#EnterFieldGroup
-	instanceVariableNames:'fields currentField leaveAction wrap'
+	instanceVariableNames:'fields currentField leaveAction wrap leaveOnTabLast'
 	classVariableNames:''
 	poolDictionaries:''
 	category:'Interface-Support'
@@ -39,21 +39,29 @@
     enabling the next/prev field when a field is left. 
     Instances of this class keep track of which field of the group is the 
     currentField (i.e. the one getting keyboard input) and forwards input
-    to the active field (having the inputField delegate its input to me).
+    to that one.
+    This is done by arranging for all of my fields to delegate their
+    input to me, which is then forwarded to the active field).
 
     The block accessable as leaveAction is evaluated when the last
     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).
+    Usually this block triggers accept on the fields (if they did not already)
+    and/or performs some followup processing and possibly 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.
+    By default, tabbing via #Tab is disabled - to enable it, send the field
+    a #makeTabable or #makeAllTabable to the group.
+
+    All of this here is low level stuff, providing a lot of freedom in
+    which keys are handled and how they perform.
+    Normally, these are not required for most users - the DialogBox sets up
+    things correctly for most cases.
+
 
     [Instance variables:]
 
@@ -71,8 +79,17 @@
                                                         This is ignored, if no leaveAction was 
                                                         defined.
 
+        leaveOnTabLast  <Boolean>                       if true, tabbing out of the last
+                                                        field leaves the group.
+                                                        The default is false.
+
     [author:]
         Claus Gittinger
+
+
+    [see also:]
+        DialogBox
+        EditField
 "
 !
 
@@ -80,233 +97,323 @@
 "
     without a group - user has to enter mouse into the next field to activate it;
     Cursor-keys dont work:
-
-	|top panel field1 field2 field3|
+                                                                        [exBegin]
+        |top panel field1 field2 field3|
 
-	top := StandardSystemView new.
-	top extent:200@200.
+        top := StandardSystemView new.
+        top extent:200@200.
 
-	panel := VerticalPanelView origin:0.0@0.0 corner:1.0@1.0 in:top.
+        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)).
+        panel add:(field1 := EditField extent:(1.0 @ nil)).
+        panel add:(field2 := EditField extent:(1.0 @ nil)).
+        panel add:(field3 := EditField extent:(1.0 @ nil)).
 
-	top open
+        top open
+                                                                        [exEnd]
 
 
     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|
+     because the topView does not forward its input into the fields.
+     Also, tabbing is not possible here)
+                                                                        [exBegin]
+        |top panel group field1 field2 field3|
 
-	top := StandardSystemView new.
-	top extent:200@200.
+        top := StandardSystemView new.
+        top extent:200@200.
 
-	panel := VerticalPanelView origin:0.0@0.0 corner:1.0@1.0 in:top.
+        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)).
+        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 := EnterFieldGroup new.
+        group add:field1; add:field2; add:field3.
 
-	top open
+        top open
+                                                                        [exEnd]
 
 
 
-    same, enables tabbing via the Tab key:
+    same, enables tabbing within the group via the Tab key
+    (but still, the mouse pointer must be in one of the fields):
+                                                                        [exBegin]
+        |top panel group field1 field2 field3|
 
-	|top panel group field1 field2 field3|
+        top := StandardSystemView new.
+        top extent:200@200.
 
-	top := StandardSystemView new.
-	top extent:200@200.
+        panel := VerticalPanelView origin:0.0@0.0 corner:1.0@1.0 in:top.
 
-	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.
 
-	panel add:(field1 := EditField extent:(1.0 @ nil)).
-	panel add:(field2 := EditField extent:(1.0 @ nil)).
-	panel add:(field3 := EditField extent:(1.0 @ nil)).
+        field1 makeTabable.
+        field2 makeTabable.
+        field3 makeTabable.
+        top open
+                                                                        [exEnd]
+    individual makeTabable messages to the fields allows single
+    fields to be sticky (i.e. explicit click is needed to get out
+    of it) - this is very seldom required.
+    To make all fields tabable (the usual case), there is a shortCut:
+                                                                        [exBegin]
+        |top panel group field1 field2 field3|
 
-	group := EnterFieldGroup new.
-	group add:field1; add:field2; add:field3.
+        top := StandardSystemView new.
+        top extent:200@200.
+
+        panel := VerticalPanelView origin:0.0@0.0 corner:1.0@1.0 in:top.
 
-	field1 leaveKeys:(EditField defaultLeaveKeys copyWith:#Tab).
-	field2 leaveKeys:(EditField defaultLeaveKeys copyWith:#Tab).
-	field3 leaveKeys:(EditField defaultLeaveKeys copyWith:#Tab).
-	top open
+        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 makeAllTabable.
+
+        top open
+                                                                        [exEnd]
 
 
 
-    with a group - Return-key or CursorKey enables next field:
-    input into topView is forwarded to the group:
-
-	|top panel group field1 field2 field3|
+    use a delagation from the outerView to the group - 
+    Return-key or CursorKey enables next field:
+    input for topView is delegated to the group, which also behaves
+    as a unit w.r.t. keyboard focus (move pointer in and out).
+    Again, without tabbing:
+                                                                        [exBegin]
+        |top panel group field1 field2 field3|
 
-	top := StandardSystemView new.
-	top extent:200@200.
+        top := StandardSystemView new.
+        top extent:200@200.
+
+        panel := VerticalPanelView origin:0.0@0.0 corner:1.0@1.0 in:top.
 
-	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.
 
-	panel add:(field1 := EditField extent:(1.0 @ nil)).
-	panel add:(field2 := EditField extent:(1.0 @ nil)).
-	panel add:(field3 := EditField extent:(1.0 @ nil)).
+        top delegate:group.
+        top open
+                                                                        [exEnd]
+
+
+    and, with tabbing:
+                                                                        [exBegin]
+        |top panel group field1 field2 field3|
+
+        top := StandardSystemView new.
+        top extent:200@200.
 
-	group := EnterFieldGroup new.
-	group add:field1; add:field2; add:field3.
+        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)).
 
-	top delegate:group.
-	top open
+        group := EnterFieldGroup new.
+        group add:field1; add:field2; add:field3.
+        group makeAllTabable.
+
+        top delegate:group.
+        top open
+                                                                        [exEnd]
 
 
 
-    as above, but close the box when the last field is left:
-
-	|top panel group field1 field2 field3|
+    as above, but close the box when the last field is left
+    via return - notice, that tabbing still wraps around:
+                                                                        [exBegin]
+        |top panel group field1 field2 field3|
 
-	top := StandardSystemView new.
-	top extent:200@200.
+        top := StandardSystemView new.
+        top extent:200@200.
 
-	panel := VerticalPanelView origin:0.0@0.0 corner:1.0@1.0 in:top.
+        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)).
+        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].
+        group := EnterFieldGroup new.
+        group add:field1; add:field2; add:field3.
+        group leaveAction:[top destroy].
+        group makeAllTabable.
 
-	top delegate:group.
-	top open
-
-
+        top delegate:group.
+        top open
+                                                                        [exEnd]
 
-    same as above, with Tab-key stepping:
-
-	|top panel group field1 field2 field3|
+    in the next example, tabbing out of the last field
+    closes the box as well:
+                                                                        [exBegin]
+        |top panel group field1 field2 field3|
 
-	top := StandardSystemView new.
-	top extent:200@200.
+        top := StandardSystemView new.
+        top extent:200@200.
 
-	panel := VerticalPanelView origin:0.0@0.0 corner:1.0@1.0 in:top.
+        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].
+        panel add:(field1 := EditField extent:(1.0 @ nil)).
+        panel add:(field2 := EditField extent:(1.0 @ nil)).
+        panel add:(field3 := EditField extent:(1.0 @ nil)).
 
-	field1 leaveKeys:(EditField defaultLeaveKeys copyWith:#Tab).
-	field2 leaveKeys:(EditField defaultLeaveKeys copyWith:#Tab).
-	field3 leaveKeys:(EditField defaultLeaveKeys copyWith:#Tab).
+        group := EnterFieldGroup new.
+        group add:field1; add:field2; add:field3.
+        group leaveAction:[top destroy].
+        group makeAllTabable.
+        group leaveOnTabLast:true.
 
-	top delegate:group.
-	top open
-
+        top delegate:group.
+        top open
+                                                                        [exEnd]
 
 
     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:
     (i.e. you can arrange your fields in multiple framedBoxes, panels or
      subviews - independent of the tab-stepping order)
-
-	|top panel group field1 field2 field3|
+                                                                        [exBegin]
+        |top panel group field1 field2 field3|
 
-	top := StandardSystemView new.
-	top extent:200@200.
+        top := StandardSystemView label:'reverse'.
+        top extent:200@200.
 
-	panel := VerticalPanelView origin:0.0@0.0 corner:1.0@1.0 in:top.
+        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)).
+        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].
+        group := EnterFieldGroup new.
+        group add:field3; add:field2; add:field1.
+        group leaveAction:[top destroy].
+        group makeAllTabable.
 
-	top delegate:group.
-	top open
+        top delegate:group.
+        top open
+                                                                        [exEnd]
 
 
 
     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|
+                                                                        [exBegin]
+        |top panel group field1 field2 field3 model
+         value1 value2 value3|
 
-	top := StandardSystemView new.
-	top extent:200@200.
+        top := StandardSystemView new.
+        top extent:200@200.
 
-	panel := VerticalPanelView origin:0.0@0.0 corner:1.0@1.0 in:top.
+        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)).
+        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].
+        group := EnterFieldGroup new.
+        group add:field1; add:field2; add:field3.
+        group leaveAction:[top destroy].
+        group makeAllTabable.
 
-	value1 := 'one'. value2 := 'two'. value3 := 'three'.
+        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].
+        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:.
+        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.
+        top delegate:group.
+        top openModal.
 
-	Transcript showCr:'value1: ' , value1.
-	Transcript showCr:'value2: ' , value2.
-	Transcript showCr:'value3: ' , value3.
+        Transcript showCr:'value1: ' , value1.
+        Transcript showCr:'value2: ' , value2.
+        Transcript showCr:'value3: ' , value3.
+                                                                        [exEnd]
 
 
-    the above is done automatically for you, if you add inputFields
-    to a dialogBox:
+    all of the above is done automatically for you, 
+    if you add inputFields to a dialogBox.
+    Here, all fields use the same model, but different aspects:
+                                                                        [exBegin]
+        |box model
+         value1 value2 value3|
+
+        box := DialogBox new.
+        box extent:200@200.
+
+        value1 := 'one'. value2 := 'two'. value3 := 'three'.
 
-	|box model
-	 value1 value2 value3|
+        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 := DialogBox new.
-	box extent:200@200.
+        (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:.
 
-	value1 := 'one'. value2 := 'two'. value3 := 'three'.
+        box addOkButton.
+
+        box open.
 
-	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].
+        Transcript showCr:'value1: ' , value1.
+        Transcript showCr:'value2: ' , value2.
+        Transcript showCr:'value3: ' , value3.
+                                                                        [exEnd]
+
+    Here, the fields use different models, but the same aspect:
+                                                                        [exBegin]
+        |box model
+         valueHolder1 valueHolder2 valueHolder3|
+
+        box := DialogBox new.
+        box extent:200@200.
+
+        valueHolder1 := 'one' asValue. 
+        valueHolder2 := 'two' asValue. 
+        valueHolder3 := 'three' asValue.
 
-	(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 addInputFieldOn:valueHolder1.
+        box addVerticalSpace.
+        box addInputFieldOn:valueHolder2.
+        box addVerticalSpace.
+        box addInputFieldOn:valueHolder3.
+
+        box addOkButton.
 
-	box open.
+        box open.
 
-	Transcript showCr:'value1: ' , value1.
-	Transcript showCr:'value2: ' , value2.
-	Transcript showCr:'value3: ' , value3.
+        Transcript showCr:'value1: ' , valueHolder1 value.
+        Transcript showCr:'value2: ' , valueHolder2 value.
+        Transcript showCr:'value3: ' , valueHolder3 value.
+                                                                        [exEnd]
 "
+
+    "Created: 27.4.1996 / 16:43:28 / cg"
 ! !
 
 !EnterFieldGroup methodsFor:'accessing'!
@@ -325,13 +432,37 @@
     leaveAction := aBlock
 !
 
+leaveOnTabLast:aBoolean
+    "specifies if leaving the last field via Tab
+     should leave the group or stay in the group.
+     (if staying, either wrap or not, depending on the setting of wrap)
+     The default is to stay in the group"
+
+    leaveOnTabLast := aBoolean
+
+    "Created: 27.4.1996 / 17:22:30 / cg"
+    "Modified: 27.4.1996 / 17:22:44 / cg"
+!
+
+makeAllTabable
+    "make all fields tabable"
+
+    fields do:[:field |
+        field makeTabable
+    ]
+
+    "Created: 27.4.1996 / 17:11:41 / cg"
+!
+
 wrap:aBoolean
     "specifies if leaving the last field via non-Return
-     should wrap back to the first, or leave the group.
-     The default is to stay in the input sequence and wrap back to 
-     the first field."
+     (i.e. Tab or Cursor-Down) should wrap back to the first, 
+     or leave the group.
+     The default is to not leave the group and wrap back to the first field."
 
     wrap := aBoolean
+
+    "Modified: 27.4.1996 / 17:19:50 / cg"
 ! !
 
 !EnterFieldGroup methodsFor:'adding / removing'!
@@ -340,7 +471,7 @@
     |thisIndex action|
 
     fields isNil ifTrue:[
-	fields := OrderedCollection new
+        fields := OrderedCollection new
     ].
     fields add:aField.
     thisIndex := fields size.
@@ -352,75 +483,78 @@
     "set the fields enableAction to disable active field"
 
     aField clickAction:[:field |
-	self makeActive:field
+        self makeActive:field
     ].
 
     "set the fields leaveAction to enable next field"
 
     aField leaveAction:[:key |
-	|next wg explicit nFields nextField|
+        |next wg explicit nFields nextField|
 
 "/        currentField notNil ifTrue:[
 "/            currentField disable.
 "/            currentField hideCursor.
 "/        ].
 "/
-	action := key.
-	nFields := fields size.
+        action := key.
+        nFields := fields size.
 
-	((key == #CursorUp) or:[key == #PreviousField]) ifTrue:[
-	    (thisIndex == 1) ifTrue:[
-		next := nFields
-	    ] ifFalse:[
-		next := thisIndex - 1
-	    ]
-	].
-	((key == #CursorDown) 
-	or:[key == #NextField
-	or:[key == #Tab]]) ifTrue:[
-	    (thisIndex == nFields) ifTrue:[
-		next := 1.
-		wrap == false ifTrue:[
-		    action := #Return.
-		].
-	    ] ifFalse:[
-		next := thisIndex + 1
-	    ]
-	].
-	(action == #Return) ifTrue:[
-	    (thisIndex == nFields) ifTrue:[
-		leaveAction notNil ifTrue:[
-		    currentField := nil.
-		    leaveAction value.
-		    next := nil
-		] ifFalse:[
-		    next := 1
-		]
-	    ] ifFalse:[
-		next := thisIndex + 1
-	    ]
-	].
-	next notNil ifTrue:[
-	    nextField := fields at:next.
+        ((key == #CursorUp) or:[key == #PreviousField]) ifTrue:[
+            (thisIndex == 1) ifTrue:[
+                next := nFields
+            ] ifFalse:[
+                next := thisIndex - 1
+            ]
+        ].
+        ((key == #CursorDown) 
+        or:[key == #NextField
+        or:[key == #Tab]]) ifTrue:[
+            (thisIndex == nFields) ifTrue:[
+                next := 1.
+                wrap == false ifTrue:[
+                    action := #Return.
+                ].
+            ] ifFalse:[
+                next := thisIndex + 1
+            ]
+        ].
+        ((action == #Return)
+        or:[key == #Tab and:[leaveOnTabLast == true]]) ifTrue:[
+            (thisIndex == nFields) ifTrue:[
+                leaveAction notNil ifTrue:[
+                    currentField := nil.
+                    leaveAction value.
+                    next := nil
+                ] ifFalse:[
+                    next := 1
+                ]
+            ] ifFalse:[
+                next := thisIndex + 1
+            ]
+        ].
+        next notNil ifTrue:[
+            nextField := fields at:next.
 
-	    explicit := false.
-	    (wg := currentField windowGroup) notNil ifTrue:[
-		wg focusView == currentField ifTrue:[
-		    explicit := true.
-		]
-	    ].
-	    explicit ifTrue:[
-		wg focusView:nextField.
-	    ] ifFalse:[
-		self makeActive:nextField 
-	    ]
-	]
+            explicit := false.
+            (wg := currentField windowGroup) notNil ifTrue:[
+                wg focusView == currentField ifTrue:[
+                    explicit := true.
+                ]
+            ].
+            explicit ifTrue:[
+                wg focusView:nextField.
+            ] ifFalse:[
+                self makeActive:nextField 
+            ]
+        ]
     ].
 
     fields size == 1 ifTrue:[
-	"the first one"
-	self makeActive:aField
+        "the first one"
+        self makeActive:aField
     ]
+
+    "Modified: 27.4.1996 / 17:21:09 / cg"
 ! !
 
 !EnterFieldGroup methodsFor:'event forwarding'!
@@ -487,6 +621,28 @@
     currentField notNil ifTrue:[
 	currentField keyRelease:key x:-1 y:-1
     ]
+!
+
+showFocus:onOrOff
+    "forward focus display to the active field "
+
+    currentField notNil ifTrue:[
+        currentField showFocus:onOrOff
+    ]
+
+    "Modified: 4.3.1996 / 22:18:22 / cg"
+    "Created: 27.4.1996 / 16:41:38 / cg"
+!
+
+showNoFocus:onOrOff
+    "forward nofocus display to the active field "
+
+    currentField notNil ifTrue:[
+        currentField showNoFocus:onOrOff
+    ]
+
+    "Modified: 4.3.1996 / 22:18:22 / cg"
+    "Created: 27.4.1996 / 16:42:07 / cg"
 ! !
 
 !EnterFieldGroup methodsFor:'misc'!
@@ -522,5 +678,5 @@
 !EnterFieldGroup class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libwidg/Attic/EFGroup.st,v 1.21 1996-04-25 16:33:37 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libwidg/Attic/EFGroup.st,v 1.22 1996-04-27 17:55:59 cg Exp $'
 ! !
--- a/EnterFieldGroup.st	Sat Apr 27 10:12:28 1996 +0200
+++ b/EnterFieldGroup.st	Sat Apr 27 19:55:59 1996 +0200
@@ -11,7 +11,7 @@
 "
 
 Object subclass:#EnterFieldGroup
-	instanceVariableNames:'fields currentField leaveAction wrap'
+	instanceVariableNames:'fields currentField leaveAction wrap leaveOnTabLast'
 	classVariableNames:''
 	poolDictionaries:''
 	category:'Interface-Support'
@@ -39,21 +39,29 @@
     enabling the next/prev field when a field is left. 
     Instances of this class keep track of which field of the group is the 
     currentField (i.e. the one getting keyboard input) and forwards input
-    to the active field (having the inputField delegate its input to me).
+    to that one.
+    This is done by arranging for all of my fields to delegate their
+    input to me, which is then forwarded to the active field).
 
     The block accessable as leaveAction is evaluated when the last
     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).
+    Usually this block triggers accept on the fields (if they did not already)
+    and/or performs some followup processing and possibly 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.
+    By default, tabbing via #Tab is disabled - to enable it, send the field
+    a #makeTabable or #makeAllTabable to the group.
+
+    All of this here is low level stuff, providing a lot of freedom in
+    which keys are handled and how they perform.
+    Normally, these are not required for most users - the DialogBox sets up
+    things correctly for most cases.
+
 
     [Instance variables:]
 
@@ -71,8 +79,17 @@
                                                         This is ignored, if no leaveAction was 
                                                         defined.
 
+        leaveOnTabLast  <Boolean>                       if true, tabbing out of the last
+                                                        field leaves the group.
+                                                        The default is false.
+
     [author:]
         Claus Gittinger
+
+
+    [see also:]
+        DialogBox
+        EditField
 "
 !
 
@@ -80,233 +97,323 @@
 "
     without a group - user has to enter mouse into the next field to activate it;
     Cursor-keys dont work:
-
-	|top panel field1 field2 field3|
+                                                                        [exBegin]
+        |top panel field1 field2 field3|
 
-	top := StandardSystemView new.
-	top extent:200@200.
+        top := StandardSystemView new.
+        top extent:200@200.
 
-	panel := VerticalPanelView origin:0.0@0.0 corner:1.0@1.0 in:top.
+        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)).
+        panel add:(field1 := EditField extent:(1.0 @ nil)).
+        panel add:(field2 := EditField extent:(1.0 @ nil)).
+        panel add:(field3 := EditField extent:(1.0 @ nil)).
 
-	top open
+        top open
+                                                                        [exEnd]
 
 
     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|
+     because the topView does not forward its input into the fields.
+     Also, tabbing is not possible here)
+                                                                        [exBegin]
+        |top panel group field1 field2 field3|
 
-	top := StandardSystemView new.
-	top extent:200@200.
+        top := StandardSystemView new.
+        top extent:200@200.
 
-	panel := VerticalPanelView origin:0.0@0.0 corner:1.0@1.0 in:top.
+        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)).
+        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 := EnterFieldGroup new.
+        group add:field1; add:field2; add:field3.
 
-	top open
+        top open
+                                                                        [exEnd]
 
 
 
-    same, enables tabbing via the Tab key:
+    same, enables tabbing within the group via the Tab key
+    (but still, the mouse pointer must be in one of the fields):
+                                                                        [exBegin]
+        |top panel group field1 field2 field3|
 
-	|top panel group field1 field2 field3|
+        top := StandardSystemView new.
+        top extent:200@200.
 
-	top := StandardSystemView new.
-	top extent:200@200.
+        panel := VerticalPanelView origin:0.0@0.0 corner:1.0@1.0 in:top.
 
-	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.
 
-	panel add:(field1 := EditField extent:(1.0 @ nil)).
-	panel add:(field2 := EditField extent:(1.0 @ nil)).
-	panel add:(field3 := EditField extent:(1.0 @ nil)).
+        field1 makeTabable.
+        field2 makeTabable.
+        field3 makeTabable.
+        top open
+                                                                        [exEnd]
+    individual makeTabable messages to the fields allows single
+    fields to be sticky (i.e. explicit click is needed to get out
+    of it) - this is very seldom required.
+    To make all fields tabable (the usual case), there is a shortCut:
+                                                                        [exBegin]
+        |top panel group field1 field2 field3|
 
-	group := EnterFieldGroup new.
-	group add:field1; add:field2; add:field3.
+        top := StandardSystemView new.
+        top extent:200@200.
+
+        panel := VerticalPanelView origin:0.0@0.0 corner:1.0@1.0 in:top.
 
-	field1 leaveKeys:(EditField defaultLeaveKeys copyWith:#Tab).
-	field2 leaveKeys:(EditField defaultLeaveKeys copyWith:#Tab).
-	field3 leaveKeys:(EditField defaultLeaveKeys copyWith:#Tab).
-	top open
+        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 makeAllTabable.
+
+        top open
+                                                                        [exEnd]
 
 
 
-    with a group - Return-key or CursorKey enables next field:
-    input into topView is forwarded to the group:
-
-	|top panel group field1 field2 field3|
+    use a delagation from the outerView to the group - 
+    Return-key or CursorKey enables next field:
+    input for topView is delegated to the group, which also behaves
+    as a unit w.r.t. keyboard focus (move pointer in and out).
+    Again, without tabbing:
+                                                                        [exBegin]
+        |top panel group field1 field2 field3|
 
-	top := StandardSystemView new.
-	top extent:200@200.
+        top := StandardSystemView new.
+        top extent:200@200.
+
+        panel := VerticalPanelView origin:0.0@0.0 corner:1.0@1.0 in:top.
 
-	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.
 
-	panel add:(field1 := EditField extent:(1.0 @ nil)).
-	panel add:(field2 := EditField extent:(1.0 @ nil)).
-	panel add:(field3 := EditField extent:(1.0 @ nil)).
+        top delegate:group.
+        top open
+                                                                        [exEnd]
+
+
+    and, with tabbing:
+                                                                        [exBegin]
+        |top panel group field1 field2 field3|
+
+        top := StandardSystemView new.
+        top extent:200@200.
 
-	group := EnterFieldGroup new.
-	group add:field1; add:field2; add:field3.
+        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)).
 
-	top delegate:group.
-	top open
+        group := EnterFieldGroup new.
+        group add:field1; add:field2; add:field3.
+        group makeAllTabable.
+
+        top delegate:group.
+        top open
+                                                                        [exEnd]
 
 
 
-    as above, but close the box when the last field is left:
-
-	|top panel group field1 field2 field3|
+    as above, but close the box when the last field is left
+    via return - notice, that tabbing still wraps around:
+                                                                        [exBegin]
+        |top panel group field1 field2 field3|
 
-	top := StandardSystemView new.
-	top extent:200@200.
+        top := StandardSystemView new.
+        top extent:200@200.
 
-	panel := VerticalPanelView origin:0.0@0.0 corner:1.0@1.0 in:top.
+        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)).
+        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].
+        group := EnterFieldGroup new.
+        group add:field1; add:field2; add:field3.
+        group leaveAction:[top destroy].
+        group makeAllTabable.
 
-	top delegate:group.
-	top open
-
-
+        top delegate:group.
+        top open
+                                                                        [exEnd]
 
-    same as above, with Tab-key stepping:
-
-	|top panel group field1 field2 field3|
+    in the next example, tabbing out of the last field
+    closes the box as well:
+                                                                        [exBegin]
+        |top panel group field1 field2 field3|
 
-	top := StandardSystemView new.
-	top extent:200@200.
+        top := StandardSystemView new.
+        top extent:200@200.
 
-	panel := VerticalPanelView origin:0.0@0.0 corner:1.0@1.0 in:top.
+        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].
+        panel add:(field1 := EditField extent:(1.0 @ nil)).
+        panel add:(field2 := EditField extent:(1.0 @ nil)).
+        panel add:(field3 := EditField extent:(1.0 @ nil)).
 
-	field1 leaveKeys:(EditField defaultLeaveKeys copyWith:#Tab).
-	field2 leaveKeys:(EditField defaultLeaveKeys copyWith:#Tab).
-	field3 leaveKeys:(EditField defaultLeaveKeys copyWith:#Tab).
+        group := EnterFieldGroup new.
+        group add:field1; add:field2; add:field3.
+        group leaveAction:[top destroy].
+        group makeAllTabable.
+        group leaveOnTabLast:true.
 
-	top delegate:group.
-	top open
-
+        top delegate:group.
+        top open
+                                                                        [exEnd]
 
 
     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:
     (i.e. you can arrange your fields in multiple framedBoxes, panels or
      subviews - independent of the tab-stepping order)
-
-	|top panel group field1 field2 field3|
+                                                                        [exBegin]
+        |top panel group field1 field2 field3|
 
-	top := StandardSystemView new.
-	top extent:200@200.
+        top := StandardSystemView label:'reverse'.
+        top extent:200@200.
 
-	panel := VerticalPanelView origin:0.0@0.0 corner:1.0@1.0 in:top.
+        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)).
+        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].
+        group := EnterFieldGroup new.
+        group add:field3; add:field2; add:field1.
+        group leaveAction:[top destroy].
+        group makeAllTabable.
 
-	top delegate:group.
-	top open
+        top delegate:group.
+        top open
+                                                                        [exEnd]
 
 
 
     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|
+                                                                        [exBegin]
+        |top panel group field1 field2 field3 model
+         value1 value2 value3|
 
-	top := StandardSystemView new.
-	top extent:200@200.
+        top := StandardSystemView new.
+        top extent:200@200.
 
-	panel := VerticalPanelView origin:0.0@0.0 corner:1.0@1.0 in:top.
+        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)).
+        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].
+        group := EnterFieldGroup new.
+        group add:field1; add:field2; add:field3.
+        group leaveAction:[top destroy].
+        group makeAllTabable.
 
-	value1 := 'one'. value2 := 'two'. value3 := 'three'.
+        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].
+        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:.
+        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.
+        top delegate:group.
+        top openModal.
 
-	Transcript showCr:'value1: ' , value1.
-	Transcript showCr:'value2: ' , value2.
-	Transcript showCr:'value3: ' , value3.
+        Transcript showCr:'value1: ' , value1.
+        Transcript showCr:'value2: ' , value2.
+        Transcript showCr:'value3: ' , value3.
+                                                                        [exEnd]
 
 
-    the above is done automatically for you, if you add inputFields
-    to a dialogBox:
+    all of the above is done automatically for you, 
+    if you add inputFields to a dialogBox.
+    Here, all fields use the same model, but different aspects:
+                                                                        [exBegin]
+        |box model
+         value1 value2 value3|
+
+        box := DialogBox new.
+        box extent:200@200.
+
+        value1 := 'one'. value2 := 'two'. value3 := 'three'.
 
-	|box model
-	 value1 value2 value3|
+        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 := DialogBox new.
-	box extent:200@200.
+        (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:.
 
-	value1 := 'one'. value2 := 'two'. value3 := 'three'.
+        box addOkButton.
+
+        box open.
 
-	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].
+        Transcript showCr:'value1: ' , value1.
+        Transcript showCr:'value2: ' , value2.
+        Transcript showCr:'value3: ' , value3.
+                                                                        [exEnd]
+
+    Here, the fields use different models, but the same aspect:
+                                                                        [exBegin]
+        |box model
+         valueHolder1 valueHolder2 valueHolder3|
+
+        box := DialogBox new.
+        box extent:200@200.
+
+        valueHolder1 := 'one' asValue. 
+        valueHolder2 := 'two' asValue. 
+        valueHolder3 := 'three' asValue.
 
-	(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 addInputFieldOn:valueHolder1.
+        box addVerticalSpace.
+        box addInputFieldOn:valueHolder2.
+        box addVerticalSpace.
+        box addInputFieldOn:valueHolder3.
+
+        box addOkButton.
 
-	box open.
+        box open.
 
-	Transcript showCr:'value1: ' , value1.
-	Transcript showCr:'value2: ' , value2.
-	Transcript showCr:'value3: ' , value3.
+        Transcript showCr:'value1: ' , valueHolder1 value.
+        Transcript showCr:'value2: ' , valueHolder2 value.
+        Transcript showCr:'value3: ' , valueHolder3 value.
+                                                                        [exEnd]
 "
+
+    "Created: 27.4.1996 / 16:43:28 / cg"
 ! !
 
 !EnterFieldGroup methodsFor:'accessing'!
@@ -325,13 +432,37 @@
     leaveAction := aBlock
 !
 
+leaveOnTabLast:aBoolean
+    "specifies if leaving the last field via Tab
+     should leave the group or stay in the group.
+     (if staying, either wrap or not, depending on the setting of wrap)
+     The default is to stay in the group"
+
+    leaveOnTabLast := aBoolean
+
+    "Created: 27.4.1996 / 17:22:30 / cg"
+    "Modified: 27.4.1996 / 17:22:44 / cg"
+!
+
+makeAllTabable
+    "make all fields tabable"
+
+    fields do:[:field |
+        field makeTabable
+    ]
+
+    "Created: 27.4.1996 / 17:11:41 / cg"
+!
+
 wrap:aBoolean
     "specifies if leaving the last field via non-Return
-     should wrap back to the first, or leave the group.
-     The default is to stay in the input sequence and wrap back to 
-     the first field."
+     (i.e. Tab or Cursor-Down) should wrap back to the first, 
+     or leave the group.
+     The default is to not leave the group and wrap back to the first field."
 
     wrap := aBoolean
+
+    "Modified: 27.4.1996 / 17:19:50 / cg"
 ! !
 
 !EnterFieldGroup methodsFor:'adding / removing'!
@@ -340,7 +471,7 @@
     |thisIndex action|
 
     fields isNil ifTrue:[
-	fields := OrderedCollection new
+        fields := OrderedCollection new
     ].
     fields add:aField.
     thisIndex := fields size.
@@ -352,75 +483,78 @@
     "set the fields enableAction to disable active field"
 
     aField clickAction:[:field |
-	self makeActive:field
+        self makeActive:field
     ].
 
     "set the fields leaveAction to enable next field"
 
     aField leaveAction:[:key |
-	|next wg explicit nFields nextField|
+        |next wg explicit nFields nextField|
 
 "/        currentField notNil ifTrue:[
 "/            currentField disable.
 "/            currentField hideCursor.
 "/        ].
 "/
-	action := key.
-	nFields := fields size.
+        action := key.
+        nFields := fields size.
 
-	((key == #CursorUp) or:[key == #PreviousField]) ifTrue:[
-	    (thisIndex == 1) ifTrue:[
-		next := nFields
-	    ] ifFalse:[
-		next := thisIndex - 1
-	    ]
-	].
-	((key == #CursorDown) 
-	or:[key == #NextField
-	or:[key == #Tab]]) ifTrue:[
-	    (thisIndex == nFields) ifTrue:[
-		next := 1.
-		wrap == false ifTrue:[
-		    action := #Return.
-		].
-	    ] ifFalse:[
-		next := thisIndex + 1
-	    ]
-	].
-	(action == #Return) ifTrue:[
-	    (thisIndex == nFields) ifTrue:[
-		leaveAction notNil ifTrue:[
-		    currentField := nil.
-		    leaveAction value.
-		    next := nil
-		] ifFalse:[
-		    next := 1
-		]
-	    ] ifFalse:[
-		next := thisIndex + 1
-	    ]
-	].
-	next notNil ifTrue:[
-	    nextField := fields at:next.
+        ((key == #CursorUp) or:[key == #PreviousField]) ifTrue:[
+            (thisIndex == 1) ifTrue:[
+                next := nFields
+            ] ifFalse:[
+                next := thisIndex - 1
+            ]
+        ].
+        ((key == #CursorDown) 
+        or:[key == #NextField
+        or:[key == #Tab]]) ifTrue:[
+            (thisIndex == nFields) ifTrue:[
+                next := 1.
+                wrap == false ifTrue:[
+                    action := #Return.
+                ].
+            ] ifFalse:[
+                next := thisIndex + 1
+            ]
+        ].
+        ((action == #Return)
+        or:[key == #Tab and:[leaveOnTabLast == true]]) ifTrue:[
+            (thisIndex == nFields) ifTrue:[
+                leaveAction notNil ifTrue:[
+                    currentField := nil.
+                    leaveAction value.
+                    next := nil
+                ] ifFalse:[
+                    next := 1
+                ]
+            ] ifFalse:[
+                next := thisIndex + 1
+            ]
+        ].
+        next notNil ifTrue:[
+            nextField := fields at:next.
 
-	    explicit := false.
-	    (wg := currentField windowGroup) notNil ifTrue:[
-		wg focusView == currentField ifTrue:[
-		    explicit := true.
-		]
-	    ].
-	    explicit ifTrue:[
-		wg focusView:nextField.
-	    ] ifFalse:[
-		self makeActive:nextField 
-	    ]
-	]
+            explicit := false.
+            (wg := currentField windowGroup) notNil ifTrue:[
+                wg focusView == currentField ifTrue:[
+                    explicit := true.
+                ]
+            ].
+            explicit ifTrue:[
+                wg focusView:nextField.
+            ] ifFalse:[
+                self makeActive:nextField 
+            ]
+        ]
     ].
 
     fields size == 1 ifTrue:[
-	"the first one"
-	self makeActive:aField
+        "the first one"
+        self makeActive:aField
     ]
+
+    "Modified: 27.4.1996 / 17:21:09 / cg"
 ! !
 
 !EnterFieldGroup methodsFor:'event forwarding'!
@@ -487,6 +621,28 @@
     currentField notNil ifTrue:[
 	currentField keyRelease:key x:-1 y:-1
     ]
+!
+
+showFocus:onOrOff
+    "forward focus display to the active field "
+
+    currentField notNil ifTrue:[
+        currentField showFocus:onOrOff
+    ]
+
+    "Modified: 4.3.1996 / 22:18:22 / cg"
+    "Created: 27.4.1996 / 16:41:38 / cg"
+!
+
+showNoFocus:onOrOff
+    "forward nofocus display to the active field "
+
+    currentField notNil ifTrue:[
+        currentField showNoFocus:onOrOff
+    ]
+
+    "Modified: 4.3.1996 / 22:18:22 / cg"
+    "Created: 27.4.1996 / 16:42:07 / cg"
 ! !
 
 !EnterFieldGroup methodsFor:'misc'!
@@ -522,5 +678,5 @@
 !EnterFieldGroup class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libwidg/EnterFieldGroup.st,v 1.21 1996-04-25 16:33:37 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libwidg/EnterFieldGroup.st,v 1.22 1996-04-27 17:55:59 cg Exp $'
 ! !