DIRECTORY Buttons USING [Create], Containers USING [Container, Create, ChildYBound, ChildXBound], Icons USING [IconFlavor, NewIconFromFile], Menus USING [AppendMenuEntry, ClickProc, CreateEntry, CreateMenu, Menu], PeanutWindow, Rope USING [Cat, ROPE], Rules USING [Create, Rule], TypeScript USING [Create, PutChar, PutRope, TS], UserProfile USING [Boolean, Number], VFonts USING [StringWidth], ViewerOps USING [DestroyViewer, MoveViewer, PaintViewer], ViewerSpecs USING [openRightWidth, scrollBarW]; PeanutWindowImpl: CEDAR MONITOR IMPORTS Buttons, Containers, Icons, Menus, Rope, Rules, UserProfile, TypeScript, VFonts, ViewerOps, ViewerSpecs EXPORTS PeanutWindow = BEGIN abortFlag: PUBLIC BOOL _ FALSE; OutputRope: PUBLIC ENTRY PROC [text: Rope.ROPE] = BEGIN ENABLE ANY => UNWIND; IF ~Destroyed[] THEN TypeScript.PutRope[peanutScript, text]; END; OutputChar: PUBLIC ENTRY PROC [char: CHAR] = BEGIN ENABLE ANY => UNWIND; IF ~Destroyed[] THEN TypeScript.PutChar[peanutScript, char]; END; SetNewMail: PUBLIC ENTRY PROC [newMail: BOOL] = BEGIN ENABLE ANY => UNWIND; newMailExists _ newMail; IF Destroyed[] THEN RETURN; peanutParent.icon _ IF newMailExists THEN newMailIcon ELSE noMailIcon; peanutParent.name _ Caption[newMailExists]; ViewerOps.PaintViewer[peanutParent, caption]; END; AddCommand: PUBLIC ENTRY PROC [name: Rope.ROPE, proc: Menus.ClickProc, data: REF ANY _ NIL, fork: BOOL _ TRUE, guarded: BOOL _ FALSE] = BEGIN ENABLE ANY => UNWIND; Menus.AppendMenuEntry[menu, Menus.CreateEntry[name, proc, data, NIL, fork, guarded]]; IF peanutScript#NIL THEN ViewerOps.PaintViewer[peanutParent, all]; END; AddButton: PUBLIC ENTRY PROC [name: Rope.ROPE, proc: Menus.ClickProc, data: REF ANY _ NIL, fork: BOOL _ TRUE, guarded: BOOL _ FALSE, redisplay: BOOL _ TRUE] = BEGIN ENABLE ANY => UNWIND; buttonHeight: INTEGER = 15; buttonSpacing: INTEGER = 5; width: INTEGER; IF Destroyed[] THEN RETURN; width _ VFonts.StringWidth[name]+6; IF width+buttonX>maxButtonX THEN BEGIN ViewerOps.MoveViewer[peanutRule, peanutRule.wx, peanutRule.wy+buttonHeight, peanutRule.ww, peanutRule.wh, FALSE]; ViewerOps.MoveViewer[peanutScript, peanutScript.wx, peanutScript.wy+buttonHeight, peanutScript.ww, peanutScript.wh-buttonHeight, FALSE]; buttonX _ 0; peanutParent.openHeight _ peanutParent.openHeight+buttonHeight; END; [] _ Buttons.Create[info: [parent: peanutParent, name: name, wx: buttonX, wy: peanutRule.wy-buttonHeight, border: FALSE, scrollable: FALSE], proc: proc, clientData: data, fork: fork, guarded: guarded]; buttonX _ buttonX+width+buttonSpacing; IF ~peanutParent.iconic AND redisplay THEN ViewerOps.PaintViewer[peanutParent, all]; END; Create: PUBLIC ENTRY PROC RETURNS [new: BOOL] = BEGIN ENABLE ANY => UNWIND; peanutOpenHeight: INTEGER; startIconic: BOOLEAN; IF ~Destroyed[] THEN RETURN [FALSE]; -- already exists peanutOpenHeight _ UserProfile.Number[key: "Peanut.WindowHeight", default: 80]; startIconic _ UserProfile.Boolean[key: "Peanut.StartIconic", default: TRUE]; peanutParent _ Containers.Create[[name: Caption[newMailExists], iconic: startIconic, icon: IF newMailExists THEN newMailIcon ELSE noMailIcon, column: right, openHeight: peanutOpenHeight, menu: menu, scrollable: FALSE]]; peanutRule _ Rules.Create[[parent: peanutParent, wx: 0, wy: 0, ww: maxButtonX, wh: 1, scrollable: FALSE, border: FALSE]]; peanutScript _ TypeScript.Create[[parent: peanutParent, wx: 0, wy: peanutRule.wy+peanutRule.wh, ww: maxButtonX, wh: 60, scrollable: TRUE, border: FALSE]]; Containers.ChildXBound[peanutParent, peanutRule]; Containers.ChildXBound[peanutParent, peanutScript]; Containers.ChildYBound[peanutParent, peanutScript]; buttonX _ LAST[INTEGER]/2; RETURN [TRUE]; END; Destroy: PUBLIC ENTRY PROC = BEGIN ENABLE ANY => UNWIND; IF ~Destroyed[] THEN ViewerOps.DestroyViewer[peanutParent]; peanutParent _ peanutScript _ NIL; END; Destroyed: PROC RETURNS [destroyed: BOOL] = BEGIN IF peanutParent=NIL THEN RETURN [TRUE] ELSE IF peanutParent.destroyed THEN {peanutParent_peanutScript_NIL; RETURN [TRUE]}; RETURN [FALSE]; END; Caption: PROC [newMail: BOOL] RETURNS [name: Rope.ROPE] = BEGIN name _ "Peanut"; IF newMail THEN BEGIN name _ Rope.Cat[name, " - You have new mail"]; END ELSE BEGIN name _ Rope.Cat[name, " - No new mail"]; END; END; peanutParent: PUBLIC Containers.Container; peanutRule: Rules.Rule; peanutScript: TypeScript.TS; menu: PUBLIC Menus.Menu _ Menus.CreateMenu[]; newMailIcon: PUBLIC Icons.IconFlavor _ Icons.NewIconFromFile["Peanut.icons", 0]; noMailIcon: PUBLIC Icons.IconFlavor _ Icons.NewIconFromFile["Peanut.icons", 1]; messageSetIcon: PUBLIC Icons.IconFlavor _ Icons.NewIconFromFile["Peanut.icons",2]; dirtyMessageSetIcon: PUBLIC Icons.IconFlavor _ Icons.NewIconFromFile["Peanut.icons", 3]; mailMessageIcon: PUBLIC Icons.IconFlavor _ Icons.NewIconFromFile["Peanut.icons", 4]; dirtyMailMessageIcon: PUBLIC Icons.IconFlavor _ Icons.NewIconFromFile["Peanut.icons", 5]; maxButtonX: INTEGER = ViewerSpecs.openRightWidth-ViewerSpecs.scrollBarW-4; buttonX: INTEGER; newMailExists: BOOL _ FALSE; END. ÔPeanutWindowImpl.mesa; Written by Scott McGregor, February 1983 Last edited by Paxton on March 1, 1983 8:59 am Last edited by McGregor on March 4, 1983 9:55 am Last Edited by: Pausch, July 14, 1983 2:28 pm ÊU– "Cedar" style˜Iproc– "Cedar" stylešœ?™?Kšœ.™.Kšœ0™0J™-unitšÏk ˜ Jšœœ ˜Jšœ œ/˜?Jšœœ˜*Jšœœ=˜HJšœ ˜ Jšœœœ˜Jšœœ˜Jšœ œœ˜0Jšœ œ˜$Jšœœ˜Jšœ œ*˜9Jšœ œ˜/—šœœ˜Jšœh˜oJšœ˜—Lš˜I modheader˜Mšœ œœœ˜M˜š Ïn œœœœ œ˜7Mšœœœ˜Mšœœ(˜