Display Classes for Buttons
                         

1. The Action Display Class

	1a. Actions

		1a(i). Callbacks; Screen Position

			Attributes:	atsector
					preset
					set
					x
					y
					yx

		1a(ii). Other Actions

			Attributes:	f1, ..., f12
					fkeys
					selected

	1b. Appearance

		1b(i). Arrangement of the Buttons

			Attributes:	geometry
					verify

		1b(ii). Size

			Attributes:	C
					R
				       	xs
					ys
					yxs

		1b(iii). Displayed Characters

			Attributes:	justify
					label
					labelfont
					shelltitle
					title
					titlefont

		1b(iv). Color

			Attributes:	bg
					fg
					labelfg
					titlefg

	1c. Additional Windows

		1c(i). Kinds of Windows

			Attributes:  	iconic
					ws
			Variable:	s.WS

		1c(ii). Visibility

			Attributes:	followers
					followertree
					hide
					icon
					icontitle
					lower
					raise
					show

		1c(iii). Selection

			Mouse Pointer
			Keys:		Arrow keys
					Ctl-Shift-Tab
					Ctl-Tab
					Enter
					Shift-Tab
					Tab

	1d. More about Appearance

		1d(i). Changes in Appearance

			Attributes:	hl
					hlthickness
					shadowthickness

		1d(ii). Other Features

			Attributes:	exit
					foot
					head
					is
					leftfoot
					pin
                                        resizeable
					rightfoot

	1e. Status and its Preservation

		1e(i). Status

			Attributes:	bound
					class
					stateself
					settings

		1e(ii). Saving

			Attribute:	script
			Variable	s.WM_SAVE_YOURSELF

2. The Button Display Class

			Attributes:	margins
					naturalsize

3. The Check Display Class

4. The Radio Display Class

---------------------------------------------------


1. The Action Display Class


An object of the action display class is shown as a set of buttons.  Each
button can trigger some action when it is pressed -- i.e., when the left mouse
button is clicked while the pointer is on the button.  Only slotfiller
variables can be bound to this class.  The display has one button for each of
the slotfiller's symbolic indices, and these indices are used to label the
buttons by default.  The slotfiller's values do not appear in the display.

A simple example with an immediately obvious action is an object that moves
around the screen when its buttons are pressed.  First, label the buttons and
specify movements by creating the slotfiller:

     ac(`up `down `left `right;(100 0;100 0;0 100;0 100))

The numbers will be used as increments, in pixels, to the vertical and
horizontal positions.  Now, after loading the s context, use the is function

to bind ac to the action display class and then the show function to display
the object on the screen.  The is function is dyadic.  It takes the variable
name, in symbol form, as left argument, and the display class name, which is
always in symbol form, as right argument.  The show functions is monadic,
taking a variable name, in symbol form, as argument; it returns Null.  Since
is, in addition to displaying some messages, returns its left argument as an
explicit result, you can combine these two operations:

     $load s
     scrs.SCREEN-34 12
     br{w;m}:{w has (`yx;scr-m+`yxs of w);}
     show `ac is `action; br{`ac;0}

You should see an action object on the screen.  Click the left mouse button
while the pointer is on the object's "up" button.  You get a pretty animation
but no action, because no callback has been set on ac.


1a. Actions

1a(i). Callbacks; Screen Position

	Attributes:	atsector
			preset
			set
			x
			y
			yx

Suppose v is the unqualified name of a slotfiller variable bound to the action
display class and c is its context, both in symbol form.  Then whenever a
button is pressed, s makes the reassignment (pc%v)pc%v, where p is the
symbolic index corresponding to the button that was pressed.  These
assignments, since they involve the slotfiller's values, enable those values
to be used to select actions.

You write a function of the form f{s;d;i;p;c;v} that incorporates the actions
you want, and you set the callback f on cv in order to have them triggered.
In the callback, s is the static data (if any) you specified when you set the
callback and d (the data) is the value to which p is the path; you can use any
of them to determine an action.  The index i is null.

Since we will move ac around the screen as an example of the actions that can
be triggered by an object of this class, we first discuss attributes used to
position objects.

The "x" and "y" attributes specify the horizontal and vertical distances in
pixels between the top left corner of an object and the top left corner of
either the object that contains it (a layout, for example) or, for top-level
objects, the screen.  For a top-level object, the default value for each is
zero.

The of function is used to query attributes.  It takes a scalar or vector left
argument of attributes, which are always in symbol form, and a variable name,
in symbol form, as right argument.  In its result, it encloses the value for
each element of the left argument:

     `y`x of `ac

The value of the "yx" attribute is simply the vector composed of the y and x
attribute values.  The has function sets attributes.  It takes a variable
name, in symbol form, as left argument, and as right argument an association
list or slotfiller containing attribute names and values.  It returns its left
argument as explicit result.  Change x and see the new position and the new
attribute value:

     `ac has (`y;0; `x;300)
     `yx of `ac

As stated above, a value selected from ac by a button press is available to a
callback function, as its second argument.  The of function encloses attribute
values in its result, so Disclose or Raze must be used to obtain the attribute
values themselves.  Define a callback function to adjust the yx attribute by
the value selected from ac by the button press, limiting the movement so as to
stay well on any screen.  Then set the callback on ac:

     acbfn{s;d;i;p;c;v}:cv has (`yx;0600(`yx of cv)+d)
     `ac _scb (acbfn;'Just to illustrate')

Two alternative methods of setting the callback use the "set" attribute:

     `ac has (`set;acbfn)
     `ac has (`set;(acbfn;'Just to illustrate'))

