-- VMenusImpl.mesa
-- Russ Atkinson, June 14, 1982 10:31 pm
DIRECTORY
Buttons USING
[Button, ButtonProc, Create],
Labels USING
[Create, Label],
Rope USING
[Flatten, ROPE, Size, Text],
ViewerOps USING
[CreateViewer],
VMenus,
VFonts,
UserTerminal USING
[BlinkDisplay];
VMenusImpl: CEDAR PROGRAM
IMPORTS Buttons, Labels, Rope, UserTerminal, ViewerOps, VFonts
EXPORTS VMenus
= PUBLIC BEGIN OPEN Rope, VMenus;
wOff: INTEGER ← 8; -- width offset for buttons
hOff: INTEGER ← 4; -- height offset for buttons
Create: PROC
[name: ROPE, buttons: VButtonList ← NIL, parent: Viewer ← NIL,
x,y: INTEGER ← 0]
RETURNS [ViewerList] = TRUSTED {
w,h,max: INTEGER ← 0;
text: Rope.Text ← name.Flatten[];
head,tail: ViewerList ← NIL;
IF name.Size = 0 THEN text ← "??";
[w,h] ← ComputeStringInfo[text];
max ← w;
FOR bl: VButtonList ← buttons, bl.rest UNTIL bl = NIL DO
btext: Rope.Text ← bl.first.name.Flatten[];
[w,h] ← ComputeStringInfo[btext];
IF w > max THEN max ← w;
ENDLOOP;
-- we now know the max size for the button texts
w ← max + wOff;
h ← h + hOff;
IF parent = NIL
THEN
{-- create a container from the air
parent ← ViewerOps.CreateViewer
[flavor: $Container,
info: [name: text, iconic: FALSE, column: right],
paint: TRUE];
head ← LIST[parent]}
ELSE
{-- use the current parent
label: Labels.Label ← Labels.Create
[[name: text, parent: parent, wx: x, wy: y, ww: w, wh: h, border: FALSE]];
head ← LIST[label];
y ← y + h};
tail ← head;
FOR bl: VButtonList ← buttons, bl.rest UNTIL bl = NIL DO
bh: VButtonRec ← bl.first;
btext: Rope.Text ← bh.name.Flatten[];
proc: Buttons.ButtonProc ← bh.proc;
button: Buttons.Button ←
Buttons.Create
[info: [name: btext, parent: parent, wx: x, wy: y, ww: w, wh: h],
proc: IF proc = NIL THEN DefaultVButtonProc ELSE proc,
clientData: bh.data, fork: bh.fork];
tail.rest ← LIST[button];
tail ← tail.rest;
y ← y + h - 1;
ENDLOOP;
RETURN [head];
};
GetDimensions: PROC
[list: ViewerList] RETURNS [xmin,ymin,xmax,ymax: INTEGER] = {
-- returns the dimensions of the vertical menu
-- given by the list of viewers
xmin ← ymin ← 0;
xmax ← ymax ← -1;
FOR vl: ViewerList ← list, vl.rest UNTIL vl = NIL DO
vh: Viewer ← vl.first;
xm: INTEGER ← vh.wx + vh.ww - 1;
ym: INTEGER ← vh.wy + vh.wh - 1;
IF xmin > vh.wx THEN xmin ← vh.wx;
IF ymin > vh.wy THEN ymin ← vh.wy;
IF xmax < xm THEN xmax ← xm;
IF ymax < ym THEN ymax ← ym;
ENDLOOP;
};
TestVButtonList: VButtonList ←
LIST[[name: "First", proc: NIL, fork: TRUE, data: NIL],
[name: "Second", proc: NIL, fork: TRUE, data: NIL]];
DefaultVButtonProc: Buttons.ButtonProc = TRUSTED {
UserTerminal.BlinkDisplay[];
};
ComputeStringInfo: PROC [r: ROPE] RETURNS [w,h: INTEGER] = TRUSTED {
w ← VFonts.StringWidth[r];
h ← VFonts.FontHeight[];
};
END.