Controls.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Bloomenthal, February 25, 1987 5:15:10 pm PST
DIRECTORY CedarProcess, Imager, ImagerFont, IO, List, Menus, Rope, TIPUser, Vector2, ViewerClasses;
Controls: CEDAR DEFINITIONS
~ BEGIN
Imported Types
Context:    TYPE ~ Imager.Context;
ClickProc:   TYPE ~ Menus.ClickProc;    -- called if button is buttoned
Viewer:    TYPE ~ ViewerClasses.Viewer;   -- buttons, controls, graphics, etc.
Column:    TYPE ~ ViewerClasses.Column;
Font:     TYPE ~ Imager.Font;
Process:    TYPE ~ CedarProcess.Process;
ROPE:     TYPE ~ IO.ROPE;
STREAM:    TYPE ~ IO.STREAM;
Controls Types
Pos:     TYPE ~ RECORD [x, y: INTEGER ← 0];
PosSequence:   TYPE ~ REF PosSequenceRep;
PosSequenceRep:  TYPE ~ RECORD [
length:      NAT ← 0,
element:      SEQUENCE maxLength: NAT OF Pos
        ];
PosSequences:  TYPE ~ REF PosSequencesRep;
PosSequencesRep: TYPE ~ RECORD [
length:      NAT ← 0,
element:      SEQUENCE maxLength: NAT OF PosSequence
];
MouseButton:  TYPE ~ {none, left, middle, right}; -- which mouse button was buttoned
MouseState:   TYPE ~ {none, down, held, up};  -- state of pressed button
Mouse:    TYPE ~ RECORD [      -- complete mouse information
x, y:       INTEGER ← 0,     -- screen coordinates
state:       MouseState ← none,
button:      MouseButton ← none,
controlKey, shiftKey:  BOOLFALSE
];
IntegerSequence:  TYPE ~ REF IntegerSequenceRep;
IntegerSequenceRep: TYPE ~ RECORD [element: SEQUENCE length: NAT OF INTEGER];
RealSequence:  TYPE ~ REF RealSequenceRep;
RealSequenceRep:  TYPE ~ RECORD [element: SEQUENCE length: NAT OF REAL];
A Control
A control is a viewers which may be a slider, dial, function, or contour.
Control:    TYPE ~ REF ControlRep;
ControlRep:   TYPE ~ RECORD [      -- complete control information
for all:
name:      ROPENIL,      -- name of control
type:      ControlType ← vSlider,   -- slider, dial, functioner, contourer
proc:      ControlProc ← NIL,    -- proc to call if control adjusted
process:     Process ← NIL,     -- fork new process if old not busy
report:     BOOLTRUE,     -- if true, report control value
truncate:     BOOLFALSE,     -- if true, truncate reported value
row:      INTEGER ← 0,     -- row of control (0 is lowest)
x, y, w, h:    INTEGER ← 0,     -- control sizes (usu. automatic set)
textLocation:    TextLocation ← above,   -- where to place text
font:      Font ← NIL,      -- font type (usu. defaulted)
dummy:     BOOLFALSE,     -- if true, don't paint this control
data:      REF ANYNIL,     -- client supplied data
for sliders, dials, and functions only:
min, max, init:   REAL ← 0.0,      -- range and inital value of control
detents:     DetentList ← NIL,    -- for sliders or dials
taper:      SliderTaper ← lin,    -- for sliders
value:      REAL ← 0.0,      -- (readonly) slider or dial value
valuePrev:    REAL ← 0.0,      -- (readonly) previous slider value
values:     RealSequence ← NIL,   -- function values
private implementation details:
sliderDialRef:   REF ANY,      -- (private) details in impl
functionRef:    REF ANY,      -- (private) details in impl
contourRef:    REF ANYNIL,     -- (private) details in impl
sketchRef:    REF ANYNIL,     -- (private) details in impl
private/readonly for all:
mouse:     Mouse,       -- (readonly) mouse in control
outerData:    OuterData ← NIL,    -- (readonly) parent viewer data
viewer:     Viewer ← NIL,     -- (readonly) control viewer
flavor:     ATOM ← $Nil,     -- (readonly) permit some wizardry
title:      Viewer ← NIL,     -- (private) viewer to display name
status:      Viewer ← NIL,     -- (private) viewer to display value
parent:      Viewer ← NIL,     -- (private) outer viewer
graphics:     Viewer ← NIL     -- (private) graphics viewer
];
ControlList:   TYPE ~ LIST OF Control;
ControlProc:   TYPE ~ PROC [control: Control];  -- proc called if control adjusted
ControlType:   TYPE ~ {
vSlider,               -- vertical slider; bar is horizontal
hSlider,               -- horizontal slider; bar is vertical
dial,                -- circular dial
function,               -- rectangular viewer for function
contour,               -- rectangular viewer for contour
sketch               -- rectangular viewer for sketch
};
ControlSizes:   TYPE ~ RECORD [
wVSlider:      INTEGER,       -- width of vertical slider
wHSlider:      INTEGER,       -- width of horizontal control
hVSlider:      INTEGER,       -- height of vertical slider
hHSlider:      INTEGER,       -- height of horizontal slider
dDial:       INTEGER,       -- diameter of dial
wSketch:      INTEGER,       -- width of sketcher
hSketch:      INTEGER       -- height of sketcher
];
defSizes:    ControlSizes ~ [25, 200, 60, 25, 60, 150, 150];
Detents:    TYPE ~ RECORD [      -- detent positions within a control
t:        REAL,        -- private
value:       REAL        -- for client use
];
DetentList:   TYPE ~ LIST OF Detents;
TextLocation:   TYPE ~ {above, below, left, right}; -- text placement relative to control
SliderTaper:   TYPE ~ {log, lin, exp};     -- logarithmic, linear, or exponential
Outer Types and Procedures
These relate to an outer, top-level viewer containing controls.
OuterData:   TYPE ~ REF OuterDataRep;
OuterDataRep:  TYPE ~ RECORD [     -- complete outer data
name:       ROPENIL,     -- name of viewer
column:      Column ← left,    -- column of viewer
data:       REF ANYNIL,    -- client supplied data
parent:      Viewer ← NIL,    -- (private) main outer viewer
typeScript:     Viewer ← NIL,    -- (private) typeScript viewer
graphics:      Viewer ← NIL,    -- (private) graphics viewer
graphicsData:    GraphicsData ← NIL,  -- (private) graphics viewer data
controls:      ControlList ← NIL,   -- controls for parent viewer
controlSizes:     ControlSizes ← defSizes, -- default sizes for controls
lastControl:     Control ← NIL,    -- (readonly) last control moused
buttons:      LIST OF Button ← NIL,  -- buttons for outer viewer
destroyProc:      DestroyProc ← NIL,   -- call if outer viewer destroyed
destroyed:     BOOLFALSE,    -- (readonly) if viewer destroyed
directory:      ROPENIL,     -- (readonly) commander directory
cmdOut:      STREAMNIL,    -- (readonly) commander output
controlsY:      INTEGER ← 0,    -- (private) base of controls
controlsH:     INTEGER ← 0,    -- (private) height of controls
graphicsY:     INTEGER ← 0,    -- (private) base of graphics
graphicsH:     INTEGER ← 0,    -- (private) graphics viewer height
tsY:       INTEGER ← 0,    -- (private) base of typescript
tsH:       INTEGER ← 0,    -- (private) typescript height
buttonsY:      INTEGER ← 0,    -- (private) base of buttons
buttonsH:      INTEGER ← 0,    -- (private) height of buttons
outerH:      INTEGER ← 0,    -- (private) height of outer viewer
tSin:       STREAMNIL,    -- (private) input typescript stream
tSout:       STREAMNIL,    -- (private) output typescript stream
tSclear:      BOOLTRUE    -- (private) typescript display clear?
];
DestroyProc:   TYPE ~ PROC [outerData: OuterData]; -- call when outer viewer destroyed
OuterViewer: PROC [
name: ROPENIL,
column: Column ← left,
buttons: ButtonList ← NIL,
controls: ControlList ← NIL,
controlSizes: ControlSizes ← defSizes,
graphicsHeight: INTEGER ← 0,
graphicsProc: GraphicsProc ← NIL,
graphicsShow: GraphicsShow ← NIL,
destroyProc: DestroyProc ← NIL,
typeScriptHeight: INTEGER ← 0,
data: REF ANYNIL,
noOpen: BOOLFALSE]
RETURNS [Viewer];

