Beautiful Code [318]
To implement this tree, we used the Visual Basic TreeView control.[§] This should be looked upon as a tree that grows from left to right. If, at any node, you click within a user-selected time interval—which is set using a Timer control—you expand the node and climb up the tree (i.e., move to the right), or, if it is a leaf node, carry out some action. If you don't click, eLocutor shifts its focus to the next sibling of the node. If the bottom is reached without a click, eLocutor starts again with the node at the top.
[§]http://www.virtualsplat.com/tips/visual-basic-treeview-control.asp.
We populated the tree such that it provides, at each level in the tree, a node called Up that, if selected, takes the highlight to its parent, one level closer to the root.
The top-level nodes are Type, Scroll, Edit (the primary editing functions), and Commands (miscellaneous). Leaf nodes in the Type subtree enter text into the typing buffer. Those in the Edit subtree delete or copy text from this buffer, while those in the Scroll buffer control the movement of text between buffers.
The intelligence of eLocutor expresses itself by dynamically repopulating the tree, so that you can relatively quickly find the next action you wish to take: it learns in several different ways from your actions, to be better able to predict in the future.
The biggest problem with binary input is navigation. If you are in the middle of typing and need to delete something at the start of the sentence, it takes a long time to wait for Up many times to get to the root, then down into Scroll to find the correct position to start deleting, then Up several times again to get to the root, then down into Edit for the deletion, then up and down again to scroll to the end, and again to return to typing. We were very relieved to find an answer to this dilemma.
30.2.2. The Long Click
From observing Professor Hawking use Equalizer, I discovered a new mode of operation: besides simply just clicking the button, he could hold down the button and release it at a strategic moment. The button, in effect, is not merely a binary input device, but actually an analog one, for it can provide a signal of varying duration. We thought long and hard about how best to use this new power we were presented with: we could now get more information out of a click than a simple bit. We could, for instance, allow the user to pick from a list of choices. A short click would now be used for the default action, while a long click opened up many other options.
Clearly, we wanted to use this newfound power for some extra choices for rapid navigation. We also were delighted with the ability to perform different operations on the text highlighted in the tree, such as to type it, copy it into the filter, etc. Without the long-click ability, we were limited to one action per leaf node, whereas now we could offer the user other choices regarding what to do with the highlighted tree node, which need not even be a leaf node.
The list of extra choices could not be too large, for that would require the user to hold down the button for relatively long periods of time. Consequently, we wanted these choices to change depending on where in the tree we were. "Type this" for instance, made no sense when we were in the Scroll subtree but was quite handy in the Speller.
What we came up with was a simple, easy-to-understand mode of operation. Clicking a node performs its default action. But if you keep the button pressed, a separate menu opens up whose options roll by one by one, from which you pick one by releasing the button when the desired choice shows up. We use this a bit like the right-click button under Microsoft Windows, to present the user context-sensitive menu choices. These typically include a jump to