Tutorial 2 for Spike2 for Windows/Mac scripts
Using a toolbar in a script
If you write scripts for Spike2 or Signal, it will not be very long before you need to use a toolbar. This article explains what they do, and describes the toolmake script that will write a skeleton toolbar script for you. The pictures are mainly from Windows, but the code works on the Macintosh too!

Why do we need the Toolbar?
Both Spike2 and Signal provide a rich interactive environment of menu options, windows and cursors, but none of this is accessible to the user while a script runs. Worse, unless you explicitly use Draw(), invalid window regions do not get repainted.
Ideally, we need to suspend a script, let Windows update any invalid screen area, let the user interact with the program (but prohibit actions that might break the script), then continue. This is exactly what the Toolbar() function does:
A simple example
If you've never tried to use the Toolbar commands, type in this script and run it:
ToolbarClear();
ToolbarSet(1,"Quit");
Toolbar("Press me",0); |
When you run it, the toolbar appears with the first argument displayed as a message. You will find that your interaction with the program is limited. Click Quit and edit the second line of the script to:
Toolbar("Press me",511); Run again and you will find that you can now use the menu commands and drag windows around. The second argument sets what the user is allowed to do.
So far, the script is not too useful, but if we add a few more lines as shown in the next example, you will find that you can still use the menus, and move windows, but now there is a function that is called whenever Windows has free time. We call this the "idle function".
var num% := 0;
func MyIdle%()
num% := num%+1;
ToolbarText(Str$(num%));
return num%<1000;
end;
ToolbarClear();
ToolbarSet(0, "", MyIdle%);
ToolbarSet(1, "Quit");
Toolbar("Press me", 511);
|
In this case, the idle function counts up to 1000 and displays the count. In a real application the idle function might look at the most recent input data and act based on it. The code in the idle function can also modify the toolbar buttons.
Toolbar command family
There are six commands in the toolbar family, and a close relative, Interact(). The command descriptions given here are simplified; see the script language documentation for full details.
The buttons in a toolbar are numbered 1 to 17 from right to left. Buttons with consecutive numbers are positioned next to each other. If one or more buttons are not present, there is a small gap, so you can use this to group related buttons. There is also a button number 0 that is never displayed. This button is associated with the idle function.
The width of a button depends on the length of the button label text. If you use many long labels your buttons may fall off the left-hand edge of the screen.
ToolbarClear({b%})
This removes a particular button (if b% is 0-17) or all buttons (if b% is omitted).
ToolbarEnable(b% {,state%})
If the state% argument is present, this function disables (state%=0) or enables (state%<l>0) the button set with b% (1-17 for a single button, or -1 for all buttons). The function returns the original state of the selected button.
ToolbarSet(b%, lb$ {,func f%()})
This procedure associates a label, lb$, and optionally a user-defined function with no arguments, f%(), with a button. Use it before Toolbar() to set the initial button state, and use it with the toolbar active to change or add buttons. If no function is given, a mouse click on the button closes the toolbar.
If a function is given, it runs on each button click and if the value returned by the function is zero or negative, the toolbar closes.
Button number 0 sets the idle function which must return a value greater than 0, or the toolbar closes immediately.
ToolbarText(msg$)
This procedure replaces any message in the toolbar, and makes the toolbar visible if it is invisible. This function can be used to give a progress report on the state of a script that takes a while to run.
ToolbarVisible({show%})
This function returns non-zero if the toolbar is visble, and can also show and hide it. If show% is present and non-zero, the toolbar is made visible. If zero and the Toolbar() function is not active, the toolbar is made invisible.
Toolbar(text$, allow% {,help})
This function displays the toolbar and waits for the user to click on a button. If button 0 has an associated function, that function is called repeatedly while no button is pressed. If no buttons are defined or enabled, or if all buttons become undefined or disabled, the toolbar is in an illegal state and an error is returned.
text$ sets the initial message displayed in the toolbar. The range of actions that the user is allowed is set by allow%. A value of 0 lets the user drag cursors in the current window and adjust the x and y axes. See the script documentation for the full range of options and a description of the help argument.
The Toolbar() function does not return until the toolbar closes. The value returned by Toolbar() depends on how the toolbar closed. If a button has a linked function and it returns 0, or there was no linked function, Toolbar() returns the button number. If the linked function returns a negative number, Toolbar() returns the negative number.
Interact()
This is a much simplified version of the toolbar. It defines up to 17 buttons, but has no linked functions or idle routine. It shares the toolbar space, and can be used from a toolbar function without disturbing the toolbar state. For example, the following is equivalent to the first toolbar example:
Interact("Press me",0,0,"Quit");
See the script documentation for more information on Interact().
The Toolmake script
Writing toolbar code is greatly simplified by the toolmake script. This script writes the skeleton of a toolbar-based application for you, and lets you test it without having to write any script languge. It is also an excellent example of toolbar use and shows how to create, change, enable and disable toolbar buttons and how to use the idle function. It also gives examples of user-defined dialogs.
When you run the script, after an initial welcome message, the main program toolbar appears (see above). The buttons have the following functions:
| Add button This opens a dialog in which you choose the button number to add (1 to 17). Only unused buttons can be selected. Once you select a button a new dialog opens: This dialog sets the button label and the name of the linked function. If you do not want a function, leave the function name blank in which case the button will close the toolbar. If you supply a function name, you can choose whether the toolbar closes or not after calling the named function. |
![]() |
Delete
If you decide you do not require a button after defining it, use the delete button and select from the list of defined buttons.
Edit
Click this button to choose a button to modify. Once you have selected a button you can edit the button settings.
| Idle
Use this button to define (or cancel) an idle function. Just type the name of the idle function or leave the name blank for no idle function. |
![]() |
Test
This button shows you how your toolbar will appear. If you have defined any idle routine, the toolbar message counts upwards from 0. You must have set at least one button to close the toolbar, otherwise you cannot test it. Click one of these buttons to end the test.
| Write code If at least one button is defined that will close the toolbar you can generate the script program that will display the toolbar you have designed. A dialog box opens in which you set what the user is allowed to do while the toolbar is active: You cannot stop the user dragging cursors, but you can stop them doing just about anything else. Once you click OK, a new window appears with the equivalent script. You cannot run this script until you have exited from the toolmake script.
Clear all
Quit |
![]() |
The Log window
The log window shows you the buttons you have defined, the names of linked functions and which buttons terminate the toolbar, for example:
# Label Function Stop 0 MyIdle MyIdle 0 1 Quit 1 2 Test me! DoTest 0 |
This window updates as you modify the list of buttons.
Toolbar tips
We have a few suggestions for budding toolbar programmers based on our experiences writing scripts:
And finally...
The Toolbar family of commands makes a useful user interface, and the toolmake script makes it quick and easy to build a script framework. However we don't yet have the universal script writing utility. Perhaps by the next newsletter...
Users of Signal and Spike2 for Windows or Macintosh will find the toolmake script in the Scripts folder, part of the installation. If you make use of user-defined dialogs, you may also wish to try the DlgMake script (in the same folder), that automates the process of building simple dialogs.
08/97