Create a top level viewer whose data field is of type OuterData.

The viewer may contain an arbitrary number of controls and buttons, a single typescript, and a single graphics viewer. The buttons are placed at the top of the viewer. Below the buttons is the optional, scrollable typescript (usually a height of 18 is good for one line); the software may print or prompt to the typescript, and the user may type a reply. Below the typescript is an optional sub-viewer for display of graphical material. The controls are placed below the graphics viewer.

If noOpen then the viewer will not be opened (iconic or otherwise), permitting a program to manipulate the viewer (for example, installing an icon from a file) before displaying it.
ChangeOuterViewer: PROC [outerData: OuterData, controls: ControlList];
Resize outer viewer, if necessary to accomodate new controls; remove any previous controls
no longer in the list.
Graphics Types and Procedures
This is the viewer that permits a graphics display.
GraphicsData: TYPE ~ REF GraphicsDataRep;
GraphicsDataRep: TYPE ~ RECORD [      -- complete graphics viewer specs
proc:    GraphicsProc ← NIL,     -- called if graphics mouse action
show:    GraphicsShow ← NIL,     -- proc called to display graphics
data:    REF ANYNIL,       -- client supplied data
mouse:   Mouse ← [0, 0, none, none],   -- (readonly) graphics viewer mouse
viewer:   Viewer ← NIL,       -- (private) graphics viewer
parent:   Viewer ← NIL       -- (private) parent viewer
];
GraphicsProc: TYPE ~ PROC [       -- call if graphics viewer mouse action
graphics: GraphicsData
];
GraphicsShow: TYPE ~ PROC [       -- graphics display proc
context:   Context,         -- Imager context
w, h:    INTEGER,         -- size of context
data:    REF ANYNIL,       -- client supplied data
whatChanged: REF ANYNIL,       -- as in ViewerOps
viewer:   Viewer ← NIL       -- as in ViewerOps
];
GraphicsViewer: PROC [
parent: Viewer,
y, h: INTEGER ← 0,
proc: GraphicsProc,
show: GraphicsShow,
data: REF ANY]
RETURNS [Viewer];
Create a graphics viewer of height h and parent.
Control Creation
NewControl: PROC [
name: ROPENIL,
type: ControlType ← vSlider,
data: REF ANYNIL,
min, max, init: REAL ← 0.0,
proc: ControlProc ← NIL,
report: BOOLTRUE,
truncate: BOOLFALSE,
row: INTEGER ← 0,
x, y, w, h: INTEGER ← 0,
textLocation: TextLocation ← above,
dummy: BOOLFALSE,
flavor: ATOM ← $Nil,
detents: LIST OF Detents ← NIL,
taper: SliderTaper ← lin,
values: RealSequence ← NIL]
RETURNS [Control];
Return a control but do not allocate its viewer; viewer allocation done by ControlViewer.
name will appear above the control.
proc, if non-nil, is called everytime the control is adjusted.
If report is true, the current control value appears next to the control name.
If truncate is true, the displayed value is rounded to an integer.
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; 0 is the lowest row. 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, the control is used as a placeholder and is not painted.
If there are any detents, the taper is constrained to linear.
Append: PROC [control: Control, controls: ControlList ← NIL] RETURNS [ControlList];
Add control to end of list and return pointer to beginning of list.
ControlViewerList: PROC [
parent, graphics: Viewer ← NIL,
controls: Controls.ControlList,
data: REF ANY];
Create set of viewers from list of controls. Usually used internally.
ControlViewer: PROC [
parent: Viewer, graphics: Viewer ← NIL,
control: Control,
outerData: OuterData ← NIL];
Create a control given a parent viewer. Usually used internally.
Specifying flavor is recommended for wizards only.
Control Notification
NotifyControl: PUBLIC ViewerClasses.NotifyProc;
Wizards only!
SetMouse: PUBLIC PROC [atom: ATOM, tipCoords: TIPUser.TIPScreenCoords] RETURNS [Mouse];
Get a mouse from tip output.
LastControlMoused: PUBLIC PROC RETURNS [Control];
Return the most recently touched control. This may be a control that no longer exists!
Control Positioning
ControlPositions: PROC [controls: ControlList, sizes: ControlSizes, columnWidth: INTEGER]
RETURNS [height: INTEGER];
If not already set, set default location and size for controls. Usually used internally.
ControlRow: PROC [control: Control, row: INTEGER];
Place control on given row; to have an effect, this call must preceed call to OuterViewer;
0 is the lowest row.
Control Reading
GetSliderDialValue: PROC [control: Control] RETURNS [REAL];
Return the value of the control slider or dial.
GetFunctionValues: PROC [control: Control] RETURNS [RealSequence];
Return the values of the control function.
GetSketch: PROC [control: Control] RETURNS [PosSequences];
Return a sketch from the control's sketch list.
GetContour: PROC [control: Control] RETURNS [PosSequence];
Return a contour from the control's contour chain.
Control Setting
Reset: PROC [c1, c2, c3, c4, c5, c6: Control ← NIL, repaint: BOOLTRUE];
Set to initalial value(s) and optionally repaint any non-nil controls.
SetSliderDialValue: PROC [control: Control, value: REAL, repaint: BOOLTRUE];
Set the value of the control slider or dial to value and repaint the control iff repaint is true.
SetFunctionValues: PROC [control: Control, values: RealSequence, repaint: BOOLTRUE];
Set the values of the control function and repaint the control iff repaint is true.
SetSketch: PROC [control: Control, sketch: PosSequences, repaint: BOOLTRUE];
If control is type sketch, then replace its sketch with newSketch.
SetContour: PROC [
control: Control, pairs: PosSequence, closed: BOOLFALSE, repaint: BOOLTRUE];
If control is type contour, then replace its contour with newContour.
CloseContour: PUBLIC PROC [control: Control, repaint: BOOLTRUE];
Close the closed or unclosed contour.
Button Definitions and Procedures
These are menu buttons. When a button's proc is called, it is passed the outer viewer's data.
Button:   TYPE ~ RECORD [      -- specifications for a menu button
name:    ROPENIL,        -- name of button
proc:    ClickProc,        -- proc to call upon button press
row:    INTEGER ← 0,       -- vert. pos'n of button (0 is lowest)
x, y, w, h:  INTEGER ← 0,       -- button dimensions (usu. auto. set)
font:    Font ← NIL,        -- font type (usu. defaulted)
fork:    BOOLTRUE,       -- if true, fork proc on button
documentation: REF ANYNIL,       -- as in Buttons.mesa
paint:    BOOLTRUE,       -- as in Buttons.mesa
guarded:   BOOLFALSE,       -- as in Buttons.mesa
style:    ATOM ← $BlackOnWhite,    -- as in Buttons.mesa
viewer:   Viewer ← NIL       -- (private) viewer for this button
];
ButtonList:  TYPE ~ LIST OF Button;
ButtonReLabel: PROC [outerData: OuterData, oldName, newName: ROPE];
Change the button name from oldName to newName (but alas, not the size).
ButtonToggle: PROC [outerData: OuterData, state: BOOL, trueName, falseName: ROPE];
Change the button name to trueName or falseName, depending on state.
ButtonStyle: PROC [outerData: OuterData, name: 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
ButtonPositions: PROC [buttons: ButtonList] RETURNS [buttonHeight: INTEGER];
If not already set, set default location and size for entries. Usually used internally.
ButtonViewerList: PROC [parent: Viewer, buttons: ButtonList, outerData: OuterData];
Create set of button viewers from list of entries. Usually used internally.
ButtonViewer: PROC [parent: Viewer, button: Button, outerData: OuterData]
RETURNS [Viewer];
Create a button viewer from button. Usually used internally.
TypeScript Procedures
This is a scrollable viewer permitting text to be read or written.
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];
Write rope into the typescript viewer.
TypeScriptRead: PROC [outerData: OuterData, prompt: ROPENIL] RETURNS [ROPE];
Wait for a reply terminated with a carriage-return.
TypeScriptReadFileName: PROC [outerData: OuterData] RETURNS [ROPE];
Wait for a reply and prepend directory name if necessary.
Vernier Procedures
Vernier: PROC [vernier, control: Control, cwIncrease: BOOLTRUE, resolution: REAL ← 10.0];
vernier is used to make fine adjustments on control;
vernier must be a dial, control must be a slider or dial.
If cwIncrease, turning the vernier clockwise will increase the value of control.
resolution is the number of vernier rotations required to move control through its full extent.
Miscellaneous Querying
IsContourClosed: PROC [control: Control] RETURNS [BOOL];
Return true if contour associated with control is closed, false otherwise.
Return false if no contour associated with control.
NPointsInContour: PROC [control: Control] RETURNS [INTEGER];
Return number of pairs in contour associated with control.
Return 0 if no contour associated with control.
NLinesInSketch: PROC [control: Control] RETURNS [INTEGER];
Return number of lines in sketch associated with control.
Return 0 if no sketch associated with control.
NPointsInSketch: PROC [control: Control] RETURNS [INTEGER];
Return number of pairs in sketch associated with control.
Return 0 if no sketch associated with control.
Miscellaneous Procedures
Quit: ClickProc;
Default quit menu procedure.
Restore: ClickProc;
Restore all controls associated with outer to their initial settings.
EndViewer: PROC [viewer: REF ANY];
Destroy the given viewer.
END.