If the former is used, the Null will be passed to acbfn as its first
argument; if the latter, 'Just to illustrate' will be passed.

No matter how the callback is imposed, by set or _scb, the value of the set
attribute is the name of the function and the static data (the Null, if no
static data was specified):

     `set of `ac

Having entered these statements in an A+ session, you can move the action
object around the screen, within the prescribed limits, by pressing its
buttons.  Try it.

There is a "preset" attribute that is similar to set.  It can be used to set
and query preset callbacks, functions that are called just before a value is
changed, rather than just after.  Execute

     pc{s;d;i;p;c;v}:{"Jump!";d}
     `ac has (`preset;pc)

Now move the object around the screen.  "Jump!" should appear in the session
log, showing that pc is being called.

To get rid of this preset callback, use a null function specification.  (Null
for set would likewise eliminate an ordinary callback.)  Enter

     `ac has (`preset;)

Since we have been discussing positioning, we might as well consider the
"atsector" attribute now.  It is used to move objects around the virtual
desktop and to determine where they are.  A position on the desktop is
specified by a vector of two indices.  The following three lines should move
ac to sector 1 1 and back.  (If you are already in sector 1 1, change the 1 1
to 0 0 in the second statement.).  Suppose you are in sector 1 0 (the
semicolon in the first line causes the result to be displayed -- see immediate
execution display of expression groups in the A+ Reference Manual):

     ;sector`atsector of `ac
     `ac has (`atsector;1 1)
     `ac has (`atsector;sector)

If your virtual-desktop window is visible, you can watch ac move around on it
as you change the value of the atsector attribute.

1a(ii). Other Actions

	Attributes:	f1, ..., f12
			fkeys
			selected

Whenever a button is pressed, the "selected" attribute is set to the symbolic
index corresponding to that button.  Press the "down" button; then:

     `selected of `ac

You can also set selected to any of the symbolic indices using an A+
statement.  Setting it does not cause a callback and an assignment of an
illicit value is simply ignored.  The domain of the selected attribute depends
upon the display class: for an object bound to the array class, for instance,
its value is an integer vector consisting of a row and a column index,
initially 1 1 to indicate no selection.

For any object, you can associate an action with a function key.  As an
example, define an action similar to the ones we have associated with the
buttons of ac:

     diag{x}:x has (`yx;600(|@0)100+`yx of x)

For any one of the twelve function keys, the key can be connected with a
function and an argument by a statement such as the following, which uses an
association list to specify several attributes at once.  A slotfiller can be
used instead of an association list, as you will see later.

     `ac has (`f1;(diag;`ac);`yx;0 0)

Now press the F1 key while the mouse pointer is in the ac display and you will
see the display move diagonally, with jumps to avoid getting too far.

