ButtonApplicationsDoc.tioga
Bier, June 13, 1991 7:21 pm PDT
Button Applications
CEDAR 7.0 —
Button Applications
Documents as User Interfaces
Eric A. Bier
© Copyright 1989 Xerox Corporation. All rights reserved.
Abstract: This package should make it possible for Cedar users to create, using the Tioga text editor and the Gargoyle illustrators, collections of buttons that perform, all with one mechanism, some of the functions currently performed by aliases, command files, CommandTool buttons, CommandTool commands, the Finch telephone directory, and the control panels of window-based applications. In addition, it is now easy to make special-purpose buttons that open a particular file, search for a particular string, remake a particular Cedar package and so forth.
The ButtonApplications package registers with EmbeddedButtons a set of routines that can be triggered by clicking the mouse over document objects (e.g., Tioga text strings or Gargoyle shapes). The ButtonApplications command recursively installs all of the software needed to make buttons work (i.e., the ButtonClasses and EmbeddedButtons packages). To get started using buttons, follow the installation instructions below. Then read and use ButtonIdeas.tioga. Currently implemented applications include Tioga macros, Gargoyle macros, sending messages to the MessageWindow, and a Buttonizer application that can be used to make more buttons.
Created by: Bier, Goodisman, Wyatt, and Pier
Maintained by: Eric Bier <Bier.pa>
Keywords: EmbeddedButtons, embedded buttons, applications, Tioga, Gargoyle, user interfaces, documents
XEROX  Xerox Corporation
   Palo Alto Research Center
   3333 Coyote Hill Road
   Palo Alto, California 94304

