Vocola Information Pages   by Rick Mohr (this page updated June 01, 2003)
 
 Introduction
 Using Vocola
 Language Tutorial
    Keystroke Commands
    Quotes And Whitespace
    Using Alternatives
    Defining Variables
    Substituting Actions
    Capturing Dictation
    Optional Words
    Function Calls
    Built-in Functions
    Defining Functions ->
    Contextual Commands
    Include Statements
    Comments
    Example File
 Command Sequences
 Install Vocola
 Vocola Versions
 Converting DVC Files
 Troubleshooting
 Support
 Wish List
 My RSI Story
 Voice Resources
 

Defining Functions

Function Calls

Vocola supports user-defined functions as well as built-in functions. If you find yourself copying an action sequence for use in several commands, defining a function can make the commands more concise and understandable. (This is also possible using the built-in function HeardWord, but creating your own function makes for clearer code and faster execution.)

For example, in the Netscape/Mozilla mailer it's useful to define commands to move around in the "summary" window (which shows a one-line summary of each e-mail message). Here we define the function goToSummary to make sure the summary window has the focus:

goToSummary() := 
    SetMousePosition(4, 7)        # Window's bottom left edge
    SetMousePosition(2, 15, -45)  # Bottom left of folder list
    ButtonClick()                 # Folder list now has focus
    {Tab_3};                      # Summary pane now has focus

The left side of the definition specifies the function's name (goToSummary) and arguments (none in this case). The right side of the definition is a standard Vocola action sequence. Here we position the mouse over the bottom left corner of the mailer window, move up and to the right slightly to be over the folder list panel, click the mouse so the folder list has focus, and finally press the tab key three times so the summary window has focus.

Now we can define 3 commands using this function. Saying "Final Message" moves to the last message in the summary. Saying "First Unread" moves to the first unread message. And saying for example "Summary 3 Up" moves to the summary window and up three messages:

Final Message = goToSummary() {End};
First Unread  = goToSummary() {End}n;
Summary 1..20 (Up|Down) = goToSummary() {$2_$1};

Each of these commands uses our function goToSummary, making them shorter and clearer than if each had to include that function's actions explicitly.

Defining Functions with Arguments

You can also specify arguments when defining a function. For example, here's a function which switches to the nth application on the Windows taskbar:

switchToTaskBar(number) := SendSystemKeys( {Ctrl+Esc} )
                           {Tab_2}{Right_$number}{Left} " ";

This function, switchToTaskBar, is defined to take the single argument number (indicating which taskbar slot to switch to). {Ctrl+Esc} opens the start menu (just to get focus on the taskbar), and {Tab_2} moves to the first application. Then $number (referring to the function argument) is used to move right the specified number of slots. Finally, sending a "space" keystroke makes the selected application active. (Note that this function works in Windows XP -- a slightly different version is needed for Windows 2000.)

Now we can use this function in several commands. Let's say that Microsoft Word is the third application from the left on the taskbar. Saying "Switch to 3" makes Word the active application. Saying "Close 3" closes Word. And saying "Copy to 3" copies everything from the current application and switches to Word:

<n> := 1..20;
Switch to <n> = switchToTaskBar($1);
Close     <n> = switchToTaskBar($1) {Alt+F4};
Copy to   <n> = {Ctrl+a}{Ctrl+c} switchToTaskBar($1);

Each of these commands uses the variable <n> to specify a number between 1 and 20, which is then passed to the switchToTaskBar function to specify the target application.

Multiple Arguments and Nested Function Calls

Here's another example, defining two functions which each take 2 arguments. First is the function moveBy, which moves the mouse a distance (x,y) from the current position. Note that it uses the built-in Vocola function Eval to multiply each coordinate by 15, providing more convenient units than pixels. (I have rulers taped to my screen in these units, thanks to Kim Patch's idea. With this approach you can place the mouse anywhere on a large screen by speaking only 2-digit numbers, which are recognized much more reliably than 3-digit numbers. See the file _vocola.vcl in the shipping Vocola samples for more examples.)

moveBy is used twice by the next function, moveWindowBy, which moves the current window a specified distance (x,y) in these same 15-pixel units.

moveBy(x,y) := SetMousePosition(2, Eval(15*$x), Eval(15*$y));

moveWindowBy(x,y) :=
    SetMousePosition(4,1)  # Top window edge, center
    moveBy(0,1)            # Down into title bar
    RememberPoint()        # Store initial drag point
    moveBy($x,$y)          # Move by given amount
    DragToPoint();         # Do the drag

Note again that a function's arguments may be referenced in its action sequence using "$". That's $x and $y in these functions.

Now here are two commands using moveWindowBy, allowing you to say for example "Window 10 Up"or "Window 20 Right" to move the current window:

<n> := 0..99;
Window <n> (  Up='-' |  Down='+') = moveWindowBy(0, $2$1);
Window <n> (Left='-' | Right='+') = moveWindowBy($2$1, 0);

Note here how a function argument can be built from two variables. When you say "Window 10 Up", the first variable term <n> has the value "10" and the second variable term has the value "-". These are concatenated by the double reference $2$1 to form the final function call moveWindowBy(0, -10).


This page (c) Copyright 2002-2005 by Rick Mohr.