These twelve connections are listed in the "fkeys" attribute, which is for
reference only; it cannot be set.  Its value is a slotfiller such that the
first two of the following three expressions give the same result for each of
f1, f2, ... f12.  (Recall that we must Disclose or Raze the of result to
obtain the attribute value.)

     `f1 of `ac
     `f1`fkeys of `ac
     `fkeys of `ac

You may have to move to the Emacs A+ area to page up and see all of the result
of the last statement.  Then press End and move to the tutorial area.


1b. Appearance

1b(i). Arrangement of the Buttons

	Attributes:	geometry
			verify

The default arrangement of the buttons on the screen is vertical, but you can
use the "geometry" attribute to alter it.  Try these arrangements:

     `ac has (`geometry;2);          br{`ac;0}
     `ac has (`geometry;1);          br{`ac;0}
     `ac has (`geometry;`horizontal); br{`ac;0}
     `ac has (`geometry;`vertical);   br{`ac;0}
     `ac has (`geometry;2 2);         br{`ac;0}
     `ac has (`geometry;1 1 1 1);     br{`ac;0}
     `ac has (`geometry;2);           br{`ac;0}
     `ac has (`geometry;1 1 2);       br{`ac;0}

-2 is a conventional value for horizontal arrangement, and -1 for vertical.
Non-negative numbers indicate how many buttons there are to be in each row and
are used repeatedly if necessary.

Fancier arrangements are possible using a matrix value for geometry.  The
matrix partitions the action display.  Symbolic indices of the slotfiller
indicate the arrangement, with a null symbol signifying an empty section.
Alternatively, integers can be used: they must be indices of the symbolic
indices in the slotfiller, or -1 signifying an empty section.  The order of
the buttons need not correspond to the order in the slotfiller variable.
Omissions and repetitions are allowed, but the repetitions for any given
symbolic or numeric index must form a submatrix.  In the following examples,
commas and parentheses are used only to make the examples immediately
obvious.  The first statement avoids all overlap of vertical and
horizontal buttons, the second one omits the "right" button, and the
third one provides partial overlap:

     `ac has (`geometry;3 3(` `up `),(` `down `),(`left ` `right)); br{`ac;0}
     `ac has (`geometry;3 3(` `up `),(` `down `),(`left ` `)); br{`ac;0}
     `ac has (`geometry;3 4(1 0 0 1),(1 1 1 1),(2 2 3 3)); br{`ac;0}

The geometry attribute, like set and unlike f1, is persistent.  The  free
function takes a variable name, in symbol form, as its only argument and,
besides displaying a message, returns its argument as an explicit result:

     free `ac
     show `ac is `action; br{`ac;0}

The buttons are arranged as they were before and they still function as they
did, but if you put the pointer in the ac display and press the F1 function
key nothing happens.

You can also change the order of the buttons by respecifying the underlying
variable, unless geometry contains symbolic indices.  When you respecify the
value of a variable that is bound to a display class, you might inadvertently
try to change it to a value that is not allowed for that class.  The
assignment is refused, either tersely by the interpreter, when the "verify"
attribute is 0:

     `verify of `ac
     `ac has (`verify;0)
     ac'No good!'

or with an explanation by s, when the verify attribute is 1, the default:

     
     `ac has (`verify;1)
     ac'No good!'

(The "a action" in the response is presumably for faster execution.)  Be sure
to clear the suspension:

     

1b(ii). Size

	Attributes:	C
			R
			xs
			ys
			yxs