0. Caution
ButtonApplications is in flux. While the syntax for popup buttons is largely stable, the syntax for guarded, multi-state and radio buttons is still changing. As a result, some buttons made during this period may cease to work in the future.
Also, there are a number of known bugs and shortcomings. See "Bugs and Shortcomings" below.
1. Introduction
ButtonApplications is the user layer of the EmbeddedButtons architecture, which includes the EmbeddedButtons, ButtonClasses and ButtonApplications packages (and relies on TiogaActive.df and Gargoyle.df). If you wish to use buttons in Tioga documents and Gargoyle pictures, do the following:
In Portable Cedar (PCedar)
Type to a Commander:
ButtonApplications
Learning more about Embedded Buttons
The best way to learn more about buttons is to play with them. Open this file (or press it as a button, see next paragraph):
[PCedar2.0]<Documentation>ButtonIdeas.tioga
ButtonIdeas.tioga explains most of what you will need to know to use, copy, and create buttons. (The filename above is a button. After running the ButtonApplications command, open a fresh copy of this file (ButtonApplicationsDoc.tioga), click on the

button that appears at the top right of the Tioga menu, and click on the file name.)
Once you have read ButtonIdeas.tioga, you may wish to come back to this document for more details on customizing your own buttons.
To add your own applications to the EmbeddedButtons architecture, you will need to use the interfaces provided in EmbeddedButtons-Source.df. See EmbeddedButtonsDoc.tioga for more information.
2. Customizing Buttons
Currently, any Tioga string and any Gargoyle slice can be a button. If a Tioga character string is part of a button, it will have "ButtonData" as one of its character properties. If a Gargoyle slice is part of a button it will have "ButtonData" as one of its slice properties. The value of the ButtonData property is a string in a language called Poppy that was invented for this purpose. This section describes typical field values for the three button classes.
Expressions that are surrounded by parentheses () are made into a list and passed to an editor or application depending on where they occur. Expressions that are surrounded by angle brackets <> are evaluated in a LISP fashion; the first element of the list is interpreted as the name of a registered procedure, the rest of the elements are passed to it as arguments. A list of the current registered procedures is given in section 4.
2.1 Pop-Up Buttons
An embedded pop-up button works just like the familar pop-up buttons of PopUpButtons.df, except that they are trigerred by normal document objects. Here is an example of a ButtonData for a pop-up button and an example pop-up button:
Poppy1
Class: PopUpButton
MessageHandler: MessageWindow
Menu: (
((Event1) "First Item" "Sends Event1 to application")
((Event2) "Second Item" "Sends Event2 to application")
((Event3) "Third Item" "Sends Event3 to application")
)
Feedback: (
(MouseMoved <SetCursor bullseye>)
)
Button
The first word, Poppy1, names the language, Poppy, and the latest version number. All old versions of Poppy will continue to be supported. This word is included so that, in the future, it will be possible to experiment with new button languages while our Poppy buttons continue to work.
Below, we explain each of the keywords that are supported by this button class.
Class: All buttons have a class field. Currently the only classes are GuardedButton, PopUpButton, MultiStateButton, RadioButton, TwoStateButton (which is obsolete and so should not be used), and PopUpStateButton (which is experimental and should not be used yet).
MessageHandler: This is the name of the application that will receive events when this button is pressed. The message handler in this example, MessageWindow, simply prints out the tokens that it receives in the Cedar MessageWindow. It is useful for debugging buttons.
Menu: This field is only relevant to the PopUpButton and PopUpStateButton classes. It is a list of menu entries, where each menu entry is a list of three elements. The first element of an entry, such as (Event1) in our example, is a list of tokens that will be sent to the application named in the MessageHandler field. The second element, e.g., "Second Item" in our example, is the string that will be displayed when this button's pop-up menu appears. The latest item is the documentation string that will appear when the user moves the mouse over this pop-up menu entry.
Feedback: Any buttons can have a Feedback field. This field is a list of button-event/action pairs. In our example, MouseMoved is the event and <SetCursor bullseye> is the action. The cursor will be set to a bullseye pattern whenever the mouse moves. The result of evaluating an action is sent to the editor in which the button is embedded. In our example, <SetCursor bullseye> returns NIL, so the document containing the button is unchanged.
2.2 Multi-State Buttons
A multi-state button has a value, called Value. In our example, Value may be TRUE or FALSE. These buttons can be used for check-boxes or for application values that toggle on and off or cycle through a small set of possibilities. Here is an example of a ButtonData for a multi-state button in a Tioga document and an example button:
Poppy1
Class: MultiStateButton
Name: George
Variables: (Value: BOOL = TRUE)
Feedback: (
((Control Left Down) (BeginButton ClearLooks 2 ApplyLook EndButton))
((Value TRUE) (BeginButton ClearLooks 1 ApplyLook EndButton))
((Value FALSE) (BeginButton ClearLooks EndButton))
(MouseMoved <SetCursor bullseye>)
)
Button
The Poppy1, Class, and MessageHandler fields should now be familiar.
Variables: This field describes the local variables of this button separated by semi-colons. The variable named Value is special. This variable is considered to be the value of this button, when an application asks for the value of the button.
Name: When an application asks for the value of a button, it refers to the button by name. The name of this button is George. All multi-state buttons that have the same name will try to have the same value. Therefore, it is important to give each independent button a distinct name. If no Name field is provided, EmbeddedButtons will make up a unique name, so unnamed buttons are always distinct from each other. Poppy variables are typed. The type can either be a BOOL, INTEGER, or an enumerated type, such as {apple, orange, banana}. Variables can be initialized after an = sign as shown.
Feedback: This Feedback field shows a variety of button-event/action pairs. If the left mouse button goes down over this button, while Control is down, Tioga will be told to (StartButton ClearLooks 2 ApplyLook EndButton). BeginButton selects the button. ClearLooks 2 ApplyLook makes the button look c (comment italics). EndButton restores the original selection. If the value of this button changes to TRUE, Tioga will make the button look bold (BeginButton ClearLooks 1 ApplyLook EndButton). If FALSE, Tioga will clear button looks. If the cursor moves over this button, the cursor pattern will be set to bullseye.
2.3 Radio Buttons
Each radio button is a member of a group of buttons, only one of which can be one at a time. The Name: field is the name of the group. The RadioButtonValue: field is the value represented by this particular radio button. Here is an example of a pair of radio buttons that might be embedded in a Gargoyle illustration:
ButtonData Poppy1
Class: RadioButton
MessageHandler: DrawShapes
Name: Shape
RadioButtonValue: Rectangle
Feedback: (
((MouseMoved MouseEntered) <SetCursor bullseye>)
((State TRUE) ((BeginButton) (LineWidth 5.0) (DashesOff) (EndButton)))
((State FALSE) ((BeginButton) (LineWidth 2.0) (DashesOff) (EndButton)))
(Down ((BeginButton) (DashesFromSelection "[3 5]") (EndButton)))
(Up ((BeginButton) (DashesOff) (EndButton)))
)
ButtonData Poppy1
Class: RadioButton
MessageHandler: DrawShapes
Name: Shape
RadioButtonValue: Circle
Feedback: (
((MouseMoved MouseEntered) <SetCursor bullseye>)
((State TRUE) ((BeginButton) (LineWidth 5.0) (DashesOff) (EndButton)))
((State FALSE) ((BeginButton) (LineWidth 2.0) (DashesOff) (EndButton)))
(Down ((BeginButton) (DashesFromSelection "[3 5]") (EndButton)))
(Up ((BeginButton) (DashesOff) (EndButton)))
)
The Class: and MessageHandler: fields should be familar.
Name: For radio buttons, the Name: field is the name of the group of radio buttons, not of this particular button.
RadioButtonValue: The current value of a group of radio buttons is the RadioButtonValue of the unique button in that group whose State is TRUE. Thus, all of the RadioButtonValues put together determine an enumerated type that the radio buttons can choose from. In this example, the enumerated type defined by the two buttons is {Rectangle, Circle}.
Feedback: Feedback fields are independent of button class. This feedback field is for a pair of radio buttons embedded in a Gargoyle picture. Each button displays itself dashed when it is depressed, and makes its line width thicker when it is turned on.
3. The Current Message Handlers
Currently, there are five names that may appear in the MessageHandler field of a ButtonData: Tioga, CommandTool, MessageWindow, Typescript, and Buttonizer. Here is what these applications do.
Tioga
MessageHandler: Tioga
The Tioga message handler interprets its argument as a set of Tioga macro commands (like the ones printed in the Operations: field of the Tioga EditTool when the GetLast key is pressed. The commands are applied to the current selection. See the Tioga Macros section of ButtonIdeas.tioga for examples.
The special Tioga operation BeginButton saves the Tioga selection and selects the button that is being pressed. The EndButton operation restores the Tioga selection.
Example Message: (BeginButton ClearLooks 1 ApplyLook EndButton)
CommandTool
Any command that you can type to a CommandTool can be executed from a button by putting it in quotes.
Example Message: "fork cdv Commands; ls *Button*.df"
List Button DFs.
Message Window
Sends its input to the MessageWindow.
Example Message: "One Potato, Two Potato, Three Potato, Four"
To MessageWindow.
Typescript
Sends its input to the EmbeddedButtons Typescript.
Example Message: "One Potato, Two Potato, Three Potato, Four"
To Typescript.
Buttonizer
A button that sends messages to the Buttonzier should have both a ButtonData property (describing itself) and a ButtonDataLiteral property (describing the buttons it will make). Buttonizer takes one argument that can be either Selected or Root. If the argument is Selected, the selected text becomes a button. Otherwise, the root of the document gets the button property making all parts of the document into buttons (not yet implemented).
Make-PopUpButton turns the selected text into a simple three-entry PopUpButton.
4. The Current Feedback Events
The Feedback: field of each ButtonData is a list of button event/action pairs. Some button events are excepted regardless of the class of button. Other events are button-dependent.
Events that Work for All Button Classes
Unless they are ignored on purpose by a button class, these events should be understood by all buttons:
[Control], [Shift], [Left, Middle, Right (or Red, Yellow, Blue)] Up or Down
Actions such as (Left Down) mean that the left mouse button has gone down. The mouse button name can be left out if the action applies to all mouse buttons. Hence, it is allowed to just say Down.
(Control Left Down) means that the left mouse button has gone down while the CTRL key is held down.
Button
Special Multi-State Button Events
(Value TRUE), (Value banana), ...
This clause means that the local variable named Value has acquired the new value named as the second element of the list.
Special Radio Button Events
(State TRUE), (State FALSE)
Individual radio buttons are either TRUE or FALSE. This value is stored in a local variable called State. This clause means that variable State has acquired the new value named as the second element of the list.
5. The Current Registered Poppy Procedures
SetCursor <cursor name>
The SetCursor command sets the cursor shape to the shape named by its argument and returns NIL. This routine is a currently a kludge, since Viewers continually sets the cursor based on the class of the viewer that the cursor is in, so the cursor shape flickers.
Example: <SetCursor bullseye>
The names of the cursor shapes can be found in [Cedar7.0]<Viewers>ViewerClasses.mesa under CursorType.
ButtonText
The ButtonText routine returns the textual contents of the button that is being pressed. This currently only makes sense for buttons embedded in Tioga documents
Example: <ButtonText>
Select
Takes as its arguments a value, v, and a list of value/result pairs. If v matches the value in one of the value/result pairs, then the result part of the pair is returned.
Example: <Select <GetValue> TRUE 5 FALSE 7.3>
In a boolean-valued button whose current value was TRUE, this statement would return 5.
AsText [<value>]
If no argument is given, returns the current value of the pressed button and converts that value into a text string. Otherwise, converts its argument to a text string. This routine can handle booleans, integers, real numbers, atoms, and text strings.
Examples: <AsText> or <AsText <GetValue Fruit>> or <AsText 3.0>
GetValue [<button name>] [<variable name>]
If no argument is given or the argument "Self", returns the current value of the pressed button. If one argument is given, treats the argument as a button name and gets the value associated with that name (in the document of the pressed button). If two arguments are given, the second argument is interpreted as the name of a local variable in the button named by the first argument, and the value of that variable is returned (if this value is not unique, picks the value of one such button). Values are REFs such as, ATOM, ROPE, REF INT, REF BOOL, and REF REAL.
Examples: <GetValue>, <GetValue Fruit> or <GetValue Self ThisVar>
SetValue [<button name>] [<variable name>] <value>
If two arguments are given, sets the current value of the pressed button to the given value. If three arguments are given, sets the named variable of the named button to the given value. The arguments must be given in order.
Examples: <SetValue TRUE>, <SetValue Fruit orange> or <SetValue Animal HasTail TRUE>
6. Bugs and Shortcomings
Multi-state buttons and radio buttons don't always change state properly when you click on them. For now, try clicking them again, more slowly.
The first time you click on a named multi-state or radio button in a large document, it takes a while to change state. EmbeddedButtons is reading through all of the buttons in the document, looking for buttons with the same name. Subsequent clicks go faster because the buttons have already been partially parsed.
The Poppy language is rather too case-sensitive.
Poppy needs a lot of operations, like arithmetic and logical operations that are not yet provided.
When a button in Tioga is copied, is ButtonData data structure is copied verbatim, making two buttons that share the same data structure. For now, if this causes unexpected behavior, save the file and reset it. The buttons will now have distinct data structures.
When two buttons have the same name, they update their values in parallel. This can come in handy, but it would be nice if EmbeddedButtons warned you when name conflicts occurred.
An expressions in parentheses, (A), when at top level, should be an abbreviation for the call <Send Editor A> or <Send Application A> depending on where the expression occurs. This semantics is not fully implemented.
CTRL-L does not work in all Tioga viewers to turn on button activity. It appears not to work in Walnut and BlackWalnut viewers. As a workaround to make these viewers active, make a selection in the viewer and use the Activity button in the Tioga Macros section of ButtonIdeas.tioga.
7. Button Commands
ButtonOpen <df file name>
Examples:
ButtonOpen Gargoyle-Suite.df
ButtonOpen /pcedar/top/Tioga-Suite.df
Creates a Viewer containing the file names and directories from the named DF file. Each file name becomes a button (a TiogaButton). Clicking with the left mouse button opens the named file in the local directory (the one in which the ButtonOpen command was given). Clicking with the right mouse button opens the named file in the directory named by the DF file.
DF files that are Include'd or Import'ed in another DF file also have next to them the symbol []. Clicking on this symbol will ButtonOpen the DF file instead of opening it normally.
Known bug: files in sub-directories (e.g. sun4/ or sun4-o3/) don't display.
bop <package name>
Examples:
bop TIP
bop ButtonApplications
Bop is short for ButtonOpen from PCedar top. It is defined as
ButtonOpen /pcedar/top/$1-Suite.df
When you use bop, you will probably need to right-click on filenames (as they are probably not defined in the working directory).
bops <package name>
Examples:
bops TIP
bops ButtonApplications
Bops is short for ButtonOpen from PCedar top Source files. It is defined as
ButtonOpen /pcedar/top/$1-Source.df
When you use bops, you will probably need to right-click on filenames (as they are probably not defined in the working directory).