SelListV.st
changeset 38 4b9b70b2cc87
parent 31 2224b4d173f7
child 51 e895ac4cc7c8
--- a/SelListV.st	Sun Aug 07 15:22:53 1994 +0200
+++ b/SelListV.st	Sun Aug 07 15:23:42 1994 +0200
@@ -19,7 +19,7 @@
                               listAttributes multipleSelectOk clickLine
                               listSymbol initialSelectionSymbol printItems oneItem
                               hilightLevel hilightFrameColor ignoreReselect
-                              arrowLevel smallArrow'
+                              arrowLevel smallArrow keyActionStyle'
        classVariableNames:   'RightArrowShadowForm RightArrowLightForm RightArrowForm
                               SmallRightArrowShadowForm SmallRightArrowLightForm'
        poolDictionaries:''
@@ -27,25 +27,56 @@
 !
 
 SelectionInListView comment:'
-
 COPYRIGHT (c) 1989 by Claus Gittinger
               All Rights Reserved
+
+$Header: /cvs/stx/stx/libwidg/Attic/SelListV.st,v 1.9 1994-08-07 13:23:23 claus Exp $
 '!
 
 !SelectionInListView class methodsFor:'documentation'!
 
+copyright
+"
+ COPYRIGHT (c) 1989 by Claus Gittinger
+              All Rights Reserved
+
+ This software is furnished under a license and may be used
+ only in accordance with the terms of that license and with the
+ inclusion of the above copyright notice.   This software may not
+ be provided or otherwise made available to, or used by, any
+ other person.  No title to or ownership of the software is
+ hereby transferred.
+"
+!
+
+version
+"
+$Header: /cvs/stx/stx/libwidg/Attic/SelListV.st,v 1.9 1994-08-07 13:23:23 claus Exp $
+"
+!
+
 documentation
 "
     this one is a ListView with a selected line (which is shown highlighted)
-    If multipleSelectionsOk is true, it is also allowed to shift-click multiple entries.
+    If multipleSelectionsOk is true, it is also allowed to shift-click multiple 
+    entries.
 
-    Whenever the selection changes, an action-block is called for,
-    passing the current selection as argument.
-    Currently, the selection can be nil, aNumber or a collection of
-    numbers; this will change to be either nil or a collection, making
-    selection handling easier in the future.
+    Whenever the selection changes, an action-block is evaluated, passing the 
+    current selection as argument.
+    Currently, the selection can be nil, aNumber or a collection of numbers; 
+    this will change to be either nil or a collection, making selection handling 
+    easier in the future.
     The actionBlock is called with the current selection as argument.
 
+    It is also possible to select entries with the keyboard; use the cursor up/
+    down keys to select prev/next, Home- and End-keys to select first/last. 
+    Use the return key to apply the double-click-action to the current selection.
+    Also, alphabetic keys will select the next entry starting with that key.
+
+    The keyboard behavior can be further controlled with the keyActionStyle
+    instance variable (see SelectionInListView>>keyActionStyle:).
+
+
     InstanceVariables:
         selection               <misc>          the current selection. nil, a number or collection of numbers
 
@@ -79,12 +110,12 @@
         printItems 
         oneItem
 
-
-    $Header: /cvs/stx/stx/libwidg/Attic/SelListV.st,v 1.8 1994-06-02 18:30:26 claus Exp $
+        keyActionStyle          <Symbol>        controls how to respond to keyboard selects
 
     written spring/summer 89 by claus
     3D Jan 90 by claus
-    multiselect Jun 92 my claus
+    multiselect Jun 92 by claus
+    keyboard-select jun 94 by claus
 "
 ! !
 
@@ -268,6 +299,7 @@
     multipleSelectOk := false.
     enabled := true.
     ignoreReselect := true.
+    keyActionStyle := #select.
 !
 
 initStyle
@@ -396,6 +428,22 @@
     ignoreReselect := aBoolean
 !
 
+keyActionStyle:aSymbol
+    "defines how the view should respond to alpha-keys pressed.
+     Possible values are:
+        #select               -> will select next entry starting with that
+                                 character and perform the click-action
+
+        #selectAndDoubleclick -> will select next & perform double-click action
+
+        #pass                 -> will pass key to superclass (i.e. no special treatment)
+
+        nil                   -> will ignore key
+    "
+
+    keyActionStyle := aSymbol
+!
+
 setList:aCollection
     "set the list - redefined, since setting the list implies unselecting"
 
@@ -820,15 +868,15 @@
 scrollSelectDown
     "auto scroll action; scroll and reinstall timed-block"
 
-    Processor addTimedBlock:autoScrollBlock after:autoScrollDeltaT.
-    self scrollDown
+    self scrollDown.
+    Processor addTimedBlock:autoScrollBlock afterSeconds:autoScrollDeltaT.
 !
 
 scrollSelectUp
     "auto scroll action; scroll and reinstall timed-block"
 