Corresponding to the position attributes there are size attributes: "ys" is
the vertical size of the object, in pixels, and "xs" is the horizontal size.
The value of "yxs" is the concatenation of the values of ys and xs.  Try these
statements:

     `ys`xs of `ac
     ;size`yxs of `ac
     `ac has (`yxs;2size); br{`ac;0}
     `ac has (`yxs;size);   br{`ac;0}

You may have noticed the asymmetry of the ac display, caused by the unequal
lengths of the labels.  When the "C" attribute is 1, the columns are required
to be of equal width; the default for C is 0.  Watch the display of ac become
symmetric when you change C to 1:

     `C of `ac
     `ac has (`C;1); br{`ac;0}

There is a similar attribute "R", also with default 0, that requires the rows
to be of equal height when it is 1.  Here is an example showing its use.
First, load some auxiliary variables that are in a separate file to avoid
cluttering the tutorial; they will all have the prefix ld_ so you will know
where they came from.

     _load{'/usr/local/aplus-fsf-4.18/doc/tutorials/s.tutorials/aux_vars.+'};
     a(`a`b`c`d`e`f`g`h`i`j`k`l`m;(;;;;;;;;;;;;))
     lb('Exit';'Refresh';'Corporate Axes'),ld_nlb
     `a has (`class`shelltitle`title`label;(`action;'nexus';'';lb));

Note the use of a slotfiller to specify several attributes at once.  The
shelltitle, title, and label attributes are discussed in the next section, and
class in a later section.

     g` ` `a`a `b`b ` ` ` `,(20`),5ҡ`c`d`e`f`g`h`i`j`k`l`m`
     `a has (`C;1; `geometry;9 10g; `show;1; `xs;600); br{`a;0}

The two empty rows take no space now.  Setting R to 1 provides the vertical
separation implied by the geometry:

     `a has (`R;1; `xs;600); br{`a;0}

     _ex `sector `size `lb `g, free `a

1b(iii). Displayed Characters

	Attributes:	justify
			label
			labelfont
			shelltitle
			title
			titlefont

The "A+" appearing at the top of the ac display is the default value for the
"shelltitle" attribute for a top-level object.  To change it, change the value
of the shelltitle attribute:

     `ac has (`shelltitle;'Move')

The "ac" below the shelltitle is the default value of the "title" attribute.
To change it:

     `ac has (`title;'')
     `ac has (`title;' ')
     `ac has (`title;'Direction')

Notice that an empty vector means no title area at all.

The symbolic index names appearing on the buttons are, again, the default.
They appear when the "label" attribute is null.  The label attribute governs
what is shown in the label areas.  (When there are also value areas, as in the
slot class, it has no effect on them.)  If its value is a character vector or
a single symbol, the same label appears on all buttons:

     `ac has (`label;'Push')
     `ac has (`label;'')

The buttons can be separately labeled using either a vector of symbols or a
nested vector of scalars or vectors:

     `ac has (`label;`u`d`l`r)
     `ac has (`label;('';'';'';''))

The label attribute is functional, the function being called once for each
button with the path as an argument:

     f{s;d;i;p;c;v}:p(`left`right`up`down;('l';'r';'u';'d'))
     `ac has (`label;f)

The fonts need not be the default, kaplgallant-19.  Try the "titlefont" and
"labelfont" attributes:

     `ac has (`titlefont;'times-19'); br{`ac;0}
     `ac has (`labelfont;'helvetica-boldoblique-19')

The labels are centered in both directions within the buttons, by default.
The "justify" attribute is used to modify their positions.  Essentially, its
argument is one of 'l' 'r' 't' 'b' 'lt' 'lb' 'rt' 'rb' `left `right `top
`bottom, and it is cumulative (the first statement below produces no visible
effect, since there is no extra vertical space):

     `ac has (`justify;`bottom)
     `ac has (`justify;`left)
     `justify of `ac
     `ac has (`justify;'r')
     `justify of `ac

In the character form, a period at the beginning of the argument makes it
non-cumulative:

     `ac has (`justify;'.rt')
     `justify of `ac

A .t or .b argument centers the labels horizontally, .r or .l vertically.  To
restore the positions to centered both ways, set justify to null:

     `ac has (`justify;)

1b(iv). Color

	Attributes:	bg
			fg
			labelfg
			titlefg

There are four attributes that govern the colors in the display.  The default
values are:

     `titlefg `labelfg `fg `bg of `ac

The foreground attributes, "...fg", refer to text and the "bg" to background.
In our example there is no text corresponding to the "fg" attribute.  In a
member of the array display class it would be the array values (see the Data
tutorial); in the slot class it would be the contents of the value areas; and
so on.  These attributes can be set to whatever colors you want, as in:

     `ac has (`titlefg;`blue);
     `ac has (`labelfg;`green);

Vectors of colors can also be used for the labels.  The colors are used
cyclically:

     `ac has (`labelfg;`blue`brown`green`red);
     `ac has (`labelfg;`blue `red);
     `ac has (`fg;`pink);
     `ac has (`bg;`yellow);

The default colors can be restored by giving null values:

     `ac has (`titlefg `labelfg `fg `bg;(;;;));


1c. Additional Windows

1c(i). Kinds of Windows

	Attributes: 	iconic
			ws
	Variable:	s.WS

A+ can, of course, display more than one window at a time.  Produce
three more windows, without stopping to make their buttons work.
Notice that they all appear originally in the top left corner, the
default position:

     b(`run `stop `cancel;(;;))
     c(`yes `no `more;(;;))
     d(`load `save;(;))
     show `b`c`d is `action
     br{`b;0 600}; br{`c;0 400}; br{`d;0 200}

You might want each of them to be sized according to its labels, the
default.  Suppose, however, that you want them to be all the same
size.  Enlarge the smaller ones:

     `c`d has <(`yxs;>`yxs of `b);br{`d;0 200}

Incidentally, the vertical justification that you took on faith can now be
demonstrated:

     `d has (`justify;`bottom);
     `d has (`justify;);

The new windows are popups, as can be seen by their having pins rather than
buttons at the top left.  (See the s-Context Variables tutorial for a way of
changing this default.)  It is possible to change them from popups and back
again, using the "iconic" attribute, which controls this property:

     `d has (`iconic;1);
     `d has (`iconic;0);

The s-context variable s.WS contains the name of the "screen workspace", which
is always a top-level object, not a popup.  (The significance of the screen
workspace is discussed in the next section.)  The default value of s.WS,
before any objects are shown, is the Null.  When an object is initially shown
and s.WS is null, that object becomes the screen workspace unless you prevent
it.

When an object is first shown, it is prevented from becoming the screen
workspace if the value of its "ws" attribute is 1, and not prevented if ws is
0.

If you change the value of s.WS, you name a new screen workspace and you
"demote" the old one to a popup:

     `d has (`shelltitle;`Popup);
     s.WS`d
     s.WS`ac
     `ac has (`shelltitle;`Move);

Notice that the value of the shelltitle is treated as related to the screen
workspace: when the screen workspace was changed, the ac display was given its
variable name as a shelltitle and d was given "A+", the default shelltitle,
and the reverse happened when the screen workspace was changed back.  The
shelltitles that had been set were lost in the process.

1c(ii). Visibility

	Attributes:	followers
			followertree
			hide
			icon
			icontitle
			lower
			raise
			show

The "hide" attribute for a pop-up window, when specified by any value other
than 0, removes it entirely from the screen.  The "show" attribute, when
specified by any value other than 0, restores the display of the window.  It
can also create the original display of a window sometimes, i.e., be used in
place of the show function, as we will soon see.  When queried, one of these
attributes is always 1 and the other 0, corresponding to the visibility of the
window:

     `d has (`hide;);
     `hide`show of `d
     `d has (`show;);
     `hide`show of `d

The hide attribute for a top-level window, when specified by any value other
than 0, changes it to an icon, generally at a different location.  Change d to
top-level and hide it, then change it to be non-iconic and see the icon
disappear:

     `d has (`iconic;1);
     `d has (`hide;);
     `d has (`iconic;0);
     `d has `show;

Note the last form: a value need not be given for an action attribute: the
value is assumed to be 1 or, what is equivalent, null.  Now keep an eye on all
the objects:

     `ac has `hide;
     `ac has `show;

Notice that when ac was changed to an icon, the other three windows vanished.
The reason is that they are "followers" of the screen workspace, as indicated
by the attribute of that name:

     `followers of `ac

Suppose that you use the followers attribute to make d a follower of c.  The
new arrangement is reflected in the reference-only attribute "followertree",
whose value is a recursive slotfiller.  Then when c is hidden, d will be
hidden also.  Although d is no longer a follower of ac, it will still follow
it into hiding because it is a follower of a follower of ac:

     `c has (`followers;`d);
     `followertree of `ac
     `c has `hide;
     `hide of `d
     `c has `show;
     `ac has `hide;

You can change the icon image and title, using the "icon" and "icontitle"
attributes.  The value for the icon attribute must be an m by n bit matrix,
with m and n each at most 64:

     `ac has (`icontitle;'Buttons');
     `ac has (`icon;64 641 0 0 0 0);
     `ac has `show;

The other way to change visibility is to put one window in front or in back of
another, i.e., have one window obscure another.  To put one in front, set its
"raise" attribute to anything; to put it in back, set its "lower" attribute to
anything.  Note that lowering a window places it in back of everything,
including the emacs session window, and that the followers attribute is for
hiding, not lowering or freeing:

     `d has (`lower;);
     `d has `raise;
     `ac has `lower;
     `ac has (`raise;0);
     `raise of `ac

Unlike hide and show, raise and lower are pure action attributes: even setting
them to 0 causes their normal actions, and no value can be shown for them; the
of function disavows them.  Now make d a follower of ac again:

     `d has (`leader;`ac);

1c(iii). Selection

	Mouse Pointer
	Keys:		Arrows
			Ctl-Shift-Tab
			Ctl-Tab
			Enter
		       	Shift-Tab
			Tab

You have already seen that when the f1 attribute is given a non-null value for
some object, the mouse pointer must be in the object's window in order for the
F1 function key to trigger the specified action.  This property of the keys'
applying to a particular window is called "keyboard focus".  It is signalled
by a brightening of the window's border.  You can give keyboard focus to any
window that is at least partially visible just by moving the pointer into any
visible part of it.

When one s window has focus, you can move the focus to another by pressing
Control-Tab or Control-Shift-Tab.  Move the mouse pointer into one of the s
windows and press Control-Tab four times.  You will see keyboard focus and the
pointer move from one window to another.  Press Control-Shift-Tab and you will
see the keyboard focus traverse the windows in the opposite order.

Within a window, you can move the selection from one field to another by
pressing Tab or, to go in the opposite order, Shift-Tab.  Move the pointer to
the ac window and press Tab four times and then Shift-Tab four times.  The
visible sign of selection is a gold border around the selected button.

One significance of selection is that you can press the selected button by
pressing the Enter key.  (Because the buttons move the ac window, you may have
to move the pointer to maintain focus after pressing Enter.)  Now move the
pointer onto a button of another object, press and hold the left mouse button,
then release it and press and hold the Enter key.  Do you see a significant
difference between the two ways of pressing the displayed button?

When you use the left mouse button, the displayed button stays depressed for
as long as you hold the mouse button down: the displayed button acts as if it
were the mouse button.  When you press and hold Enter, however, the usual
typamatic action takes place: the displayed button is pressed and released
once, and then, after a slight pause, it is rapidly pressed repeatedly until
the Enter key is released.

Moving selection within a row or column can also be done with the arrow keys.
Movement appropriate to the key occurs in a cyclic fashion.  Try the up and
down arrow keys in the various windows after selecting a button.  Notice that
two buttons are isolated from the other two in ac as far as these arrow keys
are concerned.  Then try the left and right arrow keys in the various buttons
of ac.


1d. More about Appearance

1d(i). Changes in Appearance

	Attributes:	hl
			hlthickness
			shadowthickness

Three appearance attributes are related to selection and pressing of buttons.
The "hs" attribute controls the color of the selection border; its default
value is gold.  Execute

     `d has (`hl;`mediumseagreen)

and move the pointer to give focus to d, so that you can see the green border.

The "hlthickness" attribute controls the width of the border; its default
value is 0, which means the thinnest.  Execute

     `c has (`hlthickness;5); br{`c;0 400}

and see how the object is enlarged, to allow for the wider border.  Now give
focus to c, so that you can see this border.

When an action is taken to press a displayed button, the button appears to be
physically pressed.  The button is darkened; its bottom and right edges are
highlighted, instead of its top and left; and its top and left edges are
shadowed, instead of its bottom and right.  Thickening the edges of the
buttons increases their apparent height and emphasizes this apparent action.
The thickness is controlled by the value of the "shadowthickness" attribute,
which has a default value of 2.  Execute

     `b has (`shadowthickness;6); br{`b;0 600}

and see how the object is enlarged, to allow for the thicker edges.  Now press
one of b's buttons, and notice how the shadow is switched.

When an object is placed in a container, giving it a shadowthickness of zero
is sometimes useful, so that its buttons do not seem separate from other
objects in the container:

     `b has (`shadowthickness;0)

1d(ii). Other Features

	Attributes:	exit
		       	foot
			head
			is
			leftfoot
			pin
                        resizeable
			rightfoot

In popups, the pin can be used for communication between the viewer and the
programmer.  For example, the viewer can push the pin in to say that he wants
to have the window remain visible or pull it out to indicate that he would
like to have the window removed.  Likewise, the programmer can show the pin in
or out to state his intentions.  The viewer changes the pin position by
clicking on it with the left mouse button.  In an A+ statement, the "pin"
attribute is used to set the position.  This attribute always reflects the pin
position, 1 for in and 0 for out.  Try this sequence:

     `pin of `b`c
     `b has (`pin;1)

Place the mouse pointer on the pin of c and press and release the left mouse
button.

     `pin of `b`c
     `b has (`pin;0)

Click on the pin of c again.  The c window vanished, didn't it?  The "exit"
attribute determines what happens when a viewer attempts to remove an object
from the screen.  Its default value is 1, which means hide the object.  By
changing this value to 0, say, you can have nothing happen when the pin is
pulled:

     `d has (`exit;0)
     `d has (`pin;1)

Now click on the pin of d.  The pin moves, but nothing else happens.  You can
push and pull the pin as much as you like and nothing happens.

Exit is functional: its value can be a function.  It can be set for top-level
windows as well as popups.  For example:

     no{x}:"Don't do that to the ",x," window,",sys.getusername{},"!"
     `b has (`exit;(no;`title of `b))
     `ac has (`exit;(no;`title of `ac))

Now push and pull the pin of b.  Place the tip of the mouse pointer in the
window-manager button of the ac window, press and hold the right mouse button,
move the pointer down to "Quit", and release the button.  In both instances,
the no function is called and the usual behavior does not occur, an admonition
appearing instead.  If, however, you click on the window-manager button of the
ac window or choose "Close" from its menu, the window will be hidden; then
double-clicking on its icon will bring it back.

Three otherwise unrelated attributes pass along window-manager facilities, and
cannot be changed for a window after it has been shown.  They are "head",
"foot", and "resizeable".  None applies to objects that are not top-level or
popups, since they relate to window-manager features.  The head attribute
determines whether a window has a window-manager area at the top; since that
area is not removable for top-level objects, head applies only to popups.  The
foot attribute determines whether there is an area at the bottom for
footnotes.  The resizeable attribute determines whether the window has resize
corners; that is, whether a viewer can resize the window by dragging.

These attributes are set between binding and mapping, so this is a good time
to mention the "is" attribute.  It can contain a function (and, optionally, an
argument) that is called immediately after the variable is bound.  Its default
is null.

     ed
     f{x}:(x),' is bound to ',,`class of x
     `e has (`is;(f;`e))
     `e is `action
     `e has (`resizeable `head `foot;(0;0;1))   
     show `e; br{`e;0 200}

Note that the e display has no panel at the top, so no pin or shelltitle
appears; it has a panel at the bottom that becomes lighter when the window has
focus (and that can be used for moving with the mouse); and it should have no
resize corners -- although it probably does have them, because of a window
manager bug, an interaction between resizeable and head that causes only the
one that is set later to be obeyed when they are both set to 0.

Two footnotes can appear; they are the values of the "leftfoot" and
"rightfoot" attributes.  Space is not made for them automatically, and they
are truncated if there is not enough room:

     `e has (`leftfoot;'Morgan Stanley')
     `e has (`xs;150)
     `e has (`rightfoot;'March 1994')
     `e has (`xs;250)


1e. Status and its Preservation

1e(i). Status

	Attributes:	bound
			class
			stateself
			settings

There are attributes which give you information about objects.  Some, like the
"bound" and "class" attributes, apply meaningfully to objects that are not
bound.  The class attribute for an unbound variable, for instance, is its
default display class.  You cannot set bound directly; it is a reference-only
attribute.

     prometheus'fire'
     `bound of `e `prometheus
     `class of `e `prometheus
     `prometheus has (`class;`command)
     `bound`class of `prometheus

The bound attribute is set to 1 by the is and show functions and by a non-null
specification of the class attribute; it is set to 0 by the free function and
null specification of class.  The class attribute is set by the is function to
its right argument; it is set to a default class by the free function, in
effect, and, if bound was 0, by show.

The "settings" attribute, which is for reference only, can be used to obtain a
slotfiller holding, generally speaking, the attributes that have non-default
values (except the class attribute) and the values of those attributes.

     `settings of `e

The xs attribute was not included, because its value was not known to be
non-default.  The attributes can be restricted or extended to certain ones by
naming them.  The statement above is equivalent to (`settings;) of `e.

     (`settings;`leftfoot `xs `title) of `e

The title attribute is omitted, because its value is the default.  Since a
specific request was made for xs and its value is not known to be the default,
it is included.

The "stateself" attribute, which is also for reference only, gives the same
information as `settings of, plus the value of the class attribute.  The value
of stateself will create the object when executed in the presence of the
underlying variable with a suitable value.  It is an s definition of the
object in association-list form:

     `stateself of `e

1e(ii). Saving

	Attribute:	script
	Variable:	s.WM_SAVE_YOURSELF
	Function:	s.script{}

The s.WM_SAVE_YOURSELF variable can hold the name of a function and,
optionally, an argument.  Its default value is null.  When "Save Workspace" or
"owplaces" is selected from the OLVWM Utilities Menu, the function named in
s.WM_SAVE_YOURSELF, if any, is called, allowing any vital information to be
saved or necessary actions to be taken.

The s-context niladic function s.script produces a script that will recreate
the current screen layout, given the presence of the necessary variables with
appropriate values.  There may be no need to preserve information about some
of the objects.  The default value of 1 for the "script" attribute dictates
that the s definition of the object appear in that script and a value of 0
dictates that it not appear.  Try, for example,

     `d has (`script;0)
     s.script{}

Now clean up for the next display class:

     _ex `acbfn `pc `diag `f `no, free `ac `b `c `d `e `prometheus



2. The Button Display Class

	Attributes:	margin
			naturalsize


An object of the button class looks rather like an object of the action class
with only one button and no title area.  The variable that is bound to it does
not contain symbolic indices and values, however, but rather a function array
and perhaps data.  The function must be monadic or niladic.

Specifically, let fn be a monadic function and define b as (fn;data).  Then b
can be bound to the button class, and whenever the button is pressed, fn{data}
will be executed.  A second form for defining a button is <{fn}, which is
equivalent to (fn;) for monadic functions; when the button is pressed, the
expression fn{()} or, for a niladic function, fn{} is executed.

Notice that for the button class no callback need be set; the function that is
bound is called automatically.

As an example, define a button that, when pressed, moves across the screen and
jumps back, but don't press it until after you have made the comparison set up
below:

     bf{v}:v has (`x;600|100+`x of v)
     bu(bf;`bu)
     show `bu is `button; br{`bu;0}

Just for a comparison of their appearances:

     ac(,`bu;,<1)
     `ac has (`class;`action; `title;''; `show;1); br{`ac;0 50}

     _ex free `ac

Now you can press the button.

There is no title area like the one an action object can have; the title
attribute applies to the text on the button (unlike for an action object,
which employs the label attribute for text on its buttons).  When there are no
blanks or other impermissible characters in it, a title or label can be given
as a symbol, instead of a character string.  The object is not automatically
resized for a new title:

     `bu has (`title;`Move)

The "naturalsize" attribute is an action attribute; it cannot be queried.  It
resizes an object to show it afresh, as if it, with its current text, values,
and features, were being initially displayed --

     `bu has (`naturalsize;); br{`bu;0}

-- except that in an array or matrix or suchlike the same rows and columns
might not be shown as originally, as demonstrated in the discussion of
naturalsize in the array section of the Data tutorial.

The "margin" attribute governs the minimum margin around the title on the
button; its default value is 2.  It does not affect the button size:

     `margin of `bu
     `bu has (`margin;10);
     `bu has `naturalsize; br{`bu;0}
     `bu has (`margin;200);
     `bu has `naturalsize; br{`bu;0}
     `bu has (`margin;2);
     `bu has `naturalsize; br{`bu;0}

The margin attribute also applies to the margin around the text in an object
of the label class.

     _ex free `bu



3. The Check Display Class


An object of the check class is a slotfiller variable with boolean values that
are represented by buttons.  A button is "on" if the corresponding value is 1
and "off" if it is 0.  When a button is on it has a sunken appearance and is
the color specified by the fg attribute, and when off it has a raised
appearance and is the color specified by the bg attribute.

Clicking the left mouse button on a check button toggles it between on and
off, and at the same time the corresponding value in the A+ variable is
toggled between 1 and 0.  Therefore, if a callback function is defined for the
slotfiller variable, mouse clicks cause the callback function to be executed,
the path argument p being the symbolic index of the changed value.

The slot areas that appear in the display and their arrangement can be
controlled by the setting of the geometry attribute.

This first example is a two-button moving display, in which pressing a button
moves the display to the position indicated by its buttons:

     c(`bottom`right;(0;1))
     `c is `check
     cbf{}:`c has (`yx;5001c)
     `c has (`show;1;`set;cbf;`yx;0 500)
     `c has (`fg;`mediumseagreen;`bg;`rosybrown)

Try the various button combinations.

In the second example, we show one way to set up a check display to allow one
or more categories of data to be selected.  Actually, the function we define
here for the button just lists the selected categories in the session log when
it is pressed:

     ck(`cb`ci`co`ib`i`s`sb`wb`w;(0;0;0;0;0;0;0;0;0))
     lb(`cmo_bid;`cmo_inventory;`cmo_oddlot),ld_clb
     ckfn{}:>(1ck)/`label of `ck
     `ck has (`class;`check; `set;ckfn; `geometry;9);
     `ck has (`shelltitle;`CMOView; `title;'CMO Inventory Viewer');
     `ck has (`labelfont`titlefont;2<'newcenturyschlbk-roman-16');
     `ck has (`label;lb; `show;1; `xs;1140); br{`ck;0}

Press some category buttons, adding to and deleting from the set of requests.
Observe the list that appears in the A+ session log each time.

     _ex `lb `cbf `ckfn `bf, free `c `ck



4. The Radio Display Class


The radio class is like the check class, except that
(1) it has the additional stipulation that one and only one of the values of 
the boolean-valued slotfiller is 1, 
(2) its buttons are diamond-shaped, and 
(3) pressing a button that is off turns it on and causes the button that had 
been on to be turned off (pressing a button that is on has no effect).

When a button that is off is pressed, the value of the underlying variable is
changed accordingly.  Therefore, if a callback function is defined for that
variable, it is called, the path argument p being equal to the symbolic index
of the selected button.  Note that even though there are two value changes, a
callback function associated with the variable of a radio button is called
only once, and the path argument of the callback function refers to the value
that changed from 0 to 1.

The slot areas that appear in the display and their arrangement can be
controlled by the setting of the geometry attribute.

In our first example, we make the usual moving buttons.  Execute the following
statements and press various buttons:

     r(`tl`t`tr`l``r`bl`b`br;(1;0;0;0;0;0;0;0;0))
     cbf{}:`r has (`yx;0 250 500[3 3(1r)1])
     `r has (`class;`radio; `set;cbf; `geometry;3 3 3; `show;1);

In more realistic examples, the radio object might offer a choice among four
differently formatted security definition tables and also function as a
heading for that table, or it might present a choice of security types for
listing portfolio holdings.  In our examples, the callback function merely
gives (in the session log) a waiter's response:

     _ex free `r
     rd(`ms`ba`na`bl;(0;1;0;0))
     `rd has (`class;`radio; `geometry;2; `shelltitle;'MBS'; `title;'');
     `rd has (`label;('BASIC MBS/STRIP';'BASIC ARM'),ld_rlb);
     cbf{s;d;i;p;c;v}:(>(`label of `rd)[(0rd)p]),'. Good choice.'
     show `rd has (`set;cbf); br{`rd;0}

Now the second example:
     
     `rd has (`hide;1;`shelltitle;`PH;`fg;`white;`labelfg;`white;`bg;`black);
     `rd has (`label;('Corporate';'Municipal'),ld_r1lb);
     show `rd  rd(`co`mu`mo`cm`us`ab;(1;0;0;0;0;0)); br{`rd;0}

Notice that you can click on the label or the diamond to press the button.

     _ex `cbf, free `rd