Controls.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Bloomenthal, June 9, 1986 6:26:05 pm PDT
DIRECTORY Imager, ImagerFont, IO, List, Menus, Rope, TIPUser, ViewerClasses;
Controls: CEDAR DEFINITIONS
~ BEGIN
Basic Types
ClickProc:  TYPE ~ Menus.ClickProc;    -- proc called if entry button is pressed
Viewer:   TYPE ~ ViewerClasses.Viewer;   -- buttons, controls, typescripts, graphics
Context:   TYPE ~ Imager.Context;
Detents:   TYPE ~ RECORD [t, val: REAL];  -- special positions within a control
Entry:   TYPE ~ RECORD [      -- specifications for a menu button
name:    Rope.ROPE,
proc:    ClickProc,
row:    INTEGER ← 0,
x, y, w, h:  INTEGER ← 0,
font:    Imager.Font ← NIL,
fork:    BOOLTRUE,
documentation: REF ANYNIL,
paint:    BOOLTRUE,
guarded:   BOOLFALSE,
style:    ATOM ← $BlackOnWhite,
viewer:   Viewer ← NIL
];
MouseButton: TYPE ~ {none, left, middle, right}; -- which mouse button was operated
MouseState:  TYPE ~ {none, down, held, up};  -- state of mouse button operated
Mouse:   TYPE ~ RECORD [      -- complete mouse information
x, y:    INTEGER,
state:    MouseState,
button:   MouseButton
];
ControlProc:  TYPE ~ PROC [control: ControlData]; -- proc called if control adjusted
ControlType:  TYPE ~ {horiz, vert, circ};   -- horiz. or vertical sliders, circular dial
ControlTaper: TYPE ~ {log, lin, exp};     -- logarithmic, linear, or exponential
ControlSizes:  TYPE ~ RECORD [
horizWid:  INTEGER,
vertWid:   INTEGER,
circDia:    INTEGER
];
ControlData:  TYPE ~ REF ControlDataRec;   -- complete control information
ControlDataRec: TYPE ~ RECORD [
name:    Rope.ROPENIL,
type:    ControlType ← horiz,
taper:    ControlTaper ← lin,
min, max, init: REAL ← 0.0,
truncate:   BOOLFALSE,
report:   BOOLTRUE,
detents:   LIST OF Detents ← NIL,
proc:    ControlProc ← NIL,
data:    REF ANYNIL,
row:    INTEGER ← 0,
x, y, w, h:  INTEGER ← 0,
cx, cy, rad:  REAL ← 0.0,
t, val, preval: REAL ← 0.0,
predetented:  BOOLFALSE,
detented:   BOOLFALSE,
mouse:   Mouse ← [0, 0, none, none],
dummy:   BOOLFALSE,     -- if true, don't paint this control
outerData:  OuterData ← NIL,
viewer:   Viewer ← NIL,
title, status:  Viewer ← NIL,
graphics, parent: Viewer ← NIL
];
ControlList:  TYPE ~ LIST OF ControlData;
DestroyProc:  TYPE ~ PROC [outer: OuterData]; -- call when outer viewer destroyed
GraphicsProc: TYPE ~ PROC [graphics: GraphicsData]; -- call if graphics viewer mouse act
GraphicsShow: TYPE ~ PROC [
context:   Context,
w, h:    INTEGER,
data:    REF ANYNIL,
whatChanged: REF ANYNIL
];
GraphicsData: TYPE ~ REF GraphicsDataRec;    -- complete graphics viewer specs
GraphicsDataRec: TYPE ~ RECORD [
proc:    GraphicsProc ← NIL,
show:    GraphicsShow ← NIL,
mouse:   Mouse ← [0, 0, none, none],
data:    REF ANYNIL,
viewer, parent: Viewer ← NIL
];
OuterData:  TYPE ~ REF OuterDataRec;     -- complete outer data
OuterDataRec: TYPE ~ RECORD [
parent:   Viewer ← NIL,
graphics:   Viewer ← NIL,
typeScript:  Viewer ← NIL,
graphicsData: GraphicsData ← NIL,
destroyProc:   DestroyProc ← NIL,
controls:   ControlList ← NIL,
entries:   LIST OF Entry ← NIL,
controlY:   INTEGER ← 0,
controlH:   INTEGER ← 0,
graphicsY:  INTEGER ← 0,
graphicsH:  INTEGER ← 0,
tsY:    INTEGER ← 0,
tsH:    INTEGER ← 0,
entryY:   INTEGER ← 0,
entryH:   INTEGER ← 0,
outerY:   INTEGER ← 0,
outerH:   INTEGER ← 0,
tSin:    IO.STREAMNIL,
tSout:    IO.STREAMNIL,
tSclear:   BOOLTRUE,
val:    REAL ← 0.0,
destroyed:  BOOLFALSE,
data:    REF ANYNIL,
directory:   Rope.ROPENIL,
cmdOut:   IO.STREAMNIL
];
Procedures
OuterViewer: PROC [
name: Rope.ROPENIL,
column: ViewerClasses.Column ← left,
entries: LIST OF Entry ← NIL,
controls: ControlList ← NIL,
controlSizes: ControlSizes ← [200, 25, 60],
graphicsHeight: INT ← 0,
graphicsProc: GraphicsProc ← NIL,
graphicsShow: GraphicsShow ← NIL,
destroyProc: DestroyProc ← NIL,
typeScript: BOOLFALSE,
data: REF ANYNIL,
noOpen: BOOLFALSE]
RETURNS [Viewer];
Create a top level viewer whose data field is of type OuterData.
This viewer may contain an arbitrary number of controls, which may be
created with NewControl[].
The viewer may also contain an arbitrary number of entries; when an entry's
clickproc is called, it is passed the viewer's outerData.
The viewer may also contain a single sub-viewer for graphical display.
Lastly, the viewer may contain a single typescript viewer; if the typescript viewer
exists, messages to and from the user may be accomplished with TypeScriptWrite[]
and TypeScriptRead[]; the typescript viewer is placed at the top of the outer viewer,
just below any entry buttons.
If noOpen is TRUE then don't open the viewer (iconic or otherwise), thus permitting a
program to manipulate the viewer first (for example, installing an icon from a file).
GraphicsViewer: PROC [
parent: Viewer,
y, h: INT ← 0,
proc: GraphicsProc,
show: GraphicsShow,
data: REF ANY]
RETURNS [Viewer];
Create a graphics viewer of height h and parent.
NewControl: PUBLIC PROC [
name: Rope.ROPENIL,
type: ControlType ← horiz,
taper: ControlTaper ← lin,
min, max, init: REAL ← 0.0,
report: BOOLTRUE,
truncate: BOOLFALSE,
detents: LIST OF Detents ← NIL,
proc: ControlProc ← NIL,
data: REF ANYNIL,
row: INTEGER ← 0,
x, y, w, h: INTEGER ← 0,
dummy: BOOLFALSE]
RETURNS [ControlData];