-    Processor addTimedBlock:autoScrollBlock after:autoScrollDeltaT.
-    self scrollUp
+    self scrollUp.
+    Processor addTimedBlock:autoScrollBlock afterSeconds:autoScrollDeltaT.
 ! !
 
 !SelectionInListView methodsFor:'redrawing'!
@@ -838,7 +886,7 @@
      This method is not used here, but provided for subclasses such
      as menus or file-lists."
 
-    |w h y x l form form2 topLeftColor botRightColor t|
+    |y x form form2 topLeftColor botRightColor t|
 
     x := width - 16.
     y := (self yOfLine:visLineNr).
@@ -1065,42 +1113,102 @@
     ]
 !
 
+key:key select:selectAction x:x y:y
+    "perform keyaction after a key-select"
+
+    keyActionStyle notNil ifTrue:[
+        keyActionStyle == #pass ifTrue:[
+            ^ super keyPress:key x:x y:y
+        ].
+        selectAction value.
+        actionBlock notNil ifTrue:[actionBlock value:selection].
+        keyActionStyle == #selectAndDoubleClick ifTrue:[
+            doubleClickActionBlock notNil ifTrue:[doubleClickActionBlock value:selection].
+        ]
+    ].
+!
+
 keyPress:key x:x y:y
     "handle keyboard input"
 
+    |index startSearch|
+
     (keyboardHandler notNil
     and:[keyboardHandler canHandle:key]) ifTrue:[
         keyboardHandler keyPress:key x:x y:y.
         ^ self
     ].
-    (selection isKindOf:Collection) ifFalse:[
-        (key == #CursorUp)        ifTrue:[
+    (selection size == 0) ifTrue:[
+        "/ not a multi-selection
+        (key == #CursorUp) ifTrue:[
+            (selectConditionBlock isNil or:[selectConditionBlock value]) ifTrue:[
+                self key:key select:[self selectPrevious] x:x y:y
+            ].
+            ^ self
+        ].
+        (key == #CursorDown) ifTrue:[
             (selectConditionBlock isNil or:[selectConditionBlock value]) ifTrue:[
-                self selectPrevious.
-                actionBlock notNil ifTrue:[actionBlock value:selection].
+                self key:key select:[self selectNext] x:x y:y
+            ].
+            ^ self
+        ].
+        (key == #Home) ifTrue:[
+            (selectConditionBlock isNil or:[selectConditionBlock value]) ifTrue:[
+                self key:key select:[self selection:1] x:x y:y
+            ].
+            ^ self
+        ].
+        (key == #End) ifTrue:[
+            (selectConditionBlock isNil or:[selectConditionBlock value]) ifTrue:[
+                self key:key select:[self selection:list size] x:x y:y
             ].
             ^ self
         ].
-        (key == #CursorDown)      ifTrue:[
-            (selectConditionBlock isNil or:[selectConditionBlock value]) ifTrue:[
-                self selectNext.
-                actionBlock notNil ifTrue:[actionBlock value:selection].
+    ].
+    key == #Return ifTrue:[
+        selection notNil ifTrue:[
+            doubleClickActionBlock notNil ifTrue:[
+                doubleClickActionBlock value:selection
             ].
             ^ self
-        ].
-        (key == #Home)      ifTrue:[
-            (selectConditionBlock isNil or:[selectConditionBlock value]) ifTrue:[
-                self selection:1. 
-                actionBlock notNil ifTrue:[actionBlock value:selection].
-            ].
-            ^ self
-        ].
-        (key == #End)       ifTrue:[
-            (selectConditionBlock isNil or:[selectConditionBlock value]) ifTrue:[
-                self selection:list size. 
-                actionBlock notNil ifTrue:[actionBlock value:selection].
-            ].
-            ^ self
+        ]
+    ].
+    "
+     alphabetic keys: search for next entry
+     starting with keys character
+    "
+    list size > 0 ifTrue:[
+        key isCharacter ifTrue:[
+            key isLetter ifTrue:[
+                keyActionStyle isNil ifTrue:[^ self].
+                keyActionStyle == #pass ifFalse:[
+                    selection notNil ifTrue:[
+                        selection size > 0 ifTrue:[
+                            startSearch := selection last + 1
+                        ] ifFalse:[
+                            startSearch := selection + 1
+                        ]
+                    ] ifFalse:[
+                        startSearch := 1
+                    ].
+                    startSearch > list size ifTrue:[
+                        startSearch := 1.
+                    ].
+                    index := startSearch.
+                    [true] whileTrue:[
+                        (((list at:index) at:1) asLowercase == key asLowercase) ifTrue:[
+                            ^ self key:key select:[self selection:index] x:x y:y
+                        ].
+                        index := index + 1.
+                        index > list size ifTrue:[
+                            index := 1
+                        ].
+                        index == startSearch ifTrue:[
+                            ^ self
+                        ]
+                    ]
+                ]
+            ]
         ].
     ].
     ^ super keyPress:key x:x y:y