ð 'Syntax10.Scn.Fntõtþÿÿ€8ÀÔFoldElemsNew#Syntax10.Scn.Fntjj VAR Menu, Main, SubFr: Display.Frame; M: Oberon.CopyMsg; BEGIN Menu:= V.dsc; Main:= V.dsc.next; SubFr:= V.dsc.next.next; NEW(V1); V1^:= V^; V1.state:= 0; M.F:= NIL; Menu.handle(Menu, M); V1.dsc:= M.F; M.F:= NIL; Main.handle(Main, M); V1.dsc.next:= M.F; M.F:= NIL; IF SubFr # NIL THEN SubFr.handle(SubFr, M); V1.dsc.next.next:= M.F; END; END Copy;ÿÿÿÿ€8ÀÔ&Ðþÿÿ€8ÀÔ#Syntax10.Scn.Fnt BEGIN Display.ReplConst(FrameColor, V.X, V.Y, 1, V.H, 0); Display.ReplConst(FrameColor, V.X + V.W - 1, V.Y, 1, V.H, 0); Display.ReplConst(FrameColor, V.X + 1, V.Y, V.W - 2, 1, 0); Display.ReplConst(FrameColor, V.X + 1, V.Y + V.H - 1, V.W - 2, 1, 0); END Draw;ÿÿÿÿ€8ÀÔ/Šþÿÿ€8ÀÔ#Syntax10.Scn.FntTT VAR dH: INTEGER; BEGIN dH := V.Y - newY; IF dH > 0 THEN Display.ReplConst(Display.black, V.X + 1, newY + 1, V.W - 2, dH, 0); Display.ReplConst(FrameColor, V.X, newY, 1, dH, 0); Display.ReplConst(FrameColor, V.X + V.W - 1, newY, 1, dH, 0); Display.ReplConst(FrameColor, V.X + 1, newY, V.W - 2, 1, 0); END; END Extend;ÿÿÿÿ€8ÀÔ/Šÿÿÿ€8ÀÔ#Syntax10.Scn.FntTT BEGIN Display.ReplConst(FrameColor, V.X + 1, newY, V.W - 2, 1, 0); END Reduce;ÿÿÿÿ€8ÀÔ-¿þÿÿ€8ÀÔ#Syntax10.Scn.Fnt VAR dH: INTEGER; BEGIN dH := V.H - oldH; IF dH > 0 THEN Display.ReplConst(FrameColor, V.X, V.Y + oldH, 1, dH, 0); Display.ReplConst(FrameColor, V.X + V.W - 1, V.Y + oldH, 1, dH, 0); Display.ReplConst(FrameColor, V.X + 1, V.Y + V.H - 1, V.W - 2, 1, 0); END; END Grow;ÿÿÿÿ€8ÀÔ/€ÿÿÿ€8ÀÔ#Syntax10.Scn.Fnt^^ BEGIN Display.ReplConst(FrameColor, V.X + 1, V.Y + newH - 1, V.W - 2, 1, 0); END Shrink;ÿÿÿÿ€8ÀÔ>?ÿÿÿ€8ÀÔ#Syntax10.Scn.FntŸŸ VAR M: MenuViewers.ModifyMsg; BEGIN M.id := id; M.dY := dY; M.Y := Y; M.H := H; IF F # NIL THEN F.handle(F, M); F.Y := Y; F.H := H; END; END Adjust;ÿÿÿÿ€8ÀÔ!üÿÿ€8ÀÔ#Syntax10.Scn.FntÎÎ VAR Menu, Main, SubFr: Display.Frame; BEGIN Menu := V.dsc; Main := V.dsc.next; SubFr:= V.dsc.next.next; Oberon.RemoveMarks(V.X, V.Y, V.W, V.H); Draw(V); IF V.mainW < MinW THEN V.mainW:= MinW; ELSIF V.mainW > MaxW THEN IF SubFr # NIL THEN V.mainW:= MaxW; ELSIF V.mainW > 100 THEN V.mainW:= 100; END; END; Menu.X := V.X + 1; Menu.Y := V.Y + V.H - 1; Menu.W := V.W - 2; Menu.H := 0; Main.X := V.X + 1; Main.Y := V.Y + V.H - V.menuH; Main.W := SHORT(LONG(Menu.W) * V.mainW DIV 100); Main.H := 0; IF SubFr # NIL THEN SubFr.X:= V.X + Main.W + 1; SubFr.Y:= V.Y + V.H - V.menuH; SubFr.W:= SHORT(LONG(Menu.W) * (100 - V.mainW) DIV 100) + 1; SubFr.H:= 0; END; IF V.H > V.menuH + 1 THEN Adjust(Menu, extend, 0, V.Y + V.H - V.menuH, V.menuH - 1); Adjust( Main, extend, 0, V.Y + 1, V.H - V.menuH - 1); Adjust(SubFr, extend, 0, V.Y + 1, V.H - V.menuH - 1); ELSE Adjust(Menu, extend, 0, V.Y + 1, V.H - 2); END; END Restore;ÿÿÿÿ€8ÀÔ/Iüÿÿ€8ÀÔ#Syntax10.Scn.Fnt•• VAR Menu, Main, SubFr: Display.Frame; BEGIN Menu := V.dsc; Main := V.dsc.next; SubFr:= V.dsc.next.next; IF Y < V.Y THEN (*extend*) Oberon.RemoveMarks(V.X, Y, V.W, V.Y - Y); Extend(V, Y); IF H > V.menuH + 1 THEN Adjust(Menu, extend, 0, Y + H - V.menuH, V.menuH - 1); Adjust(Main, extend, 0, Y + 1, H - V.menuH - 1); Adjust(SubFr, extend, 0, Y + 1, H - V.menuH - 1); ELSE Adjust(Menu, extend, 0, Y + 1, H - 2); END; ELSIF Y > V.Y THEN (*reduce*) Oberon.RemoveMarks(V.X, V.Y, V.W, V.H); IF H > V.menuH + 1 THEN Adjust(SubFr, reduce, 0, Y + 1, H - V.menuH - 1); Adjust(Main, reduce, 0, Y + 1, H - V.menuH - 1); Adjust(Menu, reduce, 0, Y + H - V.menuH, V.menuH - 1); ELSE Adjust(SubFr, reduce, 0, Y + H - V.menuH, 0); Adjust(Main, reduce, 0, Y + H - V.menuH, 0); Adjust(Menu, reduce, 0, Y + 1, H - 2); END ; Reduce(V, Y); END; END Modify;ÿÿÿÿ€8ÀÔ:\öÿÿ€8ÀÔ[Syntax10.Scn.Fnt!J VAR Menu, Main, SubFr: Display.Frame; V1: Viewers.Viewer; keysum: SET; Y0, dY, H: INTEGER; BEGIN (*Keys # {}*) Menu := V.dsc; Main := V.dsc.next; SubFr:= V.dsc.next.next; Oberon.DrawCursor(Oberon.Mouse, Oberon.Arrow, X, Y); Display.ReplConst(Display.white, V.X + 1, V.Y + V.H (*- 1*) - V.dsc.H, V.W - 2, V.dsc.H, 2); Y0 := Y; keysum := Keys; LOOP Input.Mouse(Keys, X, Y); IF Keys = {} THEN EXIT END ; keysum := keysum + Keys; Oberon.DrawCursor(Oberon.Mouse, Oberon.Arrow, X, Y) END ; Display.ReplConst(Display.white, V.X + 1, V.Y + V.H (*- 1*) - V.dsc.H, V.W - 2, V.dsc.H, 2); IF ~(leftKey IN keysum) THEN IF middleKey IN keysum THEN V1 := Viewers.This(X, Y); IF (V1 IS Viewer) & (Y > V1.Y + V1.H - V1(Viewer).menuH - 2) THEN Y := V1.Y + V1.H END ; IF Y < V1.Y + V.menuH + 2 THEN Y := V1.Y + V.menuH + 2 END ; Viewers.Close(V); Viewers.Open(V, X, Y); Restore(V) ELSE IF Y > Y0 THEN (*extend*) dY := Y - Y0; V1 := Viewers.Next(V); IF V1.state > 1 THEN IF V1 IS MenuViewers.Viewer THEN IF V1.H < V1(MenuViewers.Viewer).menuH + 2 THEN dY := 0 ELSIF V1.H < V1(MenuViewers.Viewer).menuH + 2 + dY THEN dY := V1.H - V1(MenuViewers.Viewer).menuH - 2 END ELSIF V1.H < 1 + dY THEN dY := V1.H - 1 END ELSIF V1.H < dY THEN dY := V1.H END ; Viewers.Change(V, V.Y + V.H + dY); Oberon.RemoveMarks(V.X, V.Y, V.W, V.H); Grow(V, V.H - dY); IF V.H > V.menuH + 1 THEN Adjust(Menu, extend, dY, V.Y + V.H - V.menuH, V.menuH - 1); Adjust(Main, extend, dY, V.Y + 1, V.H - V.menuH - 1); Adjust(SubFr, extend, dY, V.Y + 1, V.H - V.menuH - 1); ELSE(*V.H > 1*) Adjust(Menu, extend, dY, V.Y + 1, V.H - 2); Adjust(Main, extend, dY, V.Y + V.H - V.menuH, 0); Adjust(SubFr, extend, dY, V.Y + V.H - V.menuH, 0); END ELSIF Y < Y0 THEN (*reduce*) dY := Y0 - Y; IF V.H >= V.menuH + 2 THEN IF V.H < V.menuH + 2 + dY THEN dY := V.H - V.menuH - 2 END ; Oberon.RemoveMarks(V.X, V.Y, V.W, V.H); H := V.H - dY; Adjust(SubFr, reduce, dY, V.Y + 1, H - V.menuH - 1); Adjust(Main, reduce, dY, V.Y + 1, H - V.menuH - 1); Adjust(Menu, reduce, dY, V.Y + H - V.menuH, V.menuH - 1); Shrink(V, H); Viewers.Change(V, V.Y + H) END END END END END Change;ÿÿÿÿ€8ÀÔ!Ðþÿÿ€8ÀÔ#Syntax10.Scn.Fnt VAR Menu, Main, SubFr: Display.Frame; BEGIN Menu := V.dsc; Main := V.dsc.next; SubFr:= V.dsc.next.next; Adjust(SubFr, reduce, 0, V.Y + V.H - V.menuH, 0); Adjust(Main, reduce, 0, V.Y + V.H - V.menuH, 0); Adjust(Menu, reduce, 0, V.Y + V.H - 1, 0) END Suspend;ÿÿÿÿ€8ÀÔAñõÿÿ€8ÀÔ1Syntax10.Scn.Fnt\ y ß VAR Menu, Main, SubFr: Display.Frame; V1: Viewer; x, y: INTEGER; keys: SET; BEGIN WITH V: Viewer DO Ancestor:= V; Menu := V.dsc; Main := V.dsc.next; SubFr:= V.dsc.next.next; WITH M: Oberon.InputMsg DO IF M.id = Oberon.track THEN IF M.Y < V.Y + 1 THEN Oberon.DrawCursor(Oberon.Mouse, Oberon.Arrow, M.X, M.Y); ELSIF M.Y < V.Y + V.H - V.menuH THEN IF M.X < Main.X + Main.W THEN Main.handle(Main, M); ELSIF (SubFr # NIL) THEN WITH SubFr: TextFrames.Frame DO IF M.X < Main.X + Main.W + SubFr(TextFrames.Frame).barW THEN (* scroll bar *) SubFr.handle(SubFr, M); IF middleKey IN M.keys THEN Input.Mouse(keys, x, y); IF (x < SubFr.X) OR (x > SubFr.X + SubFr(TextFrames.Frame).barW) THEN x:= SHORT(LONG(x) * 100 DIV (Main.W + SubFr.W)); IF x > 100 THEN V.mainW:= 100 ELSE V.mainW:= SHORT(x); END; Viewers.Close(V); Viewers.Open(V, V.X, V.H + V.Y); Restore(V); END; END; ELSE SubFr.handle(SubFr, M); END; ELSE END; (* WITH *) END; ELSIF M.Y < V.Y + V.H - V.menuH + 2 THEN Menu.handle(Menu, M); ELSIF M.Y < V.Y + V.H - 1 THEN IF 2 IN M.keys THEN Change(V, M.X, M.Y, M.keys); ELSE Menu.handle(Menu, M); END; ELSE Oberon.DrawCursor(Oberon.Mouse, Oberon.Arrow, M.X, M.Y) END ELSE (* M.id # Oberon.track *) Menu.handle(Menu, M); Main.handle(Main, M); IF SubFr # NIL THEN SubFr.handle(SubFr, M); END; END; | M: Oberon.ControlMsg DO IF M.id = Oberon.mark THEN Oberon.DrawCursor(Oberon.Mouse, Oberon.Arrow, M.X, M.Y); Oberon.DrawCursor(Oberon.Pointer, Oberon.Star, M.X, M.Y) ELSE Menu.handle(Menu, M); Main.handle(Main, M); IF SubFr # NIL THEN SubFr.handle(SubFr, M); END; END; | M: TextFrames.UpdateMsg DO Main.handle(Main, M); IF SubFr # NIL THEN SubFr.handle(SubFr, M); END; IF (SubFr = NIL) OR (SubFr IS TextFrames.Frame) & (M.text # SubFr (TextFrames.Frame).text) THEN Menu.handle(Menu, M); END; | M: Oberon.CopyMsg DO Copy(V(Viewer), V1); M.F := V1; | M: Viewers.ViewerMsg DO IF M.id = Viewers.restore THEN Restore(V); ELSIF M.id = Viewers.modify THEN Modify(V, M.Y, M.H); ELSIF M.id = Viewers.suspend THEN Suspend(V); END; ELSE Menu.handle(Menu, M); Main.handle(Main, M); IF SubFr # NIL THEN SubFr.handle(SubFr, M); END; END; END; END Handle;ÿÿÿÿ€8ÀÔŠàþÿÿ€8ÀÔ#Syntax10.Scn.Fntþþ VAR V: Viewer; BEGIN NEW(V); V.handle:= Handle; V.dsc:= Menu; V.dsc.next:= Main; V.dsc.next.next:= SubFr; V.menuH:= menuH; IF SubFr # NIL THEN V.mainW:= 75; ELSE V.mainW:= 100; END; Viewers.Open(V, X, Y); Restore(V); RETURN V; END New;ÿÿÿÿ€8ÀÔCæMODULE HierViewers; (* EK 98 *) IMPORT Input, Display, Viewers, Oberon, MenuViewers, TextFrames; CONST extend* = 0; reduce* = 1; FrameColor = 15; leftKey= 0; middleKey= 1; rightKey= 2; MinW*= 10; MaxW*= 90; (* min; max width of main-frame (left frame) [%] *) TYPE Viewer* = POINTER TO ViewerDesc; ViewerDesc* = RECORD (MenuViewers.ViewerDesc) mainW*: SHORTINT; (* default width of main-frame [%] *) END ; VAR Ancestor*: Viewer; PROCEDURE Copy (V: Viewer; VAR V1: Viewer); PROCEDURE Draw (V: Viewers.Viewer); PROCEDURE Extend (V: Viewer; newY: INTEGER); PROCEDURE Reduce (V: Viewer; newY: INTEGER); PROCEDURE Grow (V: Viewer; oldH: INTEGER); PROCEDURE Shrink (V: Viewer; newH: INTEGER); PROCEDURE Adjust (F: Display.Frame; id, dY, Y, H: INTEGER); PROCEDURE Restore (V: Viewer); PROCEDURE Modify (V: Viewer; Y, H: INTEGER); PROCEDURE Change (V: Viewer; X, Y: INTEGER; Keys: SET); PROCEDURE Suspend (V: Viewer); PROCEDURE Handle* (V: Display.Frame; VAR M: Display.FrameMsg); (* SubFr is NIL: the behaviour is like MenuViewers *) PROCEDURE New* (Menu, Main, SubFr: Display.Frame; menuH, X, Y: INTEGER): Viewer; END HierViewers. for an application see: Edit.Open HierEdit.Mod