-- 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.