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)
--- 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