Introduction to the Introduction
ViewRec is a Cedar tool that provides a quick and easy way to make user interfaces. It includes a procedure which puts up a viewer on a given aggregate (a record, sequence, or array). ViewRec can access aggregates through refs to records, and through names of interfaces. All of the components of the aggregate that are "simple enough" are displayed, and may be invoked (if they are procedures) or edited (if they are not). Arguments are retained from one invocation to the next, and results are displayed. The displayed values may be continuously kept up to date by a background process.
The documentation on ViewRec comes in two pieces: this introduction (ViewRecIntroduction.Tioga), and a reference manual (ViewRecDoc.Tioga). This introduction gives a quick description of the essential features of ViewRec. The reference manual gives a detailed description of everything.
Example
For an example, go to a nearby Commander and:
% bringover -p [Indigo]<PostCedar5.2>Top>ViewRec.DF
or whever the most recent version is to be found
% @ViewRec.Load
% ← ViewRec.ViewInterface[name: "Rope", otherStuff: NIL]
This will produce a viewer on the Cedar interface described in Rope.Mesa. Look at it with Tioga, and try invoking some of its procedures with ViewRec.
The Interfaces Produced
For any given aggregate, ViewRec will only concern itself with some of the components: those that are simple enough. Enumerations and numbers, and subranges of either, are simple enough. Ropes are also simple enough. An aggregate is simple enough if all of its components are simple enough. Procedures are simple enough, if all of their arguments and returns are simple enough.
The area of a viewer produced by ViewRec is divided vertically into three parts. In the first part, a rectangular area is allocated for each simple enough component. The first part may also include some rectangular areas used for other purposes. The second part is used for procedure arguments and returns, for one procedure at a time. The third part is a Tioga text viewer, used for displaying messages.
In the following discussion, components that are not procedures are referred to as variables, even though in fact they might not be allowed to vary.
Treatment of Variables:
Variables are usually displayed as name: value. The name is in a screen button (i.e. Buttons.Button). The value is usually a textual representation of the current value of the variable.
Clicking the name with the left mouse button allows edits to the variable's value. A Tioga text viewer is used to display and edit the textual representations of variable values. Editing is terminated either by keying return in the Tioga viewer, or clicking any of ViewRec's screen buttons.
ViewRec tries to obey the "What-You-See-Is-What-You-Get" rule. This cannot be maintained while a variable's value text is being edited. ViewRec signals this exception to the WYSIWYG rule by displaying the variable's name video reversed. ViewRec allows only one such exception at a time, and enforces this by disabling editing in all its other text viewers.
Some variables are not allowed to vary. ViewRec indicates this by displaying the variable's name black on a light gray background. Clicking the name will provoke a message saying that you may not edit that variable.
Treatment of Procedures:
For a simple enough procedure, ViewRec puts in the first part of its viewer a screen button, named after the procedure.
There are two kinds of procedures: immediate, and prepared. Immediate procedures take no arguments and produce no returns. Prepared procedures either take arguments or produce returns (or both). Immediate simple enough procedures are treated particularly simply: clicking the name of such a procedure invokes it. Clicking the name of a prepared procedure "prepares" to invoke the procedure.
The viewer produced by ViewRec for an aggregate with N prepared simple enough procedures has N+1 display formats: one for each of those procedures, and an initial one. Clicking the screen button for a prepared procedure puts the display in the format for that procedure. Among the formats, the first and third parts of the viewer do not differ. In the format for a particular procedure, the second part of the viewer shows arguments and return values for that procedure. The arguments are variables which may be edited, as above. Also shown is a screen button whose name is "Do Name", where "Name" is the name of the procedure. Clicking this button will fork a call to this procedure, with the arguments as shown. When the procedure returns, the return variables' value texts will be updated to show the returned values.
Programming ViewRec
ViewRec is simple to use: create, in any way you wish, an aggregate of the procedures and variables you want in your user interface, invoke a ViewRec create procedure (ViewRef, ViewInterface, or ViewTV) on it, and you have a ready-made user interface. A number of whistles and bells have evolved, but they are just secondary attachements.
The three create procedures differ only in their first argument: how the aggregate is specified. ViewRef takes a REF to an aggregate. ViewInterface takes the name of a definitions module. ViewTV is the most general; it takes an AMTypes.TypedVariable for any kind of aggregate.
Most of the rest of the arguments may be ignored; defaulting them will produce vanilla behavior. The only other arguments commonly important are viewerInit and specs.
The viewerInit argument, which is of type ViewerClasses.ViewerRec, is used to pass parameters common among procedures that create viewers. This follows a convention observed througout Cedar: the same type of record used to represent viewers is used to parameterize their creation. Each of the fields of that record type has a default value. Many clients need override the defaults on only a few of the fields; name, parent, wx, wy, and ww (wh is ignored by the ViewRec create procs) are the most likely.
It is sometimes desirable to parameterize some of the procedures in a user interface with something not explicitly seen by the user. For instance, a circuit simulator might have the capability to work on many circuits at once. It might choose to create a separate control panel for each circuit. It would then parameterize each of the procedures in each of the control panels with something to indicate which circuit that procedure is to operate on. These invisible parameters are supplied by BindingLists. The invocation BindAllOfATypeFromRefs[agg, NEW[Type ← value]] will traverse the type structure starting from agg, and produce a BindingList which specifies that every component whose type is Type should be set to value, and made invisible to the user. Components treated this way do not prevent the aggregates containing them from being simple enough; they are invisible in more ways than one.
The circuit simulator hypothesized above might invoke ViewRec like this:
ctlPanel ← NEW [CtlPanel ← [...]];
[] ← ViewRef[
agg: ctlPanel,
viewerInit: [name: circuitName],
specs: BindAllOfATypeFromRefs[
agg: ctlPanel,
handle: NEW [Circuit ← circuit]]];