Tuesday, August 2, 2011

key bindings

In a program with no menus and no buttons, keybindings can be a problem.  Of course I side step a lot of problems by having the main interface be textual commands, and similarly to acme I can make an ad-hoc menu or button by typing text and clicking on it, but I also want to bind certain common actions to keys.  I think this is justifiable because music is more complicated than text, so there is a wider range of common actions.

Still it's embarrassing when I forget the keys for my own program and have to constantly go back to the source to remind myself.  So I wrote a little auxiliary program that extracts the global bindings and formats them nicely.  The first thing I noticed was that I'd managed to map just about every letter.  They go fast.

I'm not sure if there's a discipline to be applied for key assignment, I'm just making it up as I go along.  I think around 40 or so arbitrary words can be memorized without too much trouble, but you can go much higher if some kind of deeper structure can be imposed.

One thing I want to explore is a sort of syntax for temporarily applying time steps.  The idea is that if you can easily make a selection you can more easily apply general purpose operations.  For example, a possible sequence to align a note would be switch to meter time step to snap to a beat, perhaps temporarily switch to event edge time step by holding a key and extend the selection to the next event, and then invoke "move event" to align the event with the beat, or likewise, shift another event by the difference between the beat and this one.  Since "block end" and "block beginning" are time steps, this can remove the need for separate "select to end" or "select all" cmds.  Time step is also used for default note length, step play distance, and everything else ScoreTime-oriented, so the same techniques are applicable in many contexts.  With any luck I can develop a little vocabulary of building blocks: set time step, move or extend selection, reposition events, etc. and with familiarity play them as any instrument.  I currently only have one selection, but the possibility is open to have multiple selections, for cmds that require two time ranges, say to swap the contents.  I have never seen another app that does this though.

Of course, this is all on top of being able to map the keyboard to an organ-like layout to enter notes.  All non-modified keystrokes are captured by note input, so only the cmd keys are available in note entry mode.  The other guideline was to leave the secondary modifier unused, so it can be reserved for ad-hoc bindings created at runtime or per-score.

I initially had the ability to map any key chord combination, not just modifiers, but it was too hard to keep in sync with the state of the real keyboard, and I think the OS itself doesn't keep track of non-modifier key state, so if it swallows a key-up due to a focus change it's easy for the app to get out of sync with the real keyboard state, with annoying results.  Probably just as well since trying to do arbitrary keyboard chords is overkill, but there is still a MIDI keyboard available for binding and I haven't explored the possibilities of chording (literally) over there.  This is a bit opposite to the computer keyboard, since chords are easy but absolute positioned keys are not, unless you say all Cs are the same binding.  Perhaps a held interval can activate a certain time step: minor third for a quarter note, major third for a half note, etc.  And then the mouse chords are still unmapped.  I'm not sure that cut and paste are as useful in music as text so I don't need to follow acme's lead here, but it's a good example of well chosen primitives.

Then on top of all of this is the tension between representing transformations abstractly as symbols in the score, and applying them concretely to notes.  Anything systematic should probably be notation, rather than an action.  For example a time step of a small absolute offset from a note can be used to easily create grace notes, or I could use the same space to easily create the grace note ornament.  I could resolve some tension with a cmd to flatten certain kinds of notation back into notes for concrete manipulation, but once you go down to the low level you can't go back up easily.  In any case, I don't think I want cmds operating in RealTime, I think that should remain in the deriver's domain.

Here's the current state of the keymap:

cmd ' quit
- octave -1
0, cmd 0 step rank 0+0
1, cmd 1 step rank 1+0
2, cmd 2 step rank 2+0
3, cmd 3 step rank 3+1
4, cmd 4 step rank 3+0
5, cmd 5 step rank 4+1
6, cmd 6 step rank 4+0
7, cmd 7 step rank 5+1
8, cmd 8 step_rank 6+0
9, cmd 9 step_rank 7+0
= octave +1
[, cmd [ zoom out *0.8
\, cmd \ zoom to fit
], cmd ] zoom in *1.25
_ insert track end
cmd ` toggle step mode
cmd a select track / all
cmd b create block
cmd B create block template
cmd c copy selection
cmd C toggle collapse
cmd d delete tracks
e, cmd e transpose down degree
E, cmd E transpose down octave
cmd H splice track above
cmd i merge selection
j, cmd j insert time
J, cmd J move event forward
k, cmd k delete time
K, cmd K move event back
cmd L load
M toggle mute
cmd M toggle merge all
cmd n create view
o, cmd o join events
r, cmd r redo
R, cmd R resize to fit
S toggle solo
cmd S save
cmd t insert track
cmd T splice track below
u, cmd u undo
cmd V insert selection
cmd v paste selection
cmd W destroy block
cmd w destroy view
cmd x cut selection
y, cmd y transpose up degree
Y, cmd Y transpose up octave
cmd ~ invert step
escape toggle val edit
shift escape toggle kbd entry mode
cmd escape toggle raw edit
backspace, cmd backspace clear selected
tab toggle method edit
shift + cmd right step play tracks here
cmd right step play here
left shift selection left
shift left extend shift selection left
up rewind selection
shift up extend rewind selection
shift + cmd up, cmd up step play rewind
right shift selection right
shift right extend shift selection right
down advance selection
shift down extend advance selection
shift + cmd down step play tracks advance
cmd down step play advance
ctrl click 1, alt click 1 toggle skeleton edge
double-click 1 open block
shift drag 1, drag 1 snap drag selection
shift + cmd drag 1 extend selection
cmd drag 1 drag selection

No comments:

Post a Comment