Return a control. The name will appear above the control if the type is vert or circl, or to the right of the control if the type is horiz. If report is true, the current control value appears below the control name. If truncate is true, the reported value is given as an integer. proc, if non-nil, is called everytime the control is adjusted. The controls are normally ordered by OuterViewer, from right to left, beginning new rows as needed; if row is non-zero, however, the control will appear in the specified row and all subsequent controls will follow it. If y is non-zero, however, the control will appear at the specified y value, regardless of the value of row. If dummy is true, just use this control for positioning, not to be painted.
EntryReLabel: PROC [outerData: OuterData, oldName, newName: Rope.ROPE];
Change the button name from oldName to newName (but alas, not the size).
EntryToggle: PROC [outerData: OuterData, state: BOOL, trueName, falseName: Rope.ROPE];
Change the button name to trueName or falseName, depending on state.
EntryStyle: PROC [outerData: OuterData, name: Rope.ROPE, style: ATOM];
Change the style of the named button; recognised display styles are:
$BlackOnWhite - black letters on white background (default)
$WhiteOnBlack - white letters on black background
$BlackOnGrey - black letters on grey background
EntryPositions: PUBLIC PROC [entries: LIST OF Entry] RETURNS [entryHeight: INTEGER];
If not already set, set default location and size for entries.
EntryViewerList: PUBLIC PROC [parent: Viewer, entries: LIST OF Entry, data: OuterData];
Create set of entry viewers from list of entries.
EntryViewer: PROC [parent: Viewer, e: Entry, data: OuterData] RETURNS [Viewer];
Create a button viewer from e.
TypeScriptClear: PROC [outerData: OuterData];
Write a carriage-return to the tyescript viewer if the current line is not empty.
TypeScriptWrite: PROC [outerData: OuterData, rope: Rope.ROPE];
Write the rope into the typescript viewer.
TypeScriptRead: PROC [outerData: OuterData] RETURNS [Rope.ROPE];
Wait for a reply terminated with a carriage-return.
TypeScriptReadFileName: PROC [outerData: OuterData] RETURNS [Rope.ROPE];
Wait for a reply and prepend directory name if necessary.
ControlRow: PROC [c: ControlData, row: INTEGER];
Make c begin on given row; to have an effect, this call must preceed call to OuterViewer.
ControlPositions: PROC [controls: ControlList, sizes: ControlSizes] RETURNS [height: INTEGER];
If not already set, set default location and size for controls.
ControlViewerList: PROC [
parent, graphics: Viewer ← NIL,
controls: Controls.ControlList,
data: REF ANY];
Create set of viewers from list of controls.
ControlViewer: PROC [
parent, graphics: Viewer ← NIL,
control: ControlData,
data: REF ANYNIL,
outerData: OuterData ← NIL];
Create a control given a parent viewer.
SetControlVal: PROC [c: ControlData, val: REAL, repaint: BOOLTRUE];
Set the value of the control to val and repaint the control iff repaint is true.
GetControlVal: PROC [c: ControlData] RETURNS [REAL];
Return the value of the control.
GetControlValInt: PROC [c: ControlData] RETURNS [INTEGER];
Return the value of the control as rounded to an integer.
ControlReset: PROC [c1, c2, c3, c4, c5, c6: Controls.ControlData ← NIL];
Set to 0.0 and repaint any non-nil controls.
SetMouse: PROC [a: ATOM, t: TIPUser.TIPScreenCoords] RETURNS [Mouse];
Return coordinates, which button, and button state of the mouse.
Quit: ClickProc;
Default quit menu function.
Restore: ClickProc;
Menu function to restore all controls to intital settings.
EndViewer: PROC [viewer: REF ANY];
Destroy the given viewer.
UnTick: PROC [context: Context, c: ControlData];
Delete the previously set tick mark on the given control.
Tick: PROC [context: Context, c: ControlData, val: REAL, detent: BOOLFALSE, width: INT ← 1];
Set a tick mark for on the given control at location val.
Circle: PROC [context: Context, x, y, rad: REAL, fill: BOOLFALSE];
Draw a circle.
Square: PROC [context: Context, x, y, size: REAL];
Draw a (filled in) square.
Append: PROC [control: ControlData, list: ControlList ← NIL] RETURNS [ControlList];
Add control to end of list and return pointer to beginning of list.
END.