DIRECTORY Containers USING [Container], ViewerClasses USING [AdjustProc, GetProc, InitProc, PaintProc, ScrollProc, SetProc, Viewer, ViewerClass, ViewerClassRec, ViewerRec], ViewerLocks USING [CallUnderWriteLock], ViewerOps USING [CreateViewer, EstablishViewerPosition, PaintViewer, RegisterViewerClass]; ContainersImpl: CEDAR PROGRAM IMPORTS ViewerLocks, ViewerOps EXPORTS Containers = BEGIN OPEN ViewerClasses; Container: TYPE ~ Containers.Container; ContainerData: TYPE = REF ContainerDataRec; ContainerDataRec: TYPE = RECORD [ scrolled: INTEGER _ 0, yBounded: LIST OF Viewer _ NIL, xBounded: LIST OF Viewer _ NIL ]; Create: PUBLIC PROC [info: ViewerRec _ [], paint: BOOL _ TRUE] RETURNS [container: Container] = {RETURN[ViewerOps.CreateViewer[$Container, info, paint]]}; ChildYBound: PUBLIC PROC [container: Container, child: Viewer] ~ { IF child.parent#container THEN RETURN; WITH container.data SELECT FROM cd: ContainerData => cd.yBounded _ CONS[child, cd.yBounded]; ENDCASE; }; ChildXBound: PUBLIC PROC [container: Container, child: Viewer] ~ { IF child.parent#container THEN RETURN; WITH container.data SELECT FROM cd: ContainerData => cd.xBounded _ CONS[child, cd.xBounded]; ENDCASE; }; ContainerScroll: ScrollProc = { cd: ContainerData _ NARROW[self.data]; incr: INTEGER; height: INTEGER; LockedScroll: PROC = { FOR v: Viewer _ self.child, v.sibling UNTIL v=NIL DO ViewerOps.EstablishViewerPosition[v, v.wx, v.wy+incr, v.ww, v.wh]; ENDLOOP; cd.scrolled _ cd.scrolled+incr; ViewerOps.PaintViewer[self, client]; }; IF cd = NIL THEN RETURN; IF op=query OR op=thumb THEN { -- compute total height thumbIncr: LONG INTEGER; max: INTEGER _ -LAST[INTEGER]; min: INTEGER _ LAST[INTEGER]; FOR v: Viewer _ self.child, v.sibling UNTIL v=NIL DO min _ MIN[min, v.wy]; max _ MAX[max, v.wy+v.wh]; ENDLOOP; height _ max-min; IF op=thumb THEN { thumbIncr _ LONG[amount]*height/100; height _ thumbIncr; -- narrow to short integer }; }; IF op=query THEN { top, bottom: INT; IF self.child = NIL OR height=0 THEN RETURN [0, 100]; top _ LONG[100]*MIN[height, -cd.scrolled]/height; bottom _ 100 - (LONG[100]*MAX[height-self.ch+cd.scrolled, 0])/height; RETURN[top, bottom]; }; incr _ SELECT op FROM up => -amount, down => MIN[amount, -cd.scrolled], thumb => -cd.scrolled-(IF amount<5 THEN 0 ELSE height), ENDCASE => ERROR; IF incr#0 THEN ViewerLocks.CallUnderWriteLock[LockedScroll, self]; }; minDimension: INTEGER _ 5; ContainerAdjust: AdjustProc = { cd: ContainerData _ NARROW[self.data]; update: BOOL _ FALSE; IF cd = NIL THEN RETURN; FOR l: LIST OF Viewer _ cd.xBounded, l.rest UNTIL l=NIL DO v: Viewer ~ l.first; IF v.destroyed THEN update _ TRUE ELSE { newWidth: INTEGER ~ MAX[v.parent.cw-v.wx, minDimension]; IF newWidth#v.ww THEN { ViewerOps.EstablishViewerPosition[v, v.wx, v.wy, newWidth, v.wh]; adjusted _ TRUE; }; }; ENDLOOP; FOR l: LIST OF Viewer _ cd.yBounded, l.rest UNTIL l=NIL DO v: Viewer ~ l.first; IF v.destroyed THEN update _ TRUE ELSE { newHeight: INTEGER ~ MAX[v.parent.ch-v.wy, minDimension]; IF newHeight#v.wh THEN { ViewerOps.EstablishViewerPosition[v, v.wx, v.wy, v.ww, newHeight]; adjusted _ TRUE; }; }; ENDLOOP; IF update THEN { oldx: LIST OF Viewer _ cd.xBounded; oldy: LIST OF Viewer _ cd.yBounded; cd.xBounded _ cd.yBounded _ NIL; FOR l: LIST OF Viewer _ oldx, l.rest UNTIL l=NIL DO IF ~l.first.destroyed THEN cd.xBounded _ CONS[l.first, cd.xBounded]; ENDLOOP; FOR l: LIST OF Viewer _ oldy, l.rest UNTIL l=NIL DO IF ~l.first.destroyed THEN cd.yBounded _ CONS[l.first, cd.yBounded]; ENDLOOP; }; }; ContainerPaint: PaintProc = { }; ContainerSet: SetProc = { SELECT op FROM $YBound => ChildYBound[self, NARROW[data]]; $XBound => ChildXBound[self, NARROW[data]]; ENDCASE; }; ContainerGet: GetProc = { cd: ContainerData ~ NARROW[self.data]; IF cd#NIL THEN SELECT op FROM $YBound => RETURN[cd.yBounded]; $XBound => RETURN[cd.xBounded]; ENDCASE; RETURN[NIL]; }; ScrollOffset: PUBLIC PROC [container: Container] RETURNS [offTop: INTEGER] = { cd: ContainerData = NARROW[container.data]; IF cd = NIL THEN RETURN[0] ELSE RETURN[cd.scrolled]; }; ContainerInit: InitProc = { self.data _ NEW[ContainerDataRec]; }; containerClass: ViewerClasses.ViewerClass _ NEW[ViewerClasses.ViewerClassRec _ [ init: ContainerInit, paint: ContainerPaint, set: ContainerSet, get: ContainerGet, scroll: ContainerScroll, adjust: ContainerAdjust, topDownCoordSys: TRUE, icon: tool, bltV: top ]]; ViewerOps.RegisterViewerClass[$Container, containerClass]; -- plug in to Viewers END. ψContainersImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. McGregor, November 23, 1982 1:30 pm Maxwell, January 23, 1984 8:32:52 am PST Russ Atkinson, September 28, 1983 4:15 pm Doug Wyatt, April 16, 1985 5:59:59 pm PST Κ(– "Mesa" style˜codešœ™Kšœ Οmœ1™