Allow individual applications to define their own shortcut mapping jv
authorJan Vrany <jan.vrany@fit.cvut.cz>
Wed, 08 Feb 2017 23:58:18 +0000
branchjv
changeset 7969 2bac4f32553f
parent 7856 7c52e7a9a087
child 7970 43c6888f5f92
Allow individual applications to define their own shortcut mapping When a system wants to translate a shortcut into a logical action key, it asks a view to it's keyboard map which porivdes such translations. Histrically, there was only one such map kept in window device. To allow per-application customization, each view by default returns its parent's view map. The top level window then asks its underlaying application model for a map. This way, each application may provide its own shortcut mappings or override / inhibit global ones. Keyboard mappings may be chained to from a hiearchy: if a mapping is not found in given keyboard map, it's parent map (if any) is asked for the mapping. Usually a device's keyboard map is at the top of the hiearchy (but not necessarily)
DeviceWorkstation.st
KeyboardMap.st
SimpleView.st
--- a/DeviceWorkstation.st	Sat Feb 04 23:21:45 2017 +0000
+++ b/DeviceWorkstation.st	Wed Feb 08 23:58:18 2017 +0000
@@ -2924,9 +2924,26 @@
 !
 
 shortKeyStringFor:symbolicOrRawKey
+    "Obsolete: For given symbolic or raw key, return a user-friendly shortcut description string.
+     Examples:
+       #Find -> Ctrl+f (depending on your default)
+       #CtrlX -> Ctrl+X
+
+     This method is used in menu panel (#shortcutKeyAsString) to display shortcuts in menus.
+    "
+    <resource: #obsolete>
+
+    self obsoleteMethodWarning: 'Use #shortKeyStringFor:usingMap: instead'.  
+    ^ self shortKeyStringFor: symbolicOrRawKey usingMap: self keyboardMap
+
+    "Created: / 08-08-2006 / 15:45:38 / cg"
+    "Modified: / 08-02-2017 / 23:54:50 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+shortKeyStringFor:symbolicOrRawKey usingMap: kbdMap
     "For given symbolic or raw key, return a user-friendly shortcut description string.
      Examples:
-       #Find -> Ctrl+f (depending on your settings)
+       #Find -> Ctrl+f (depending mapping in `kbdMap` parameter)
        #CtrlX -> Ctrl+X
 
      This method is used in menu panel (#shortcutKeyAsString) to display shortcuts in menus.
@@ -2938,14 +2955,13 @@
     "/ but want to know the untranslated (inverse keyBoardMapped) key & modifier
     "/ this is used in the menu, to show the shortCut key beside the items.
 
-    untranslatedKeys := OrderedCollection new.
-    self keyboardMap keysAndValuesDo:[:k :v | v == symbolicOrRawKey ifTrue:[untranslatedKeys add:k]].
-    untranslatedKeys size == 0 ifTrue:[
-	"/ if its not an explicit command key (Ctrl-*, Alt-* or Cmd-*),
-	"/ but a symbolic key, return nil.
-	(#('Cmd' 'Ctrl' 'Alt' 'Meta' 'Shift')
-	    contains:[:k | (symbolicOrRawKey startsWith:k) ])
-		ifFalse:[^ nil].
+    untranslatedKeys := kbdMap rawKeysForLogical: symbolicOrRawKey.
+    untranslatedKeys isEmpty ifTrue:[
+        "/ if its not an explicit command key (Ctrl-*, Alt-* or Cmd-*),
+        "/ but a symbolic key, return nil.
+        (#('Cmd' 'Ctrl' 'Alt' 'Meta' 'Shift')
+            contains:[:k | (symbolicOrRawKey startsWith:k) ])
+                ifFalse:[^ nil].
 
 "/        (aSymbolicKey startsWith:'Cmd') ifFalse:[
 "/            (aSymbolicKey startsWith:'Ctrl') ifFalse:[
@@ -2958,43 +2974,43 @@
 "/                ].
 "/            ].
 "/        ].
-	untranslatedKey := symbolicOrRawKey.
+        untranslatedKey := symbolicOrRawKey.
     ] ifFalse:[
-	untranslatedKeys size == 1 ifTrue:[
-	    untranslatedKey := untranslatedKeys first.
-	] ifFalse:[
-	    "if there are multiple mappings, show the Ctrl or the F-key mapping"
-	    untranslatedKey := untranslatedKeys
-				detect:[:k |k startsWith:'Ctrl']
-				ifNone:[
-				    untranslatedKeys
-					detect:[:k |k startsWith:'F']
-					ifNone:[untranslatedKeys first]].
-	].
+        untranslatedKeys size == 1 ifTrue:[
+            untranslatedKey := untranslatedKeys first.
+        ] ifFalse:[
+            "if there are multiple mappings, show the Ctrl or the F-key mapping"
+            untranslatedKey := untranslatedKeys
+                                detect:[:k |k startsWith:'Ctrl']
+                                ifNone:[
+                                    untranslatedKeys
+                                        detect:[:k |k startsWith:'F']
+                                        ifNone:[untranslatedKeys first]].
+        ].
     ].
 
     "/
     "/ some modifier-key combination ?
     "/
     (untranslatedKey startsWith:#Cmd) ifTrue:[
-	prefix := #Cmd.
+        prefix := #Cmd.
     ] ifFalse:[(untranslatedKey startsWith:#Alt) ifTrue:[
-	prefix := #Alt.
+        prefix := #Alt.
     ] ifFalse:[(untranslatedKey startsWith:#Meta) ifTrue:[
-	prefix := #Meta.
+        prefix := #Meta.
     ] ifFalse:[(untranslatedKey startsWith:#Ctrl) ifTrue:[
-	prefix := #Ctrl.
+        prefix := #Ctrl.
     ]]]].
 
     prefix notNil ifTrue:[
-	|modifier rest|
-
-	modifier := self modifierKeyTopFor:prefix.
-	modifier := (modifier ? prefix).
-	rest := (untranslatedKey copyFrom:(prefix size + 1)).
-	rest isEmpty ifTrue:[^ modifier ].
-	modifier := modifier , (self shortKeyPrefixSeparator).
-	^ modifier , rest
+        |modifier rest|
+
+        modifier := self modifierKeyTopFor:prefix.
+        modifier := (modifier ? prefix).
+        rest := (untranslatedKey copyFrom:(prefix size + 1)).
+        rest isEmpty ifTrue:[^ modifier ].
+        modifier := modifier , (self shortKeyPrefixSeparator).
+        ^ modifier , rest
     ].
     ^ untranslatedKey
 
@@ -3004,8 +3020,7 @@
     Screen current shortKeyStringFor: #CursorLeft
     "
 
-    "Created: / 08-08-2006 / 15:45:38 / cg"
-    "Modified (comment): / 28-04-2014 / 10:04:28 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Created: / 08-02-2017 / 23:28:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !
 
 !DeviceWorkstation methodsFor:'accessing-misc'!
@@ -8324,6 +8339,11 @@
 
 version_CVS
     ^ '$Header$'
+!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
 ! !
 
 
--- a/KeyboardMap.st	Sat Feb 04 23:21:45 2017 +0000
+++ b/KeyboardMap.st	Wed Feb 08 23:58:18 2017 +0000
@@ -149,6 +149,28 @@
     parent := aKeyboardMap.
 !
 
+rawKeysForLogical: logicalKey
+    "Return all raw keys for given )possibly) logical key.
+     Example:
+       #Copy -> #(Ctrlc) - depending on mappings
+    "
+    | map rawKeys |
+
+    map := self.
+    rawKeys := #().
+    [ rawKeys isEmpty and:[ map notNil ] ] whileTrue:[
+        map keysAndValuesDo:[ :raw :logical | logical == logicalKey ifTrue:[ rawKeys := rawKeys copyWith: raw ] ].
+        map := map parent.
+    ].
+    ^ rawKeys
+
+    "
+    Screen current keyboardMap rawKeysForLogical: #Copy
+    "
+
+    "Created: / 08-02-2017 / 23:43:26 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
 valueFor:aKey
     "retrieve a logical key"
 
--- a/SimpleView.st	Sat Feb 04 23:21:45 2017 +0000
+++ b/SimpleView.st	Wed Feb 08 23:58:18 2017 +0000
@@ -3956,6 +3956,14 @@
     "Created: 4.6.1996 / 21:32:11 / cg"
 ! !
 
+!SimpleView methodsFor:'accessing-keyboard mappings'!
+
+shortKeyStringFor:symbolicOrRawKey
+    ^ device shortKeyStringFor:symbolicOrRawKey usingMap: self keyboardMap.
+
+    "Created: / 08-02-2017 / 23:20:12 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
 !SimpleView methodsFor:'accessing-menus'!
 
 menuHolder