The key-binding mechanism used in OsmondCocoa is similar to the key-binding mechanism used in the Cocoa Text system. An excellent description of the Cocoa Text system by Jacob Rus can be found here, from which I have shamelessly borrowed.
OsmondCocoa uses a generalized key-binding mechanism that is completely re-mappable by the user. Key bindings are specified in a dictionary file that should be placed at:
~/Library/Application Support/OsmondCocoa/keyBindings.dict
Create the OsmondCocoa
folder if it does not already exist. This file is a normal Property List, which can be created either with a text editor or with Apple’s Property List Editor (installed with the developer tools). There are two types of property lists, old-style NeXT text files, and newer XML formatted files. Either type will work but the examples below use the old-style plists because they are easier to read and understand; they are more compact, with less distracting markup.
The NeXT property list format is a file format that can describe, using plain text, all of the objects used in Cocoa programs. We specifically care about 2 types: “strings” and “dictionaries”:
-
A string is simply a sequence of letters, numbers, and symbols, such as:
"this is a string with some $#@! symbols"
- A dictionary contains pairs of “keys” and “values”. Basically, dictionaries provide a way to name a bunch of objects, and refer to them by name.
{"key1" = "value1"; "key2" = "value2"; "key3" = "value3";}
- In addition, comments can be added to old-style property lists by enclosing
some text in
/*
and*/
.
The format of keyBindings.dict
The keyBindings.dict file format is fairly straight-forward. It is a normal property list, with the keys being strings that specify the requested key bindings, and the values being strings that specify the commands they should execute. For instance, if you want the letter v to cause the Via tool to be selected, simply put the following in your keyBindings.dict file.
{
/* This makes the letter v select the Via tool. */
"v" = "selectViaTool:";
}
How to represent bindings
But of course, if we could only bind things to letter keys, this wouldn’t really be so useful, now would it? Fortunately, Apple’s engineers made sure that every key that you could possibly ever type can be put into a binding. The way it works is simple. For lower-case and capital letters, simply type the letter into the string. So "y" represents the “y” key, while "T" represents “Shift-t”. For numbers and symbols, including space, the same holds. So "!" represents “Shift-1”, or however you type “!” on your keyboard layout. To add modifier keys, add a symbol corresponding to that modifier:
"@t"
= Command-t
"^t"
= Control-t
"~t"
= Option-t
"@^T"
= Command-Control-Shift-t
"~ "
= Option-space
For numbers and symbols, to add the shift key is not as easy as typing a capital letter, so $ stands for shift.
Note: Lots of bindings with the Command key won’t work. This is done by Apple to ensure that applications can use these shortcuts for themselves, and not worry about user key bindings. Some will work, however, such as “Command-right arrow”. There are two special cases: First, if we want to bind a literal “@” or “&” symbol, we escape it by adding a \ before the symbol.
"~\$"
= Option-$
Second, special non-letter keys like “delete”, “tab”, and “esc” are entered using their unicode values. The following shows unicode values for many non-letter keys:
Escape: | \U001B |
Tab: | \U0009 |
Backtab: | \U0019 |
Return: | \U000A |
Enter: | \U000D |
Delete: | \U007F |
Up Arrow: | \UF700 |
Down Arrow: | \UF701 |
Left Arrow: | \UF702 |
Right Arrow: | \UF703 |
Help: | \UF746 |
Forward Delete: | \UF728 |
Home: | \UF729 |
End: | \UF72B |
Page Up: | \UF72C |
Page Down: | \UF72D |
Clear: | \UF739 |
F1: | \UF704 |
F2: | \UF705 |
F3: | \UF706 |
… | |
F35 | \UF726 |
Not on Apple keyboards: | |
Menu: | \UF735 |
To illustrate the use of special keys, we can change the default behavior of OsmondCocoa’s arrow keys. Normally, pressing an arrow key scrolls the view but pressing the arrow key and option key moves the selected parts. To reverse this behavior, place the following in the keyBindings.dict
file.
/* OsmondCocoa key-bindings */
{
"~\UF700" = "scrollUp:"; /* Option Up-arrow */
"~\UF701" = "scrollDown:"; /* Option Down-arrow */
"~\UF702" = "scrollLeft:"; /* Option Left-arrow */
"~\UF703" = "scrollRight:"; /* Option Right-arrow */
"\UF700" = "moveSelectedUp:"; /* Up-arrow */
"\UF701" = "moveSelectedDown:"; /* Down-arrow */
"\UF702" = "moveSelectedLeft:"; /* Left-arrow */
"\UF703" = "moveSelectedRight:"; /* Right-arrow */
}
Available Commands
The following commands are currently available for key-binding. Make sure that you include the colon at the end; it is an essential part of the command.
Commands to change the current layer
selectFrontSilkLayer:
selectBackSilkLayer:
selectFrontMaskLayer:
selectBackMaskLayer:
selectFrontAuxLayer:
selectBackAuxLayer:
selectLayer1:
selectLayer2:
...
selectLayer15:
selectLayer16:
Commands to move selected items
moveSelectedLeft:
moveSelectedRight:
moveSelectedUp:
moveSelectedDown:
Scroll commands
scrollLeft:
scrollRight:
scrollUp:
scrollDown:
Tool selection commands
selectSelectTool:
selectMagnifyTool:
selectTurnTool:
selectFlipTool:
selectJoinTool:
selectAttachTool:
selectSwapTool:
selectCutTool:
selectPegTool:
selectWrapTool:
selectQuickRouteTool:
selectTraceWidthTool:
selectInfoTool:
selectOriginTool:
selectDrawTool:
selectTextTool:
selectFilletTool:
selectPadChangeTool:
selectPinChangeTool:
selectNewPinTool:
selectThermalTool:
selectCheckTool:
selectViaTool:
selectNewPartTool:
View size commands
handleActualSize:
handleDoubleSize:
handleFullView:
handleZoomIn:
handleZoomOut:
Editing commands
selectAll:
cut:
copy:
paste:
Grid commands
handleSnapToGrid:
handleMajorGrid:
handleMinorGrid:
Design check commands
handleCheckCurrentLayer:
handleCheckAllLayers:
handleNextSignal:
handlePreviousSignal:
Rats nest commands
handleMakeRatsNest:
handleDestroyRatsNest:
handleMakeOneRatsNest:
handleDestroyOneRatsNest:
Miscellaneous commands
handleFindOverlappingHoles:
handleFindMultipleThermalConnections:
handleFindConflictingPins:
handleFlipOver:
handleUpdateAllParts: