(FILECREATED " 2-Jan-85 08:38:52" {ERIS}<LISPCORE>LIBRARY>GRAPHER.;26 105119 changes to: (FNS GN/RIGHT GN/TOP RESET/NODE/BORDER MAX/RIGHT MIN/BOTTOM MAX/TOP MIN/LEFT EDITTOGGLEBORDER SHOWGRAPH DEFAULTGRAPHERCOPYBUTTONEVENTFN PRINTDISPLAYNODE) (VARS GRAPHERCOMS) previous date: "11-Dec-84 14:36:38" {PHYLUM}<VANLEHN>LISP>GRAPHER.;8) (* Copyright (c) 1983, 1984, 1985 by Xerox Corporation. All rights reserved.) (PRETTYCOMPRINT GRAPHERCOMS) (RPAQQ GRAPHERCOMS ((FNS ADD/AND/DISPLAY/LINK APPLYTOSELECTEDNODE CALL.MOVENODEFN CHANGE.NODEFONT.SIZE CHOOSE.GRAPH.FONT CLOSEST/NODE DEFAULT.ADDNODEFN DELETE/AND/DISPLAY/LINK DISPLAY/NAME DISPLAYGRAPH DISPLAYLINK DISPLAYLINK/LR DISPLAYLINK/TB EDITTOGGLEBORDER ERASE/GRAPHNODE DISPLAYNODE DISPLAYNODELINKS DRAW/GRAPHNODE/BORDER DRAWAREABOX EDITADDLINK EDITADDNODE EDITAPPLYTOLINK EDITCHANGEFONT EDITDELETELINK EDITDELETENODE EDITGRAPH EDITGRAPH1 EDITGRAPHMENU EDITMOVENODE EDITTOGGLELABEL FLIPNODE FONTNAMELIST FROMLINKS GETNODEFROMID GN/BOTTOM GN/LEFT GN/RIGHT GN/TOP GRAPHADDLINK GRAPHADDNODE GRAPHDELETELINK GRAPHDELETENODE GRAPHEDITCOMMANDFN GRAPHEDITEVENTFN GRAPHER/CENTERPRINTINAREA GRAPHMOVENODE GRAPHNODE/BORDER/WIDTH GRAPHREGION HARDCOPYGRAPH INTERSECT/REGIONP/LBWH INVERTED/GRAPHNODE/BORDER INVERTED/SHADE/FOR/GRAPHER LAYOUT/POSITION MANHATTANDIST MAX/RIGHT MAX/TOP MEASUREGRAPHNODE MIN/BOTTOM MIN/LEFT MOVENODE NODECREATE NODELST/AS/MENU NODEREGION PRINTDISPLAYNODE FILL/GRAPHNODE/LABEL PROMPTINWINDOW READ/NODE REDISPLAYGRAPH RESET/NODE/BORDER RESET/NODE/LABELSHADE SCALE/GRAPH SCALE/GRAPHNODE/BORDER SET/LABEL/SIZE SET/LAYOUT/POSITION SHIFTP SHOWGRAPH SIZE/GRAPH/WINDOW TOGGLE/DIRECTEDFLG TOGGLE/SIDESFLG TOLINKS TRACKCURSOR TRACKNODE) [COMS (FNS DEFAULTGRAPHERCOPYBUTTONEVENTFN) (* For shift-selecting without GRAPHEROBJs) (P (MOVD? (QUOTE DEFAULTGRAPHERCOPYBUTTONEVENTFN) (QUOTE GRAPHERCOPYBUTTONEVENTFN] (COMS (* functions for finding larger and smaller fonts) (FNS NEXTSIZEFONT DECREASING.FONT.LIST SCALE.FONT) [DECLARE: DONTEVAL@LOAD DOCOPY (VARS (DECREASING.FONT.LIST (DECREASING.FONT.LIST] (GLOBALVARS DECREASING.FONT.LIST)) (* functions for LAYOUTGRAPH And LAYOUTLATTICE) (FNS BRH/LAYOUT BRH/LAYOUT/DAUGHTERS BRH/OFFSET BRHC/INTERTREE/SPACE BRHC/LAYOUT BRHC/LAYOUT/DAUGHTERS BRHC/LAYOUT/TERMINAL BRHC/OFFSET BRHL/LAYOUT BRHL/LAYOUT/DAUGHTERS BRHL/MOVE/RIGHT BROWSE/LAYOUT/HORIZ BROWSE/LAYOUT/HORIZ/COMPACTLY BROWSE/LAYOUT/LATTICE BRV/OFFSET EXTEND/TRANSITION/CHAIN FOREST/BREAK/CYCLES INIT/NODES/FOR/LAYOUT INTERPRET/MARK/FORMAT LATTICE/BREAK/CYCLES LAYOUTFOREST LAYOUTGRAPH LAYOUTLATTICE LAYOUTSEXPR LAYOUTSEXPR1 MARK/GRAPH/NODE NEW/INSTANCE/OF/GRAPHNODE RAISE/TRANSITION/CHAIN REFLECT/GRAPH/DIAGONALLY REFLECT/GRAPH/HORIZONTALLY REFLECT/GRAPH/VERTICALLY SWITCH/NODE/HEIGHT/WIDTH) (VARS DEFAULT.GRAPH.NODEBORDER DEFAULT.GRAPH.NODEFONT DEFAULT.GRAPH.NODELABELSHADE ( CACHE/NODE/LABEL/BITMAPS) (EDITGRAPHMENU) (GRAPHEDITWINDOW) (NODEBORDERWIDTH 1) (ORIGIN (CREATEPOSITION 0 0))) (P (MOVD? (FUNCTION NILL) (FUNCTION IMAGEOBJP) T)) (LOCALVARS . T) (GLOBALVARS EDITGRAPHMENU GRAPHEDITWINDOW NODEBORDERWIDTH ORIGIN) (RECORDS GRAPHNODE GRAPH) (DECLARE: DONTCOPY (MACROS HALF)))) (DEFINEQ (ADD/AND/DISPLAY/LINK [LAMBDA (FROMND TOND WIN G) (* rmk: "10-Apr-84 12:36") (* adds and displays a link.) (COND ((MEMB (fetch NODEID of TOND) (TOLINKS FROMND)) (PRIN1 " link already exists. " T) (TERPRI T) NIL) (T (GRAPHADDLINK FROMND TOND G WIN) (DISPLAYLINK FROMND TOND (CONSTANT (create POSITION XCOORD ← 0 YCOORD ← 0)) WIN G) T]) (APPLYTOSELECTEDNODE [LAMBDA (WINDOW) (* kvl " 3-MAY-82 20:45") (* applys a function whenever the node is selected. Is used as BUTTONEVENTFN and gets called whenever cursor moves or button is down.) (PROG ((LEFTFNOFNODE (WINDOWPROP WINDOW (QUOTE BROWSER/LEFTFN))) (MIDDLEFNOFNODE (WINDOWPROP WINDOW (QUOTE BROWSER/MIDDLEFN))) [NODELST (fetch (GRAPH GRAPHNODES) of (WINDOWPROP WINDOW (QUOTE GRAPH] (DS (WINDOWPROP WINDOW (QUOTE DSP))) BUTTON OLDPOS REG NOW NEAR) (* note which button is down.) (TOTOPW WINDOW) (COND ((LASTMOUSESTATE LEFT) (OR LEFTFNOFNODE (RETURN)) (SETQ BUTTON (QUOTE LEFT))) ((LASTMOUSESTATE MIDDLE) (OR MIDDLEFNOFNODE (RETURN)) (SETQ BUTTON (QUOTE MIDDLE))) (T (* no button down, not interested.) (RETURN))) (* get the region of this window.) (SETQ REG (WINDOWPROP WINDOW (QUOTE REGION))) [SETQ NEAR (NODELST/AS/MENU NODELST (SETQ OLDPOS (CURSORPOSITION NIL DS] FLIP(AND NOW (FLIPNODE NOW DS)) (AND NEAR (FLIPNODE NEAR DS)) (SETQ NOW NEAR) LP (* wait for a button up or move out of region) (GETMOUSESTATE) (COND ((NOT (LASTMOUSESTATE (OR LEFT MIDDLE))) (* button up, process it.) (AND NOW (FLIPNODE NOW DS)) (* NOW node has been selected.) (RETURN (APPLY* (SELECTQ BUTTON (LEFT LEFTFNOFNODE) (MIDDLE MIDDLEFNOFNODE) (SHOULDNT)) NOW WINDOW))) ((NOT (INSIDE? (WINDOWPROP WINDOW (QUOTE REGION)) LASTMOUSEX LASTMOUSEY)) (* outside of region, return) (AND NOW (FLIPNODE NOW DS)) (RETURN)) ([EQ NOW (SETQ NEAR (NODELST/AS/MENU NODELST (CURSORPOSITION NIL DS OLDPOS] (GO LP)) (T (GO FLIP]) (CALL.MOVENODEFN [LAMBDA (NODE NEWPOS GRAPH WINDOW) (* rrb " 1-NOV-83 12:02") (* calls a graphs movenodefn.) (PROG ((MOVEFN (fetch (GRAPH GRAPH.MOVENODEFN) of GRAPH))) (AND MOVEFN (APPLY* MOVEFN NODE NEWPOS GRAPH WINDOW]) (CHANGE.NODEFONT.SIZE [LAMBDA (HOW NODE GRAPH WINDOW) (* kvl "20-Aug-84 10:36") (* makes the label font of a node larger.) (PROG [(NEWFONT (NEXTSIZEFONT HOW (fetch (GRAPHNODE NODEFONT) of NODE] (COND (NEWFONT (DISPLAYNODE NODE (CONSTANT (create POSITION XCOORD ← 0 YCOORD ← 0)) WINDOW GRAPH) (PROG ((CHNGFN (fetch (GRAPH GRAPH.FONTCHANGEFN) of GRAPH))) (AND CHNGFN (APPLY* CHNGFN HOW NODE GRAPH WINDOW))) (replace (GRAPHNODE NODEFONT) of NODE with NEWFONT) (replace (GRAPHNODE NODEWIDTH) of NODE with NIL) (replace (GRAPHNODE NODEHEIGHT) of NODE with NIL) (MEASUREGRAPHNODE NODE) (DISPLAYNODE NODE (CONSTANT (create POSITION XCOORD ← 0 YCOORD ← 0)) WINDOW GRAPH]) (CHOOSE.GRAPH.FONT [LAMBDA (GRAPH) (* rrb " 1-NOV-83 11:57") (* picks a font for a new node in a graph) (* for now use the same font as the first node.) (fetch (GRAPHNODE NODEFONT) of (CAR (fetch (GRAPH GRAPHNODES) of GRAPH]) (CLOSEST/NODE [LAMBDA (NODELST POS) (* rmk: " 2-Feb-84 22:35") (* finds the node that is closest to POS) (PROG (CLOSEST (MINDIST 65000) DIST) LP (COND ((NULL NODELST) (RETURN CLOSEST)) ((IGREATERP MINDIST (SETQ DIST (MANHATTANDIST (fetch NODEPOSITION of (CAR NODELST)) POS))) (SETQ CLOSEST (CAR NODELST)) (SETQ MINDIST DIST))) (SETQ NODELST (CDR NODELST)) (GO LP]) (DEFAULT.ADDNODEFN [LAMBDA (GRAPH WINDOW BOXED FONT) (* rrb " 2-NOV-83 20:29") (* reads a node label name from the user and puts a node at the current cursor position.) (PROG (NODELABEL NODENAME) (SETQ NODELABEL (PROMPTINWINDOW "Node label? ")) LP (COND ((FASSOC (SETQ NODENAME (PACK* NODELABEL (GENSYM))) (fetch (GRAPH GRAPHNODES) of GRAPH)) (GO LP))) (RETURN (NODECREATE NODENAME NODELABEL (CURSORPOSITION NIL WINDOW) NIL NIL (OR FONT (CHOOSE.GRAPH.FONT GRAPH)) BOXED]) (DELETE/AND/DISPLAY/LINK [LAMBDA (FROMND TOND WIN G) (* rmk: "10-Apr-84 12:38") (* delete a link and updates the display.) (COND ([NOT (OR (MEMB (fetch NODEID of TOND) (TOLINKS FROMND)) (AND (MEMB (fetch NODEID of FROMND) (TOLINKS TOND)) (NOT (fetch (GRAPH DIRECTEDFLG) of G)) (PROG ((TMP FROMND)) (* editting graph, don't distinguish between links.) (SETQ FROMND TOND) (SETQ TOND TMP) (RETURN T] (PRIN1 " link does not exist. " T) (TERPRI T) NIL) (T (GRAPHDELETELINK FROMND TOND G WIN) (DISPLAYLINK FROMND TOND (CONSTANT (create POSITION XCOORD ← 0 YCOORD ← 0)) WIN G) T]) (DISPLAY/NAME [LAMBDA (ND) (* rrb "13-JUL-81 10:56") (fetch NODELABEL of ND]) (DISPLAYGRAPH [LAMBDA (GRAPH STREAM CLIP/REG TRANS) (* rmk: "27-Aug-84 10:04") (* Displays GRAPH with coordinates system translated to TRANS on STREAM. POS=NIL is interpreted as 0,0. Draws links first then labels so that lattices don't have lines through the labels.) (PROG (SCALE (LINEWIDTH 1)) [OR (type? POSITION TRANS) (SETQ TRANS (CONSTANT (create POSITION XCOORD ← 0 YCOORD ← 0] (SETQ STREAM (\GETSTREAM STREAM (QUOTE OUTPUT))) (COND ((DISPLAYSTREAMP STREAM) (* This is because PRIN3 on displaystreams can sometimes cause CR's to be output. GRAPHER/CENTERPRINTINAREA doesn't have the rightmargin kludge that the CENTERPRINTINAREA in MENU has.) (DSPRIGHTMARGIN 65000 STREAM)) (T (SETQ SCALE (DSPSCALE NIL STREAM)) (SETQ GRAPH (SCALE/GRAPH GRAPH STREAM SCALE)) [SETQ TRANS (create POSITION XCOORD ←(FIXR (FTIMES SCALE (fetch XCOORD of TRANS))) YCOORD ←(FIXR (FTIMES SCALE (fetch YCOORD of TRANS] (SETQ LINEWIDTH SCALE))) (for N in (fetch (GRAPH GRAPHNODES) of GRAPH) do (DISPLAYNODELINKS N TRANS STREAM GRAPH T LINEWIDTH)) (for N in (fetch (GRAPH GRAPHNODES) of GRAPH) do (PRINTDISPLAYNODE N TRANS STREAM CLIP/REG]) (DISPLAYLINK [LAMBDA (FRND TOND TRANS STREAM G LINEWIDTH) (* kvl "15-Aug-84 10:12") (* draws in a link from FRND TO TOND, translated by TRANS) (OR LINEWIDTH (SETQ LINEWIDTH 1)) (COND ((fetch (GRAPH SIDESFLG) of G) (COND ((OR (fetch (GRAPH DIRECTEDFLG) of G) (IGREATERP (GN/LEFT TOND) (GN/RIGHT FRND))) (* in the horizontal case of LATTICE, always draw from right to left.) (DISPLAYLINK/LR TRANS TOND FRND LINEWIDTH NIL STREAM)) ((IGREATERP (GN/LEFT FRND) (GN/RIGHT TOND)) (DISPLAYLINK/LR TRANS FRND TOND LINEWIDTH NIL STREAM)) ((IGREATERP (GN/BOTTOM FRND) (GN/TOP TOND)) (DISPLAYLINK/TB TRANS TOND FRND LINEWIDTH NIL STREAM)) ((IGREATERP (GN/BOTTOM TOND) (GN/TOP FRND)) (DISPLAYLINK/TB TRANS FRND TOND LINEWIDTH NIL STREAM)) (T (* if on top of each other, don't draw.) NIL))) (T (COND ((OR (fetch (GRAPH DIRECTEDFLG) of G) (IGREATERP (GN/BOTTOM FRND) (GN/TOP TOND))) (* if LATTICE, always draw from FROMNODE BOTTOM to TONODE TOP. Otherwise find the one that looks best.) (DISPLAYLINK/TB TRANS TOND FRND LINEWIDTH NIL STREAM)) ((IGREATERP (GN/BOTTOM TOND) (GN/TOP FRND)) (DISPLAYLINK/TB TRANS FRND TOND LINEWIDTH NIL STREAM)) ((IGREATERP (GN/LEFT TOND) (GN/RIGHT FRND)) (DISPLAYLINK/LR TRANS TOND FRND LINEWIDTH NIL STREAM)) ((IGREATERP (GN/LEFT FRND) (GN/RIGHT TOND)) (DISPLAYLINK/LR TRANS FRND TOND LINEWIDTH NIL STREAM)) (T (* if on top of each other, don't draw.) NIL]) (DISPLAYLINK/LR [LAMBDA (TRANS GNL GNR WIDTH OPERATION STREAM COLOR) (* rmk: "17-Aug-84 10:18") (* draws a line from the left edge of GNL to the right edge of GNR, translated by TRANS) (DRAWLINE (IPLUS (fetch XCOORD of TRANS) (SUB1 (GN/LEFT GNL))) (IPLUS (fetch YCOORD of TRANS) (fetch YCOORD of (fetch NODEPOSITION of GNL))) (IPLUS (fetch XCOORD of TRANS) (ADD1 (GN/RIGHT GNR))) (IPLUS (fetch YCOORD of TRANS) (fetch YCOORD of (fetch NODEPOSITION of GNR))) WIDTH OPERATION STREAM COLOR]) (DISPLAYLINK/TB [LAMBDA (TRANS GNT GNB WIDTH OPERATION STREAM COLOR) (* rmk: "17-Aug-84 10:16") (* draws a line from the top edge of GNT to the bottom edge of GNR, translated by TRANS) (DRAWLINE (IPLUS (fetch XCOORD of TRANS) (fetch XCOORD of (fetch NODEPOSITION of GNT))) (IPLUS (fetch YCOORD of TRANS) (ADD1 (GN/TOP GNT))) (IPLUS (fetch XCOORD of TRANS) (fetch XCOORD of (fetch NODEPOSITION of GNB))) (IPLUS (fetch YCOORD of TRANS) (SUB1 (GN/BOTTOM GNB))) WIDTH OPERATION STREAM COLOR]) (EDITTOGGLEBORDER [LAMBDA (W) (* rmk: "14-Dec-84 13:50") (* prompts the user for a node and inverts its border) (RESETFORM (TTYDISPLAYSTREAM PROMPTWINDOW) (CLRPROMPT) (PROG ((GRAPH (WINDOWPROP W (QUOTE GRAPH))) (DS (WINDOWPROP W (QUOTE DSP))) NODE) (COND ((NOT (fetch (GRAPH GRAPHNODES) of GRAPH)) (PROMPTPRINT " No nodes to invert. ") (RETURN))) (PROMPTPRINT " Select node to have border inverted. ") (SETQ NODE (READ/NODE (fetch (GRAPH GRAPHNODES) of GRAPH) DS)) (TERPRI T) (RESET/NODE/BORDER NODE (QUOTE INVERT) W GRAPH) (AND (fetch (GRAPH GRAPH.INVERTBORDERFN) of GRAPH) (APPLY* (fetch (GRAPH GRAPH.INVERTBORDERFN) of GRAPH) NODE GRAPH W)) (printout T "Node " (fetch NODELABEL of NODE) " inverted." T) (RETURN NODE]) (ERASE/GRAPHNODE [LAMBDA (NODE STREAM TRANS) (* kvl " 5-Sep-84 18:22") (* erases a node at its position translated by TRANS) (OR [NOT (OR (WINDOWP STREAM) (IMAGESTREAMTYPEP STREAM (QUOTE DISPLAY] (ZEROP (fetch (GRAPHNODE NODEHEIGHT) of NODE)) (NULL (fetch NODEFONT of NODE)) (BITBLT NIL NIL NIL STREAM (COND (TRANS (IPLUS (fetch XCOORD of TRANS) (GN/LEFT NODE))) (T (GN/LEFT NODE))) (COND (TRANS (IPLUS (fetch YCOORD of TRANS) (GN/BOTTOM NODE))) (T (GN/BOTTOM NODE))) (fetch NODEWIDTH of NODE) (fetch NODEHEIGHT of NODE) (QUOTE TEXTURE) (QUOTE REPLACE) WHITESHADE]) (DISPLAYNODE [LAMBDA (NODE TRANS STREAM G TOSONLY) (* kvl "10-Aug-84 19:08") (* displays a node and its links. IF TOSONLY IS NON-NIL, DRAWS ONLY THE TO LINKS.) (DISPLAYNODELINKS NODE TRANS STREAM G TOSONLY) (PRINTDISPLAYNODE NODE TRANS STREAM (DSPCLIPPINGREGION NIL STREAM]) (DISPLAYNODELINKS [LAMBDA (NODE TRANS STREAM G TOSONLY LINEWIDTH) (* kvl "15-Aug-84 10:12") (* displays a node links. IF TOSONLY IS NON-NIL, DRAWS ONLY THE TO LINKS.) (PROG ((NODELST (fetch (GRAPH GRAPHNODES) of G))) (for TONODEID in (TOLINKS NODE) do (DISPLAYLINK NODE (GETNODEFROMID TONODEID NODELST) TRANS STREAM G LINEWIDTH)) (OR TOSONLY (for FROMNDID in (FROMLINKS NODE) do (DISPLAYLINK (GETNODEFROMID FROMNDID NODELST) NODE TRANS STREAM G LINEWIDTH] ) (DRAW/GRAPHNODE/BORDER [LAMBDA (BORDER LEFT BOTTOM WIDTH HEIGHT STREAM) (* kvl "11-Dec-84 13:58") (* interprets the node border. If the border is a shade, then bitblt twice in invert mode. This will look ugly if a link runs underneath the node, but at least the label will be legible.) (COND ((EQ BORDER NIL)) ((EQ BORDER T) (DRAWAREABOX LEFT BOTTOM WIDTH HEIGHT 1 NIL STREAM)) ((FIXP BORDER) (OR (ILEQ BORDER 0) (DRAWAREABOX LEFT BOTTOM WIDTH HEIGHT BORDER NIL STREAM))) [(LISTP BORDER) (AND (OR (WINDOWP STREAM) (IMAGESTREAMTYPEP STREAM (QUOTE DISPLAY))) (PROG ((NBW (GRAPHNODE/BORDER/WIDTH BORDER))) (BITBLT NIL NIL NIL STREAM LEFT BOTTOM WIDTH HEIGHT (QUOTE TEXTURE) (QUOTE INVERT) (CADR BORDER)) (BITBLT NIL NIL NIL STREAM (IPLUS LEFT NBW) (IPLUS BOTTOM NBW) (IDIFFERENCE WIDTH (IPLUS NBW NBW)) (IDIFFERENCE HEIGHT (IPLUS NBW NBW)) (QUOTE TEXTURE) (QUOTE INVERT) (CADR BORDER] (T (ERROR "Illegal border:" BORDER]) (DRAWAREABOX [LAMBDA (LEFT BOTTOM WIDTH HEIGHT BORDER OP W) (* kvl " 5-Sep-84 17:27") (* draws lines inside the region.) (PROG (BIG/HALF SM/HALF VERTLEFT VERTRIGHT HORIZTOP HORIZBOTTOM HORIZLEFT HORIZRIGHT) (SETQ BIG/HALF (IQUOTIENT BORDER 2)) (SETQ SM/HALF (IQUOTIENT (SUB1 BORDER) 2)) (* draw left edge) (SETQ VERTLEFT (IPLUS LEFT SM/HALF)) (SETQ HORIZTOP (IPLUS BOTTOM HEIGHT -1)) (DRAWLINE VERTLEFT BOTTOM VERTLEFT HORIZTOP BORDER OP W) (* draw top) (SETQ HORIZTOP (IDIFFERENCE HORIZTOP BIG/HALF)) (DRAWLINE (SETQ HORIZLEFT (IPLUS LEFT BORDER)) HORIZTOP (SETQ HORIZRIGHT (IDIFFERENCE (IPLUS LEFT WIDTH -1) BORDER)) HORIZTOP BORDER OP W) (* draw right edge) (SETQ VERTRIGHT (IDIFFERENCE (IPLUS LEFT WIDTH -1) BIG/HALF)) (DRAWLINE VERTRIGHT BOTTOM VERTRIGHT (IPLUS BOTTOM HEIGHT -1) BORDER OP W) (* draw bottom) (SETQ HORIZBOTTOM (IPLUS BOTTOM SM/HALF)) (DRAWLINE HORIZLEFT HORIZBOTTOM HORIZRIGHT HORIZBOTTOM BORDER OP W]) (EDITADDLINK [LAMBDA (W) (* kvl "20-APR-82 13:53") (* reads and adds a link to the graph) (EDITAPPLYTOLINK (FUNCTION ADD/AND/DISPLAY/LINK) (QUOTE added) (WINDOWPROP W (QUOTE GRAPH)) W]) (EDITADDNODE [LAMBDA (W) (* kvl "10-Aug-84 19:06") (* adds a node to the graph in the window W and displays it.) (PROG [NODE (GRAPH (WINDOWPROP W (QUOTE GRAPH] (OR (SETQ NODE (GRAPHADDNODE GRAPH W)) (RETURN)) (MEASUREGRAPHNODE NODE) (printout PROMPTWINDOW T "Position node " (DISPLAY/NAME NODE)) (PRINTDISPLAYNODE NODE (CONSTANT (create POSITION XCOORD ← 0 YCOORD ← 0)) W (DSPCLIPPINGREGION NIL W)) (TRACKCURSOR NODE (WINDOWPROP W (QUOTE DSP)) GRAPH) (RETURN NODE]) (EDITAPPLYTOLINK [LAMBDA (FN MSG GRAPH DS) (* kvl "20-APR-82 14:29") (RESETFORM (TTYDISPLAYSTREAM PROMPTWINDOW) (COND [(fetch (GRAPH GRAPHNODES) of GRAPH) (PROG (FROM TO) (printout T "Specify the link by selecting the FROM node, then the TO node." T) (PRIN1 "FROM?" T) (SETQ FROM (READ/NODE (fetch (GRAPH GRAPHNODES) of GRAPH) DS)) (CLRPROMPT) (FLIPNODE FROM DS) (PRIN1 "TO?" T) [SETQ TO (COND [(CAR (ERSETQ (READ/NODE (fetch (GRAPH GRAPHNODES) of GRAPH) DS] (T (FLIPNODE FROM DS) (ERROR!] (CLRPROMPT) (FLIPNODE FROM DS) (COND ((APPLY* FN FROM TO DS GRAPH) (* return non-nil if changed anything.) (printout T "Link from " (DISPLAY/NAME FROM) " to " (DISPLAY/NAME TO) , MSG T] (T (TERPRI T) (PRINT "There are no nodes. You can create nodes with the Add Node command." T]) (EDITCHANGEFONT [LAMBDA (HOW W) (* rrb " 2-NOV-83 21:26") (* prompts the user for a node and deletes it) (PROG ((GRAPH (WINDOWPROP W (QUOTE GRAPH))) (DS (WINDOWPROP W (QUOTE DSP))) NODE) (COND ((NOT (fetch (GRAPH GRAPHNODES) of GRAPH)) (PROMPTPRINT " No nodes yet. ") (RETURN))) (printout PROMPTWINDOW T " Select node to be made " (COND ((EQ HOW (QUOTE SMALLER)) "smaller.") (T "larger."))) (SETQ NODE (READ/NODE (fetch (GRAPH GRAPHNODES) of GRAPH) DS)) (AND NODE (CHANGE.NODEFONT.SIZE HOW NODE GRAPH W]) (EDITDELETELINK [LAMBDA (W) (* kvl "20-APR-82 13:54") (* reads and adds a link to the graph) (EDITAPPLYTOLINK (FUNCTION DELETE/AND/DISPLAY/LINK) (QUOTE deleted) (WINDOWPROP W (QUOTE GRAPH)) W]) (EDITDELETENODE [LAMBDA (W) (* rmk: "10-Apr-84 12:33") (* prompts the user for a node and deletes it) (RESETFORM (TTYDISPLAYSTREAM PROMPTWINDOW) (CLRPROMPT) (PROG ((GRAPH (WINDOWPROP W (QUOTE GRAPH))) (DS (WINDOWPROP W (QUOTE DSP))) NODE NODELABEL) (COND ((NOT (fetch (GRAPH GRAPHNODES) of GRAPH)) (PROMPTPRINT " No nodes to delete. ") (RETURN))) (PROMPTPRINT " Select node to be deleted. ") (SETQ NODE (READ/NODE (fetch (GRAPH GRAPHNODES) of GRAPH) DS)) (TERPRI T) (FLIPNODE NODE DS) (COND ((EQ [ASKUSER NIL NIL (LIST "delete node " (SETQ NODELABEL (DISPLAY/NAME NODE] (QUOTE Y)) (FLIPNODE NODE DS) (DISPLAYNODE NODE (CONSTANT (create POSITION XCOORD ← 0 YCOORD ← 0)) DS GRAPH) (for TOND in (APPEND (TOLINKS NODE)) do (GRAPHDELETELINK NODE (GETNODEFROMID TOND (fetch (GRAPH GRAPHNODES) of GRAPH)) GRAPH W)) (for FROMND in (APPEND (FROMLINKS NODE)) do (GRAPHDELETELINK (GETNODEFROMID FROMND (fetch (GRAPH GRAPHNODES) of GRAPH)) NODE GRAPH W)) (GRAPHDELETENODE NODE GRAPH W) (printout T "Node " NODELABEL " deleted." T) (RETURN NODE)) (T (FLIPNODE NODE DS) (printout T "nothing deleted." T) (RETURN NIL]) (EDITGRAPH [LAMBDA (GRAPH WINDOW) (* kvl "10-Aug-84 19:56") (* top level function for editing a graph. If there is no graph, create one empty. IF there is no window, create on the right size for the graph. After getting the arguments right, put the right button functions on, display it and enter the main loop.) (OR GRAPH (SETQ GRAPH (create GRAPH))) (SETQ WINDOW (SIZE/GRAPH/WINDOW GRAPH WINDOW)) (WINDOWPROP WINDOW (QUOTE GRAPH) GRAPH) (WINDOWPROP WINDOW (QUOTE REPAINTFN) (FUNCTION REDISPLAYGRAPH)) (WINDOWPROP WINDOW (QUOTE SCROLLFN) (FUNCTION SCROLLBYREPAINTFN)) (DSPOPERATION (QUOTE INVERT) WINDOW) (REDISPLAYGRAPH WINDOW) (EDITGRAPH1 WINDOW) GRAPH]) (EDITGRAPH1 [LAMBDA (W) (* rrb " 7-NOV-83 14:51") (* Can also be called from top level if the given window W has a graph on its GRAPH windowprop and the graph has been displayed by SHOWGRAPH or its equivalent. It waits for mouse hits, does the comand, then waits for mouse clear. Each edit command function takes only the window so that they can be hung separately on button event functions. However, the window must have INVERT as its display operation mode.) (PROG (VAL) (CLRPROMPT) (printout PROMPTWINDOW "Use the left button to move nodes." T "Use the middle button to get a menu of edit commands." T "During an edit command, the middle button can be used to abort.") LP (until (MOUSESTATE (OR LEFT MIDDLE)) do) (COND [(LASTMOUSESTATE MIDDLE) (SETQ VAL (ERSETQ (GRAPHEDITCOMMANDFN W))) (COND ((NULL VAL) (* aborted) (printout PROMPTWINDOW T T "command aborted." T)) ((EQ (CAR VAL) (QUOTE STOP)) (RETURN (CLRPROMPT] ((fetch (GRAPH GRAPHNODES) of (WINDOWPROP W (QUOTE GRAPH))) (* track the nearest node.) (TRACKNODE W)) (T (printout PROMPTWINDOW T "There are no nodes to move yet." T "Press the middle button and select the 'Add a node' command."))) (until (MOUSESTATE UP) do) (GO LP]) (EDITGRAPHMENU [LAMBDA NIL (* rrb " 6-JAN-82 12:29") (COND ((type? MENU EDITGRAPHMENU) EDITGRAPHMENU) (T (SETQ EDITGRAPHMENU (create MENU ITEMS ←(QUOTE (("Add Node" (QUOTE ADDNODE)) ("Delete Node" (QUOTE DELETENODE)) ("Add Link" (QUOTE ADDLINK)) ("Delete Link" (QUOTE DELETELINK)) ("Toggle DirectedFlg" (QUOTE DIRECTED)) ("Toggle SidesFlg" (QUOTE SIDES)) STOP)) CENTERFLG ← T CHANGEOFFSETFLG ← T]) (EDITMOVENODE [LAMBDA (WINDOW) (* rrb "31-OCT-83 21:47") (* hilite nodes until the cursor goes down then move it) (PROG ((DS (WINDOWPROP WINDOW (QUOTE DSP))) (REG (WINDOWPROP WINDOW (QUOTE REGION))) (GRAPH (WINDOWPROP WINDOW (QUOTE GRAPH))) OLDPOS NOW NEAR NODELST) (COND (GRAPH (SETQ NODELST (fetch (GRAPH GRAPHNODES) of GRAPH))) (T (RETURN))) (printout PROMPTWINDOW T "Move the cursor to the node " "you want to move " "and press any button.") [SETQ NEAR (NODELST/AS/MENU NODELST (SETQ OLDPOS (CURSORPOSITION NIL DS] FLIP(AND NOW (FLIPNODE NOW DS)) (AND NEAR (FLIPNODE NEAR DS)) (SETQ NOW NEAR) LP (GETMOUSESTATE) (COND ((LASTMOUSESTATE (NOT UP)) (* button up, process it.) (AND NOW (FLIPNODE NOW DS)) (* NOW node has been selected.) ) ([EQ NOW (SETQ NEAR (NODELST/AS/MENU NODELST (CURSORPOSITION NIL DS OLDPOS] (GO LP)) (T (GO FLIP))) (printout PROMPTWINDOW T "Holding the button down, " "move the node to its new position" "and release the button.") (TRACKCURSOR NOW DS GRAPH) (printout PROMPTWINDOW T "Done."]) (EDITTOGGLELABEL [LAMBDA (W) (* kvl " 5-Sep-84 19:16") (* prompts the user for a node and inverts its lable) (RESETFORM (TTYDISPLAYSTREAM PROMPTWINDOW) (CLRPROMPT) (PROG ((GRAPH (WINDOWPROP W (QUOTE GRAPH))) (DS (WINDOWPROP W (QUOTE DSP))) NODE) (COND ((NOT (fetch (GRAPH GRAPHNODES) of GRAPH)) (PROMPTPRINT " No nodes to invert.") (RETURN))) (PROMPTPRINT " Select node to have label inverted. ") (SETQ NODE (READ/NODE (fetch (GRAPH GRAPHNODES) of GRAPH) DS)) (TERPRI T) (RESET/NODE/LABELSHADE NODE (QUOTE INVERT) W) (AND (fetch (GRAPH GRAPH.INVERTLABELFN) of GRAPH) (APPLY* (fetch (GRAPH GRAPH.INVERTLABELFN) of GRAPH) NODE GRAPH W)) (printout T "Node " (fetch NODELABEL of NODE) " inverted." T) (RETURN NODE]) (FLIPNODE [LAMBDA (NODE DS) (* kvl "10-Aug-84 17:27") (* flips the region around a node.) (BITBLT NIL NIL NIL DS (IDIFFERENCE (GN/LEFT NODE) 1) (IDIFFERENCE (GN/BOTTOM NODE) 1) (IPLUS (fetch NODEWIDTH of NODE) 2) (IPLUS (fetch NODEHEIGHT of NODE) 2) (QUOTE TEXTURE) (QUOTE INVERT) BLACKSHADE]) (FONTNAMELIST [LAMBDA (FONTDESC) (* rrb " 2-NOV-83 21:00") (LIST (FONTPROP FONTDESC (QUOTE FAMILY)) (FONTPROP FONTDESC (QUOTE SIZE)) (FONTPROP FONTDESC (QUOTE FACE]) (FROMLINKS [LAMBDA (NODE) (* rrb "13-JUL-81 10:55") (fetch FROMNODES of NODE]) (GETNODEFROMID [LAMBDA (ID NODELST) (* kvl "22-DEC-83 17:55") (OR (FASSOC ID NODELST) (ERROR "No graphnode for nodeid:" ID]) (GN/BOTTOM [LAMBDA (NODE) (* kvl "10-Aug-84 17:08") (IDIFFERENCE (fetch YCOORD of (fetch NODEPOSITION of NODE)) (HALF (fetch NODEHEIGHT of NODE]) (GN/LEFT [LAMBDA (NODE) (* kvl "10-Aug-84 17:03") (IDIFFERENCE (fetch XCOORD of (fetch NODEPOSITION of NODE)) (HALF (fetch NODEWIDTH of NODE]) (GN/RIGHT [LAMBDA (NODE) (* rmk: " 2-Jan-85 08:37") (* Assumes that the big-half of width is to the left of the center, for even width) (IPLUS (fetch XCOORD of (fetch NODEPOSITION of NODE)) (SUB1 (HALF (ADD1 (fetch NODEWIDTH of NODE]) (GN/TOP [LAMBDA (NODE) (* rmk: " 2-Jan-85 08:38") (* Assumes that big-half of height is under the center, for even height. Result is -1 for height=0, which is correct.) (IPLUS (fetch YCOORD of (fetch NODEPOSITION of NODE)) (SUB1 (HALF (ADD1 (fetch NODEHEIGHT of NODE]) (GRAPHADDLINK [LAMBDA (FROM TO GRAPH WINDOW) (* rrb " 1-NOV-83 09:18") (* links two nodes) (PROG ((ADDFN (fetch (GRAPH GRAPH.ADDLINKFN) of GRAPH))) (AND ADDFN (APPLY* ADDFN FROM TO GRAPH WINDOW))) (push (fetch FROMNODES of TO) (fetch NODEID of FROM)) (push (fetch TONODES of FROM) (fetch NODEID of TO]) (GRAPHADDNODE [LAMBDA (GRAPH W) (* rrb " 2-NOV-83 20:29") (* adds a node to the graph GRAPH) (PROG (ADDFN NODE) (OR [SETQ NODE (COND ((SETQ ADDFN (fetch (GRAPH GRAPH.ADDNODEFN) of GRAPH)) (APPLY* ADDFN GRAPH W)) (T (DEFAULT.ADDNODEFN GRAPH W T] (RETURN)) (replace (GRAPH GRAPHNODES) of GRAPH with (NCONC1 (fetch (GRAPH GRAPHNODES) of GRAPH) NODE)) (RETURN NODE]) (GRAPHDELETELINK [LAMBDA (FROM TO GRAPH WINDOW) (* rrb " 1-NOV-83 09:16") (* deletes a link from a graph) (PROG ((DELFN (fetch (GRAPH GRAPH.DELETELINKFN) of GRAPH))) (AND DELFN (APPLY* DELFN FROM TO GRAPH WINDOW))) (replace TONODES of FROM with (REMOVE (fetch NODEID of TO) (fetch TONODES of FROM))) (replace FROMNODES of TO with (REMOVE (fetch NODEID of FROM) (fetch FROMNODES of TO]) (GRAPHDELETENODE [LAMBDA (NODE GRAPH WINDOW) (* kvl " 5-Sep-84 19:03") (PROG ((DELFN (fetch (GRAPH GRAPH.DELETENODEFN) of GRAPH))) (AND DELFN (APPLY* DELFN NODE GRAPH WINDOW)) (replace (GRAPH GRAPHNODES) of GRAPH with (DREMOVE NODE (fetch (GRAPH GRAPHNODES) of GRAPH]) (GRAPHEDITCOMMANDFN [LAMBDA (GRAPHWINDOW) (* kvl " 5-Sep-84 19:14") (SELECTQ [MENU (COND ((type? MENU EDITGRAPHMENU) EDITGRAPHMENU) (T (SETQ EDITGRAPHMENU (create MENU ITEMS ←(QUOTE (("Move Node" (QUOTE MOVENODE)) ("Add Node" (QUOTE ADDNODE)) ("Delete Node" (QUOTE DELETENODE)) ("Add Link" (QUOTE ADDLINK)) ("Delete Link" (QUOTE DELETELINK)) ("label smaller" (QUOTE SMALLER)) ("label larger" (QUOTE LARGER)) ("<-> Directed" (QUOTE DIRECTED)) ("<-> Sides" (QUOTE SIDES)) ("<-> Border" (QUOTE BORDER)) ("<-> Shade" (QUOTE SHADE)) STOP)) CENTERFLG ← T CHANGEOFFSETFLG ← T] (STOP (QUOTE STOP)) (MOVENODE (EDITMOVENODE GRAPHWINDOW)) (ADDNODE (EDITADDNODE GRAPHWINDOW)) (DELETENODE (EDITDELETENODE GRAPHWINDOW)) (ADDLINK (EDITADDLINK GRAPHWINDOW)) (SMALLER (EDITCHANGEFONT (QUOTE SMALLER) GRAPHWINDOW)) (LARGER (EDITCHANGEFONT (QUOTE LARGER) GRAPHWINDOW)) (DELETELINK (EDITDELETELINK GRAPHWINDOW)) (DIRECTED (TOGGLE/DIRECTEDFLG GRAPHWINDOW)) (SIDES (TOGGLE/SIDESFLG GRAPHWINDOW)) (BORDER (EDITTOGGLEBORDER GRAPHWINDOW)) (SHADE (EDITTOGGLELABEL GRAPHWINDOW)) NIL]) (GRAPHEDITEVENTFN [LAMBDA (GRWINDOW) (* rrb " 8-NOV-83 10:21") (* implements a graph editor on the right button transition of a window.) (COND ((NOT (INSIDE? (DSPCLIPPINGREGION NIL GRWINDOW) (LASTMOUSEX GRWINDOW) (LASTMOUSEY GRWINDOW))) (DOWINDOWCOM GRWINDOW)) ((SHIFTP) (TRACKNODE GRWINDOW)) ((EQ (GRAPHEDITCOMMANDFN GRWINDOW) (QUOTE STOP)) (* do menu) (CLOSEW GRWINDOW]) (GRAPHER/CENTERPRINTINAREA [LAMBDA (EXP X Y WIDTH HEIGHT STREAM) (* kvl "15-Aug-84 11:01") (* prints an expression in a box. The system CENTERPRINTINAREA on MENU worried about overflowing the right margin, which we ignore here.) (SETQ STREAM (\GETSTREAM STREAM (QUOTE OUTPUT))) (PROG (XPOS (STRWIDTH (STRINGWIDTH EXP STREAM))) (MOVETO (SETQ XPOS (IPLUS X (IQUOTIENT (ADD1 (IDIFFERENCE WIDTH STRWIDTH)) 2))) (IPLUS Y (IQUOTIENT (IPLUS (IDIFFERENCE HEIGHT (FONTPROP STREAM (QUOTE ASCENT))) (FONTPROP STREAM (QUOTE DESCENT))) 2)) STREAM) (PRIN3 EXP STREAM]) (GRAPHMOVENODE [LAMBDA (NODE NEWPOS GRAPH WINDOW) (* rmk: " 2-Feb-84 22:35") (* moves a node but doesn't change any display.) (COND ((EQUAL (fetch NODEPOSITION of NODE) NEWPOS) (* don't move if position hasn't changed) NIL) (T (SET/LAYOUT/POSITION NODE NEWPOS) (CALL.MOVENODEFN NODE NEWPOS GRAPH WINDOW]) (GRAPHNODE/BORDER/WIDTH [LAMBDA (BORDER) (* kvl " 5-Sep-84 16:19") (* returns a non-negative interger) (COND ((NULL BORDER) 0) ((EQ BORDER T) 1) ((FIXP BORDER) (ABS BORDER)) ((AND (LISTP BORDER) (FIXP (CAR BORDER)) (IGEQ (CAR BORDER) 0)) (CAR BORDER)) (T (ERROR "Illegal border:" BORDER]) (GRAPHREGION [LAMBDA (GRAPH) (* kvl "10-Aug-84 20:14") (* Returns the minimum region containing the graph.) (PROG (LEFTOFFSET BOTTOMOFFSET (NODELST (fetch GRAPHNODES of GRAPH))) (RETURN (COND [NODELST (* Determine the dimensions of the node labels) (for N in NODELST do (MEASUREGRAPHNODE N)) (CREATEREGION (SETQ LEFTOFFSET (MIN/LEFT NODELST)) (SETQ BOTTOMOFFSET (MIN/BOTTOM NODELST)) (ADD1 (IDIFFERENCE (MAX/RIGHT NODELST) LEFTOFFSET)) (ADD1 (IDIFFERENCE (MAX/TOP NODELST) BOTTOMOFFSET] (T (CREATEREGION 0 0 0 0]) (HARDCOPYGRAPH [LAMBDA (GRAPH/WINDOW FILE IMAGETYPE TRANS) (* rmk: "27-Aug-84 10:03") (PROG ((STREAM (OPENIMAGESTREAM FILE IMAGETYPE))) (DISPLAYGRAPH (COND ((WINDOWP GRAPH/WINDOW) (WINDOWPROP GRAPH/WINDOW (QUOTE GRAPH))) (T GRAPH/WINDOW)) STREAM NIL TRANS) (RETURN (CLOSEF STREAM]) (INTERSECT/REGIONP/LBWH [LAMBDA (L B W H REG) (* kvl "20-Aug-84 09:54") (* like intersect regions, but without requiring the consing) (NOT (OR (IGREATERP (fetch BOTTOM of REG) (IPLUS B H)) (ILESSP (fetch PRIGHT of REG) L) (IGREATERP (fetch LEFT of REG) (IPLUS L W)) (ILESSP (fetch PTOP of REG) B]) (INVERTED/GRAPHNODE/BORDER [LAMBDA (BORDER) (* kvl " 5-Sep-84 18:49") (* returns the right thing to invert a graphnode's border) (COND ((EQ BORDER T) NIL) ((NULL BORDER) T) ((FIXP BORDER) (IMINUS BORDER)) ((AND (LISTP BORDER) (FIXP (CAR BORDER))) (LIST (CAR BORDER) (INVERTED/SHADE/FOR/GRAPHER (CADR BORDER]) (INVERTED/SHADE/FOR/GRAPHER [LAMBDA (SHADE) (* kvl " 5-Sep-84 18:50") (* funny name because hopefully will become system function) (COND ((EQ SHADE T) NIL) ((NULL SHADE) T) ((FIXP SHADE) (LOGNOT SHADE)) ((BITMAPP SHADE) (PROG ((NB (COPYBITMAP SHADE))) (BITBLT NIL NIL NIL NB NIL NIL NIL NIL (QUOTE TEXTURE) (QUOTE INVERT) BLACKSHADE) (RETURN NB))) (T (ERROR "Illegal shade:" SHADE]) (LAYOUT/POSITION [LAMBDA (NODE) (* rrb "13-JUL-81 10:54") (fetch NODEPOSITION of NODE]) (MANHATTANDIST [LAMBDA (POS1 POS2) (* rrb "13-FEB-81 16:19") (* simple measure of closeness) (IPLUS (ABS (IDIFFERENCE (fetch XCOORD of POS1) (fetch XCOORD of POS2))) (ABS (IDIFFERENCE (fetch YCOORD of POS1) (fetch YCOORD of POS2]) (MAX/RIGHT [LAMBDA (NODES) (* rmk: "20-Dec-84 09:33") (for NODE in NODES largest (GN/RIGHT NODE) finally (RETURN $$EXTREME]) (MAX/TOP [LAMBDA (NODES) (* rmk: "20-Dec-84 09:34") (for NODE in NODES largest (GN/TOP NODE) finally (RETURN $$EXTREME]) (MEASUREGRAPHNODE [LAMBDA (NODE) (* rmk: " 2-Feb-84 21:19") (* Measure the nodelabel image) (SET/LABEL/SIZE NODE) (SET/LAYOUT/POSITION NODE (OR (fetch NODEPOSITION of NODE) (ERROR "This graphnode has not been given a position:" NODE]) (MIN/BOTTOM [LAMBDA (NODES) (* rmk: "20-Dec-84 09:34") (* returns the bottommost point of the graph.) (for NODE in NODES smallest (GN/BOTTOM NODE) finally (RETURN $$EXTREME]) (MIN/LEFT [LAMBDA (NODES) (* rmk: "20-Dec-84 09:34") (* returns the leftmost point of the graph.) (for NODE in NODES smallest (GN/LEFT NODE) finally (RETURN $$EXTREME]) (MOVENODE [LAMBDA (NODE OLDPOS POS GRAPH STREAM) (* rmk: "10-Apr-84 12:31") (* moves a node from its current position to POS) (COND ((EQUAL OLDPOS POS) (* don't move if position hasn't changed) NIL) (T (* node is flipped, flip it back.) (FLIPNODE NODE STREAM) (* erase current position) (DISPLAYNODE NODE (CONSTANT (create POSITION XCOORD ← 0 YCOORD ← 0)) STREAM GRAPH) (* put it in new one.) (SET/LAYOUT/POSITION NODE POS) (DISPLAYNODE NODE (CONSTANT (create POSITION XCOORD ← 0 YCOORD ← 0)) STREAM GRAPH) (FLIPNODE NODE STREAM]) (NODECREATE [LAMBDA (ID LABEL POS TONODEIDS FROMNODEIDS FONT BORDER LABELSHADE) (* rmk: "15-Sep-84 00:11") (* creates a node for a grapher.) (create GRAPHNODE NODEID ← ID NODEPOSITION ← POS NODELABEL ← LABEL NODEFONT ←(OR FONT DEFAULT.GRAPH.NODEFONT (FONTNAMELIST DEFAULTFONT)) TONODES ← TONODEIDS FROMNODES ← FROMNODEIDS NODEBORDER ← BORDER NODELABELSHADE ← LABELSHADE]) (NODELST/AS/MENU [LAMBDA (NODELST POS) (* kvl "10-Aug-84 18:55") (* finds the node that is closest to POS) (for N in NODELST bind (X ←(fetch XCOORD of POS)) (Y ←(fetch YCOORD of POS)) T1 T2 thereis (AND (ILESSP [IDIFFERENCE (SETQ T1 (fetch YCOORD of (fetch NODEPOSITION of N))) (SETQ T2 (HALF (fetch NODEHEIGHT of N] Y) (ILESSP Y (IPLUS T1 T2)) (ILESSP [IDIFFERENCE (SETQ T1 (fetch XCOORD of (fetch NODEPOSITION of N))) (SETQ T2 (HALF (fetch NODEWIDTH of N] X) (ILESSP X (IPLUS T1 T2]) (NODEREGION [LAMBDA (NODE) (* kvl "10-Aug-84 17:25") (* returns the region taken up by NODE) (CREATEREGION (GN/LEFT NODE) (GN/BOTTOM NODE) (fetch (GRAPHNODE NODEWIDTH) of NODE) (fetch (GRAPHNODE NODEHEIGHT) of NODE]) (PRINTDISPLAYNODE [LAMBDA (NODE TRANS STREAM CLIP/REG) (* rmk: "14-Dec-84 09:21") (* prints a node at its position translated by TRANS. Takes the operation from the stream so that when editor has set the operation to invert, this may erase as well as draw; but when the operation is paint, then nodes obliterate any link lines that they are drawn over.) (OR (ZEROP (fetch (GRAPHNODE NODEHEIGHT) of NODE)) (PROG [(LEFT (IPLUS (fetch XCOORD of TRANS) (GN/LEFT NODE))) (BOTTOM (IPLUS (fetch YCOORD of TRANS) (GN/BOTTOM NODE))) (WIDTH (fetch NODEWIDTH of NODE)) (HEIGHT (fetch NODEHEIGHT of NODE)) (FONT (fetch (GRAPHNODE NODEFONT) of NODE)) (NBW (GRAPHNODE/BORDER/WIDTH (fetch NODEBORDER of NODE] (COND ((AND CLIP/REG (NOT (INTERSECT/REGIONP/LBWH LEFT BOTTOM WIDTH HEIGHT CLIP/REG))) (RETURN NODE)) ((BITMAPP (fetch NODELABELBITMAP of NODE)) (BITBLT (fetch NODELABELBITMAP of NODE) 0 0 STREAM LEFT BOTTOM WIDTH HEIGHT (QUOTE INPUT))) [(BITMAPP (fetch NODELABEL of NODE)) (COND ((NEQ 0 NBW) (DRAW/GRAPHNODE/BORDER (fetch NODEBORDER of NODE) LEFT BOTTOM WIDTH HEIGHT STREAM) (BITBLT (fetch NODELABEL of NODE) 0 0 STREAM (IPLUS LEFT NBW) (IPLUS BOTTOM NBW) WIDTH HEIGHT (QUOTE INPUT))) (T (BITBLT (fetch NODELABEL of NODE) 0 0 STREAM LEFT BOTTOM WIDTH HEIGHT (QUOTE INPUT] ((IMAGEOBJP (fetch NODELABEL of NODE)) (COND ((NEQ 0 NBW) (DRAW/GRAPHNODE/BORDER (fetch NODEBORDER of NODE) LEFT BOTTOM WIDTH HEIGHT STREAM) (MOVETO (IPLUS NBW LEFT) (IPLUS NBW BOTTOM) STREAM)) (T (MOVETO LEFT BOTTOM STREAM))) (APPLY* (IMAGEOBJPROP (fetch NODELABEL of NODE) (QUOTE DISPLAYFN)) (fetch NODELABEL of NODE) STREAM)) ((NULL FONT)) [(IGREATERP HEIGHT 2) (* This constant is wrong for scaled graphs) (AND (NEQ NBW 0) (DRAW/GRAPHNODE/BORDER (fetch NODEBORDER of NODE) LEFT BOTTOM WIDTH HEIGHT STREAM)) (DSPFONT FONT STREAM) (GRAPHER/CENTERPRINTINAREA (fetch NODELABEL of NODE) LEFT BOTTOM WIDTH HEIGHT STREAM) (AND (fetch NODELABELSHADE of NODE) (FILL/GRAPHNODE/LABEL (fetch NODELABELSHADE of NODE) LEFT BOTTOM WIDTH HEIGHT NBW STREAM)) (COND ((AND CACHE/NODE/LABEL/BITMAPS CLIP/REG (INTERSECT/REGIONP/LBWH LEFT BOTTOM WIDTH HEIGHT CLIP/REG)) (replace NODELABELBITMAP of NODE with (BITMAPCREATE WIDTH HEIGHT)) (BITBLT STREAM LEFT BOTTOM (fetch NODELABELBITMAP of NODE) 0 0 WIDTH HEIGHT (QUOTE INPUT] (T (* so small just use texture) (BITBLT NIL NIL NIL STREAM LEFT BOTTOM 2 2 (QUOTE TEXTURE) NIL BLACKSHADE))) (RETURN NODE]) (FILL/GRAPHNODE/LABEL [LAMBDA (SHADE LEFT BOTTOM WIDTH HEIGHT NBW STREAM) (* kvl "10-Sep-84 14:41") (* NBW is the border, which must be subtracted from the node's region) (PROG ((NS SHADE)) (OR (WINDOWP STREAM) (DISPLAYSTREAMP STREAM) (RETURN)) (COND ((EQ SHADE T) (SETQ NS BLACKSHADE)) ((NULL SHADE) (SETQ NS WHITESHADE))) (BITBLT NIL NIL NIL STREAM (IPLUS LEFT NBW) (IPLUS BOTTOM NBW) (IDIFFERENCE WIDTH (IPLUS NBW NBW)) (IDIFFERENCE HEIGHT (IPLUS NBW NBW)) (QUOTE TEXTURE) (QUOTE INVERT) NS]) (PROMPTINWINDOW [LAMBDA (PROMPTSTR POSITION WHICHCORNER BORDERSIZE) (* rrb "16-Jan-84 11:48") (* opens a small window for prompting at a position and PROMPTFORWORD's a word.) (* POSITION is the location in screen coordinate of the window. Default is the cursor position.) (* WHICHCORNER can be a list of up to two of the atoms LEFT RIGHT TOP BOTTOM which specify which corner position is intended to be. Default is lower left.) (* BORDERSIZE is the border size of the prompt window. Default is 6.0) (PROG ((PROMPTWBORDER (OR (NUMBERP BORDERSIZE) 6)) (X (COND (POSITION (fetch (POSITION XCOORD) of POSITION)) (T LASTMOUSEX))) (Y (COND (POSITION (fetch (POSITION YCOORD) of POSITION)) (T LASTMOUSEY))) HGHT WDTH READSTR PREVTTY) (SETQ HGHT (HEIGHTIFWINDOW (ITIMES (FONTPROP (DEFAULTFONT (QUOTE DISPLAY)) (QUOTE HEIGHT)) 2) T PROMPTWBORDER)) (SETQ WDTH (WIDTHIFWINDOW (IMAX (STRINGWIDTH PROMPTSTR WindowTitleDisplayStream) 60) PROMPTWBORDER)) (SETQ PREVTTY (TTYDISPLAYSTREAM (CREATEW (CREATEREGION (COND ((MEMB (QUOTE RIGHT) WHICHCORNER) (DIFFERENCE X WDTH)) (T X)) (COND ((MEMB (QUOTE TOP) WHICHCORNER) (DIFFERENCE Y HGHT)) (T Y)) WDTH HGHT) PROMPTSTR PROMPTWBORDER))) (DSPLEFTMARGIN (IMAX 0 (fetch (CURSOR CURSORHOTSPOTX) of (CARET))) (TTYDISPLAYSTREAM)) (MOVETOUPPERLEFT (TTYDISPLAYSTREAM)) [SETQ READSTR (ERSETQ (PROMPTFORWORD NIL NIL NIL NIL NIL NIL (CONS (CHARCODE EOL] (CLOSEW (TTYDISPLAYSTREAM PREVTTY)) (RETURN (COND (READSTR (CAR READSTR)) (T (* pass back the error.) (ERROR!]) (READ/NODE [LAMBDA (NODES DS) (* kvl "10-Aug-84 19:26") (until (MOUSESTATE (OR LEFT MIDDLE RIGHT)) do) (PROG (NEAR NOW OLDPOS) [SETQ NEAR (CLOSEST/NODE NODES (SETQ OLDPOS (CURSORPOSITION NIL DS] FLIP (* turn off old flip (if one) and turn on new flip.) (AND NOW (FLIPNODE NOW DS)) (FLIPNODE (SETQ NOW NEAR) DS) LP (COND ((MOUSESTATE UP) (FLIPNODE NOW DS) (RETURN NOW)) ([EQ NOW (SETQ NEAR (CLOSEST/NODE NODES (CURSORPOSITION NIL DS OLDPOS] (GO LP)) (T (GO FLIP]) (REDISPLAYGRAPH [LAMBDA (WINDOW REGION) (* kvl "10-Aug-84 19:52") (* displays the graph that is in a window. REGION if given is the clipping region. Later this could be used to make things run faster.) (DSPFILL NIL NIL (QUOTE REPLACE) WINDOW) (DISPLAYGRAPH (WINDOWPROP WINDOW (QUOTE GRAPH)) WINDOW (OR REGION (DSPCLIPPINGREGION NIL WINDOW]) (RESET/NODE/BORDER [LAMBDA (NODE BORDER STREAM GRAPH TRANS) (* rmk: "31-Dec-84 11:42") (* gives the node a new border, and displays it if there is a stream. Might not be a stream if being called just to finagle a graph datastructure.) (PROG [(ONBW (GRAPHNODE/BORDER/WIDTH (fetch NODEBORDER of NODE] [OR TRANS (SETQ TRANS (CONSTANT (create POSITION XCOORD ← 0 YCOORD ← 0] (COND (STREAM (ERASE/GRAPHNODE NODE STREAM TRANS) [OR GRAPH (AND (WINDOWP STREAM) (SETQ GRAPH (WINDOWPROP STREAM (QUOTE GRAPH] (DISPLAYNODELINKS NODE TRANS STREAM GRAPH))) (replace NODEBORDER of NODE with (COND ((EQ BORDER (QUOTE INVERT)) (INVERTED/GRAPHNODE/BORDER (fetch NODEBORDER of NODE))) (T BORDER))) (OR (IEQP ONBW (GRAPHNODE/BORDER/WIDTH (fetch NODEBORDER of NODE))) (SET/LABEL/SIZE NODE T)) (AND STREAM (DISPLAYNODE NODE TRANS STREAM GRAPH)) (RETURN NODE]) (RESET/NODE/LABELSHADE [LAMBDA (NODE SHADE STREAM TRANS) (* kvl " 5-Sep-84 19:23") (* gives the node a new SHADE and displays it if there is a stream) (AND STREAM (ERASE/GRAPHNODE NODE STREAM TRANS)) (replace NODELABELSHADE of NODE with (COND ((EQ SHADE (QUOTE INVERT)) (INVERTED/SHADE/FOR/GRAPHER (fetch NODELABELSHADE of NODE))) (T SHADE))) (AND STREAM (PRINTDISPLAYNODE NODE (OR TRANS (CONSTANT (create POSITION XCOORD ← 0 YCOORD ← 0))) STREAM)) NODE]) (SCALE/GRAPH [LAMBDA (GRAPH STREAM SCALE) (* rmk: "15-Sep-84 13:52") (create GRAPH using GRAPH GRAPHNODES ←(for N in (fetch GRAPHNODES of GRAPH) collect (SETQ N (create GRAPHNODE using N NODEPOSITION ←[create POSITION XCOORD ←[FIXR (FTIMES SCALE (fetch XCOORD of (fetch NODEPOSITION of N] YCOORD ←(FIXR (FTIMES SCALE (fetch YCOORD of (fetch NODEPOSITION of N] NODELABELBITMAP ← NIL NODEWIDTH ← NIL NODEHEIGHT ← NIL NODEFONT ←(FONTCREATE (fetch NODEFONT of N) NIL NIL NIL STREAM) NODEBORDER ←(SCALE/GRAPHNODE/BORDER (fetch NODEBORDER of N) SCALE))) (SET/LABEL/SIZE N) N]) (SCALE/GRAPHNODE/BORDER [LAMBDA (BORDER SCALE) (* kvl " 5-Sep-84 18:06") (* returns a new setting for the border appropriate for the given SCALE) (COND ((NULL BORDER) 0) ((EQ BORDER T) (FIXR (FTIMES SCALE NODEBORDERWIDTH))) ((FIXP BORDER) (FIXR (FTIMES SCALE BORDER))) ((AND (LISTP BORDER) (FIXP (CAR BORDER))) (CONS (FIXR (FTIMES SCALE (CAR BORDER))) (CDR BORDER]) (SET/LABEL/SIZE [LAMBDA (NODE RESET/FLG) (* kvl " 5-Sep-84 18:27") (* the SHADE and null font stuff is for ZOOMGRAPH) (OR (AND (NOT RESET/FLG) (FIXP (fetch NODEHEIGHT of NODE)) (FIXP (fetch NODEWIDTH of NODE))) (PROG ((FONT (fetch (GRAPHNODE NODEFONT) of NODE)) (LAB (fetch (GRAPHNODE NODELABEL) of NODE)) (NBW (GRAPHNODE/BORDER/WIDTH (fetch NODEBORDER of NODE))) WIDTH HEIGHT) [COND ((BITMAPP LAB) (SETQ WIDTH (BITMAPWIDTH LAB)) (SETQ HEIGHT (BITMAPHEIGHT LAB))) ((EQ FONT (QUOTE SHADE)) (* node image is very small) (SETQ WIDTH (SETQ HEIGHT 2))) ((IMAGEOBJP LAB) (SETQ WIDTH (APPLY* (IMAGEOBJPROP LAB (QUOTE IMAGEBOXFN)) LAB)) (SETQ HEIGHT (fetch (IMAGEBOX YSIZE) of WIDTH)) (SETQ WIDTH (fetch (IMAGEBOX XSIZE) of WIDTH))) [(NULL FONT) (* FONT of NIL means that the node is smaller than displays) (SETQ NBW (SETQ WIDTH (SETQ HEIGHT 0] (T (OR (FONTP FONT) (SETQ FONT (FONTCREATE FONT))) [SETQ WIDTH (IPLUS (STRINGWIDTH (fetch NODELABEL of NODE) FONT) (FONTPROP FONT (QUOTE DESCENT] (SETQ HEIGHT (IPLUS (FONTPROP FONT (QUOTE HEIGHT)) (FONTPROP FONT (QUOTE DESCENT] (OR (AND (NOT RESET/FLG) (FIXP (fetch NODEWIDTH of NODE))) (replace NODEWIDTH of NODE with (IPLUS WIDTH NBW NBW))) (OR (AND (NOT RESET/FLG) (FIXP (fetch NODEHEIGHT of NODE))) (replace NODEHEIGHT of NODE with (IPLUS HEIGHT NBW NBW))) (RETURN NODE]) (SET/LAYOUT/POSITION [LAMBDA (NODE POS) (* kvl "10-Aug-84 17:32") (* sets a nodes position) (replace XCOORD of (fetch NODEPOSITION of NODE) with (fetch XCOORD of POS)) (replace YCOORD of (fetch NODEPOSITION of NODE) with (fetch YCOORD of POS)) NODE]) (SHIFTP [LAMBDA NIL (* rrb " 8-NOV-83 10:09") (* is a shift key down) (OR (KEYDOWNP (QUOTE RSHIFT)) (KEYDOWNP (QUOTE LSHIFT]) (SHOWGRAPH [LAMBDA (GRAPH WINDOW LEFTBUTTONFN MIDDLEBUTTONFN TOPJUSTIFYFLG ALLOWEDITFLG COPYBUTTONEVENTFN) (* rmk: "14-Dec-84 12:11") (* puts a graph in the given window, creating one if a window is not given.) (SETQ WINDOW (SIZE/GRAPH/WINDOW (COND ((NULL GRAPH) (SETQ GRAPH (create GRAPH))) (T GRAPH)) (COND (WINDOW) (ALLOWEDITFLG (* put on a blank title so there will be a place to get window commands.) "")) TOPJUSTIFYFLG)) (WINDOWPROP WINDOW (QUOTE GRAPH) GRAPH) (WINDOWPROP WINDOW (QUOTE REPAINTFN) (FUNCTION REDISPLAYGRAPH)) (WINDOWPROP WINDOW (QUOTE SCROLLFN) (FUNCTION SCROLLBYREPAINTFN)) [COND (ALLOWEDITFLG (* change the mode to invert so lines can be erased by being redrawn.) (DSPOPERATION (QUOTE INVERT) WINDOW) (WINDOWPROP WINDOW (QUOTE RIGHTBUTTONFN) (FUNCTION GRAPHEDITEVENTFN))) (T (WINDOWPROP WINDOW (QUOTE RIGHTBUTTONFN) NIL) (WINDOWPROP WINDOW (QUOTE COPYBUTTONEVENTFN) (OR COPYBUTTONEVENTFN (FUNCTION GRAPHERCOPYBUTTONEVENTFN] (WINDOWPROP WINDOW (QUOTE BUTTONEVENTFN) (FUNCTION APPLYTOSELECTEDNODE)) (WINDOWPROP WINDOW (QUOTE BROWSER/LEFTFN) LEFTBUTTONFN) (WINDOWPROP WINDOW (QUOTE BROWSER/MIDDLEFN) MIDDLEBUTTONFN) (REDISPLAYGRAPH WINDOW) WINDOW]) (SIZE/GRAPH/WINDOW [LAMBDA (GRAPH WINDOW/TITLE TOPJUSTIFYFLG) (* kvl "10-Aug-84 20:18") (* returns a window sized to fit the given graph. WINDOW/TITLE can be either a window to be printed in or a title of a window to be created. If TOPJUSTIFYFLG is true, scrolls so top of graph is at top of window, else puts bottom of graph at bottom of window.) (PROG ((GRAPHREG (GRAPHREGION GRAPH)) TITLE WINDOW) (COND ((WINDOWP WINDOW/TITLE) (SETQ WINDOW WINDOW/TITLE)) (T (SETQ TITLE WINDOW/TITLE))) (* if there is not already a window, ask the user for one to fit.) (COND ((NULL WINDOW) (SETQ WINDOW (CREATEW (GETBOXREGION (WIDTHIFWINDOW (IMIN (IMAX (fetch (REGION WIDTH) of GRAPHREG) 100) 500)) (HEIGHTIFWINDOW (IMIN (IMAX (fetch (REGION HEIGHT) of GRAPHREG) 60) (IQUOTIENT SCREENHEIGHT 2)) TITLE)) TITLE))) (T (CLEARW WINDOW))) (WINDOWPROP WINDOW (QUOTE EXTENT) GRAPHREG) (WXOFFSET (IDIFFERENCE (WXOFFSET NIL WINDOW) (fetch (REGION LEFT) of GRAPHREG)) WINDOW) (WYOFFSET [IDIFFERENCE (WYOFFSET NIL WINDOW) (COND [TOPJUSTIFYFLG (IDIFFERENCE (fetch (REGION PTOP) of GRAPHREG) (WINDOWPROP WINDOW (QUOTE HEIGHT] (T (fetch (REGION BOTTOM) of GRAPHREG] WINDOW) (RETURN WINDOW]) (TOGGLE/DIRECTEDFLG [LAMBDA (WIN) (* kvl "20-APR-82 13:38") (* flips the value of the flag that indicates whether the graph is a lattice.) [replace (GRAPH DIRECTEDFLG) of (WINDOWPROP WIN (QUOTE GRAPH)) with (NOT (fetch (GRAPH DIRECTEDFLG) of (WINDOWPROP WIN (QUOTE GRAPH] (DSPFILL NIL (DSPTEXTURE NIL WIN) (QUOTE REPLACE) WIN) (REDISPLAYGRAPH WIN]) (TOGGLE/SIDESFLG [LAMBDA (WIN) (* kvl "20-APR-82 13:15") (* flips the value of the flag that indicates whether the graph is to be layed out vertically or horizontally.) [replace (GRAPH SIDESFLG) of (WINDOWPROP WIN (QUOTE GRAPH)) with (NOT (fetch (GRAPH SIDESFLG) of (WINDOWPROP WIN (QUOTE GRAPH] (DSPFILL NIL (DSPTEXTURE NIL WIN) (QUOTE REPLACE) WIN) (REDISPLAYGRAPH WIN]) (TOLINKS [LAMBDA (NODE) (* rrb "13-JUL-81 10:55") (fetch TONODES of NODE]) (TRACKCURSOR [LAMBDA (ND DS GRAPH) (* rmk: " 2-Feb-84 22:36") (* causes ND to follow cursor.) (PROG (OLDPOS ORIGPOS DOWNFLG) (* maybe there aren't any nodes) (OR ND (RETURN)) (SETQ ORIGPOS (COPYALL (fetch NODEPOSITION of ND))) (SETQ OLDPOS (CURSORPOSITION (fetch NODEPOSITION of ND) DS)) (FLIPNODE ND DS) (until (COND (DOWNFLG (MOUSESTATE UP)) ((SETQ DOWNFLG (MOUSESTATE (NOT UP))) NIL)) do (MOVENODE ND (fetch NODEPOSITION of ND) (CURSORPOSITION NIL DS OLDPOS) GRAPH DS)) (FLIPNODE ND DS) (COND ([NOT (EQUAL ORIGPOS (SETQ OLDPOS (fetch NODEPOSITION of ND] (EXTENDEXTENT (WFROMDS DS) (NODEREGION ND)) (CALL.MOVENODEFN ND OLDPOS GRAPH (WFROMDS DS]) (TRACKNODE [LAMBDA (W) (* kvl "20-APR-82 13:43") (* grabs the nearest nodes and hauls it around with the cursor, leaving it where it is when the button goes up.) (TRACKCURSOR (CLOSEST/NODE (fetch (GRAPH GRAPHNODES) of (WINDOWPROP W (QUOTE GRAPH))) (CURSORPOSITION NIL W)) (WINDOWPROP W (QUOTE DSP)) (WINDOWPROP W (QUOTE GRAPH]) ) (DEFINEQ (DEFAULTGRAPHERCOPYBUTTONEVENTFN [LAMBDA (WINDOW) (* rmk: "14-Dec-84 12:11") (APPLY* (OR (WINDOWPROP WINDOW (QUOTE BUTTONEVENTFN)) (FUNCTION NILL)) WINDOW) NIL]) ) (* For shift-selecting without GRAPHEROBJs) (MOVD? (QUOTE DEFAULTGRAPHERCOPYBUTTONEVENTFN) (QUOTE GRAPHERCOPYBUTTONEVENTFN)) (* functions for finding larger and smaller fonts) (DEFINEQ (NEXTSIZEFONT [LAMBDA (WHICHDIR NOWFONT) (* rmk: "15-Sep-84 00:14") (* returns the next sized font either SMALLER or LARGER that on of size FONT. (NEXTSIZEFONT (QUOTE LARGER) DEFAULTFONT)) (PROG [(NOWSIZE (FONTPROP NOWFONT (QUOTE HEIGHT] (RETURN (COND [(EQ WHICHDIR (QUOTE LARGER)) (COND ((IGEQ NOWSIZE (FONTPROP (CAR DECREASING.FONT.LIST) (QUOTE HEIGHT))) (* nothing larger) NIL) (T (for FONTTAIL on DECREASING.FONT.LIST when [AND (CDR FONTTAIL) (IGEQ NOWSIZE (FONTPROP (CADR FONTTAIL) (QUOTE HEIGHT] do (RETURN (FONTNAMELIST (CAR FONTTAIL] (T (for FONT in DECREASING.FONT.LIST when (LESSP (FONTPROP FONT (QUOTE HEIGHT)) NOWSIZE) do (RETURN (FONTNAMELIST FONT]) (DECREASING.FONT.LIST [LAMBDA NIL (* rrb "16-Dec-83 12:28") (* returns a list of the font descriptors for the fonts sketch windows are willing to print in.) (for SIZE in (QUOTE (18 14 12 10 8 5)) collect (FONTCREATE (QUOTE HELVETICA) SIZE]) (SCALE.FONT [LAMBDA (WID STR) (* rrb " 7-NOV-83 11:35") (* returns the font that text should be printed in to have the text STR fit into a region WID points wide) (COND ((GREATERP WID (TIMES (STRINGWIDTH STR (CAR DECREASING.FONT.LIST)) 1.5)) (* scale it too large for even the largest font.) NIL) (T (for FONT in DECREASING.FONT.LIST when (NOT (GREATERP (STRINGWIDTH STR FONT) WID)) do (RETURN FONT) finally (RETURN (QUOTE SHADE]) ) (DECLARE: DONTEVAL@LOAD DOCOPY (RPAQ DECREASING.FONT.LIST (DECREASING.FONT.LIST)) ) (DECLARE: DOEVAL@COMPILE DONTCOPY (GLOBALVARS DECREASING.FONT.LIST) ) (* functions for LAYOUTGRAPH And LAYOUTLATTICE) (DEFINEQ (BRH/LAYOUT [LAMBDA (N X Y MOMLST GN) (* kvl "26-DEC-83 16:44") (* X and Y are the lower left corner of the box that will surround the tree headed by the browsenode N. MOMLST is the mother node inside a cons cell. GN is the graphnode for the nodeid N. It is crucial that the NODEPOSITION be set before recursion because this marks that the node has been (is being) laid out already. BRH/OFFSET is used to raise the daughters in those rare cases where the label is bigger than the daughters.) (DECLARE (USEDFREE MOTHERD PERSONALD NODELST)) (PROG ((DS (fetch (GRAPHNODE TONODES) of GN)) (W (fetch (GRAPHNODE NODEWIDTH) of GN)) (YHEIGHT (IPLUS PERSONALD (fetch (GRAPHNODE NODEHEIGHT) of GN))) DHEIGHT) (replace (GRAPHNODE FROMNODES) of GN with MOMLST) [replace (GRAPHNODE NODEPOSITION) of GN with (create POSITION XCOORD ←(IPLUS X (HALF W] (COND ((NULL DS)) [[IGREATERP YHEIGHT (SETQ DHEIGHT (BRH/LAYOUT/DAUGHTERS DS (IPLUS X W MOTHERD) Y (LIST N] (BRH/OFFSET DS (HALF (IDIFFERENCE YHEIGHT DHEIGHT] (T (SETQ YHEIGHT DHEIGHT))) (replace YCOORD of (fetch (GRAPHNODE NODEPOSITION) of GN) with (IPLUS Y (HALF YHEIGHT))) (RETURN YHEIGHT]) (BRH/LAYOUT/DAUGHTERS [LAMBDA (DS X Y MOMLST) (* rmk: " 5-Feb-84 15:01") (* DS are the daughters of (CAR MOMLST). X is where the left edge of their labels will be, and Y is the bottom of the mother's box. Returns the height of the mother's box. Tests to see if a node has been layout out already If so, it replaces the daughter with one that has no descendents, and splices into the mother's daughter list, side-effecting the graphnode structure.) (DECLARE (USEDFREE NODELST)) (for D (FLOOR ← Y) in DS do [SETQ FLOOR (IPLUS FLOOR (BRH/LAYOUT D X FLOOR MOMLST (GETNODEFROMID D NODELST] finally (RETURN (IDIFFERENCE FLOOR Y]) (BRH/OFFSET [LAMBDA (NODEIDS YINC) (DECLARE (USEDFREE NODELST)) (* kvl "11-Dec-84 14:35") (for N in NODEIDS do (SETQ N (GETNODEFROMID N NODELST)) (add (fetch YCOORD of (fetch (GRAPHNODE NODEPOSITION) of N)) YINC) (BRH/OFFSET (fetch (GRAPHNODE TONODES) of N) YINC]) (BRHC/INTERTREE/SPACE [LAMBDA (TTC BTC) (* kvl "21-DEC-83 10:23") (* Given the top transition chain of the old daughter and the bottom transition chain of the new daughter, where BTC is sitting on the bottom of the box, calculate how much the bottom must be raised so that it just clears the TTC. OP is the top left corner of some label. NP is the bottom left corner.) (PROG ((RAISE -1000) NP DIST OP) (SETQ OP (pop TTC)) (SETQ NP (pop BTC)) L (SETQ DIST (IDIFFERENCE (fetch YCOORD of OP) (fetch YCOORD of NP))) (AND (IGREATERP DIST RAISE) (SETQ RAISE DIST)) [COND ((NULL BTC) (RETURN RAISE)) ((NULL TTC) (RETURN RAISE)) ((IEQP (fetch XCOORD of (CAR BTC)) (fetch XCOORD of (CAR TTC))) (SETQ NP (pop BTC)) (SETQ OP (pop TTC))) ((ILESSP (fetch XCOORD of (CAR BTC)) (fetch XCOORD of (CAR TTC))) (SETQ NP (pop BTC))) (T (SETQ OP (pop TTC] (GO L]) (BRHC/LAYOUT [LAMBDA (N X MOMLST GN) (* rmk: " 5-Feb-84 14:47") (* See comment on BRH/LAYOUT. Instead of keeping only the graphnode in layed out node's position field, keep the offset as well. The offset is how much this nodes box must be raised relative to the inclosing box. Uses two free variables to return transition chains. RETURNTTC is the top left corners of all the labels. RETURNBTC is the bottom left corners.) (DECLARE (USEDFREE PERSONALD RETURNTTC RETURNBTC)) (PROG ((DS (fetch (GRAPHNODE TONODES) of GN)) (W (fetch (GRAPHNODE NODEWIDTH) of GN)) (H (fetch (GRAPHNODE NODEHEIGHT) of GN)) YCENTER X/SW H/2) (SETQ H/2 (HALF H)) (SETQ X/SW (IPLUS X W)) (replace (GRAPHNODE FROMNODES) of GN with MOMLST) (replace (GRAPHNODE NODEPOSITION) of GN with (LIST 0)) [SETQ YCENTER (COND (DS (BRHC/LAYOUT/DAUGHTERS DS X/SW (LIST N))) (T (BRHC/LAYOUT/TERMINAL GN X/SW] (RPLACD (fetch (GRAPHNODE NODEPOSITION) of GN) (create POSITION XCOORD ←(IPLUS X (HALF W)) YCOORD ← YCENTER)) [push RETURNTTC (create POSITION XCOORD ← X YCOORD ←(IPLUS PERSONALD (IPLUS (IDIFFERENCE YCENTER H/2) H] (push RETURNBTC (create POSITION XCOORD ← X YCOORD ←(IDIFFERENCE YCENTER H/2))) (RETURN YCENTER]) (BRHC/LAYOUT/DAUGHTERS [LAMBDA (DS X/SW MOMLST) (DECLARE (USEDFREE MOTHERD FAMILYD NODELST RETURNTTC RETURNBTC)) (* rmk: " 5-Feb-84 14:52") (* see comment on BRH/LAYOUT/DAUGHTERS. First daughter is always laid out on the bottom of the box. Subsequent daughters have the amount that they are to be raised calculated by comparing the top edge of the old daughter (in TTC) with the bottom edge of the new daughter (in RETURNBTC). TTC is update by adding the new daughter's transition chain to the front, because the new daughter's front is guaranteed to be higher than the old daughter's front. Conversely, BTC is updated by adding the new daughter's transition chain to the back, because the old daughter's front is guaranteed to be lower.) (for D in DS bind GN BTC TTC 1ST/DCENTER LST/DCENTER (OFFSET ← 0) (X ←(IPLUS X/SW MOTHERD)) do (SETQ GN (GETNODEFROMID D NODELST)) (SETQ LST/DCENTER (BRHC/LAYOUT D X MOMLST GN)) [COND ((NULL TTC) (* first daughter) (SETQ 1ST/DCENTER LST/DCENTER) (SETQ TTC RETURNTTC) (SETQ BTC RETURNBTC)) (T (SETQ OFFSET (BRHC/INTERTREE/SPACE TTC RETURNBTC)) (RPLACA (fetch (GRAPHNODE NODEPOSITION) of GN) OFFSET) (SETQ TTC (EXTEND/TRANSITION/CHAIN (RAISE/TRANSITION/CHAIN RETURNTTC OFFSET) TTC)) (SETQ BTC (EXTEND/TRANSITION/CHAIN BTC (RAISE/TRANSITION/CHAIN RETURNBTC OFFSET] finally (* add a mythical top left corner at the height of the highest daughter because diagnonal links are getting clobbered. Move lowest daughter's bottom left corner to the left for the same reason.) (SETQ RETURNTTC (CONS (create POSITION XCOORD ← X/SW YCOORD ←(fetch YCOORD of (CAR TTC))) TTC)) (replace XCOORD of (CAR BTC) with X/SW) (add (fetch YCOORD of (CAR TTC)) FAMILYD) (SETQ RETURNBTC BTC) (* center of mother is halfway between first and last daughter's label centers using fact that offset of first daughter is zero and last daughter's offset is OFFSET) (RETURN (HALF (IPLUS 1ST/DCENTER OFFSET LST/DCENTER]) (BRHC/LAYOUT/TERMINAL [LAMBDA (GN X/SW) (* rmk: " 3-Feb-84 09:55") (* initiallizes the transition chains to the right edge of the node label, and returns the label's center.) (DECLARE (USEDFREE RETURNTTC RETURN/TBC)) (SETQ RETURNTTC (LIST (create POSITION XCOORD ← X/SW YCOORD ← 0))) [SETQ RETURNBTC (LIST (create POSITION XCOORD ← X/SW YCOORD ←(fetch (GRAPHNODE NODEHEIGHT) of GN] (HALF (fetch (GRAPHNODE NODEHEIGHT) of GN]) (BRHC/OFFSET [LAMBDA (N ABSY) (* kvl "30-DEC-81 14:08") (* Adds in all the offsets. See comment on BRHC/LAYOUT/DAUGHTERS.) (DECLARE (USEDFREE NODELST)) (PROG ((GN (FASSOC N NODELST))) (OR GN (ERROR "No GRAPHNODE for NODEID" N)) [SETQ ABSY (IPLUS ABSY (pop (fetch (GRAPHNODE NODEPOSITION) of GN] [replace YCOORD of (fetch (GRAPHNODE NODEPOSITION) of GN) with (IPLUS ABSY (fetch YCOORD of (fetch (GRAPHNODE NODEPOSITION) of GN] (for D in (fetch (GRAPHNODE TONODES) of GN) do (BRHC/OFFSET D ABSY]) (BRHL/LAYOUT [LAMBDA (N X Y MOMLST GN) (* kvl "26-DEC-83 16:36") (* X and Y are the lower left corner of the box that will surround the tree headed by the browsenode N. MOMLST is the mother node inside a cons cell. GN is the graphnode for the nodeid N. It is crucial that the NODEPOSITION be set before recursion because this marks that the node has been laid out already. If in addition, the YCOORD is NIL, then the node is still in the process of being laid out. BRHL/LAYOUT/DAUGHTERS uses this fact to break loops by inserting boxed nodes.) (DECLARE (USEDFREE MOTHERD PERSONALD NODELST)) (COND ((fetch (GRAPHNODE NODEPOSITION) of GN) (* This case only occurs if this node has been put in the roots list, and has already been visited by recursion. Value won't be used) 0) (T (PROG [(DS (fetch (GRAPHNODE TONODES) of GN)) (W (fetch (GRAPHNODE NODEWIDTH) of GN)) (YHEIGHT (IPLUS PERSONALD (fetch (GRAPHNODE NODEHEIGHT) of GN] (replace (GRAPHNODE FROMNODES) of GN with MOMLST) (* This is first time for layout, so set FROMNODES) [replace (GRAPHNODE NODEPOSITION) of GN with (create POSITION XCOORD ←(IPLUS X (HALF W] (AND DS (SETQ YHEIGHT (IMAX (BRHL/LAYOUT/DAUGHTERS DS (IPLUS X W MOTHERD) Y (LIST N)) YHEIGHT))) (replace YCOORD of (fetch (GRAPHNODE NODEPOSITION) of GN) with (IPLUS Y (HALF YHEIGHT)) ) (RETURN YHEIGHT]) (BRHL/LAYOUT/DAUGHTERS [LAMBDA (DS X Y MOMLST) (* kvl "26-DEC-83 16:14") (* DS are the daughters of (CAR MOMLST). X is where their the left edge of their labels will be, and Y is the bottom of the mother's box. Returns the height of the mother's box. Tests to see if a node has been laid out out already If so, it sees if the node is far enought to the right; if not it moves the node and its daughters.) (DECLARE (USEDFREE NODELST YHEIGHT)) (for DTAIL on DS bind D GN NP DELTA (FLOOR ← Y) finally (RETURN (IDIFFERENCE FLOOR Y)) do (SETQ GN (GETNODEFROMID (SETQ D (CAR DTAIL)) NODELST)) (COND ((SETQ NP (fetch (GRAPHNODE NODEPOSITION) of GN)) [COND [(NULL (fetch YCOORD of NP)) (SETQ GN (NEW/INSTANCE/OF/GRAPHNODE GN)) (RPLACA DTAIL (fetch NODEID of GN)) (SETQ FLOOR (IPLUS FLOOR (BRHL/LAYOUT (fetch NODEID of GN) X FLOOR MOMLST GN] (T (BRHL/MOVE/RIGHT GN X NIL) (push (fetch (GRAPHNODE FROMNODES) of GN) (CAR MOMLST] (* Add this mother to the fromLinks) ) (T (SETQ FLOOR (IPLUS FLOOR (BRHL/LAYOUT D X FLOOR MOMLST GN]) (BRHL/MOVE/RIGHT [LAMBDA (GN X STACK) (* kvl "26-DEC-83 16:25") (* Move this node and its children right) (DECLARE (USEDFREE NODELST)) (PROG ((W (fetch (GRAPHNODE NODEWIDTH) of GN)) (NP (fetch NODEPOSITION of GN))) (AND (FMEMB GN STACK) (ERROR "Loop caught in BRHL/MOVE/RIGHT at" (fetch NODELABEL of GN))) (COND ((ILESSP X (IDIFFERENCE (fetch XCOORD of NP) (HALF W))) (RETURN))) (for D in (TOLINKS GN) bind (NEWX ←(IPLUS X W MOTHERD)) (NSTACK ←(CONS GN STACK)) do (BRHL/MOVE/RIGHT (GETNODEFROMID D NODELST) NEWX NSTACK)) (replace XCOORD of NP with (IPLUS X (HALF W]) (BROWSE/LAYOUT/HORIZ [LAMBDA (ROOTIDS) (* kvl "10-Aug-84 19:56") (* each subtree is given a box centered vertically on its label. Sister boxes abut but do not intrude as they do in the compacting version.) (DECLARE (USEDFREE NODELST)) [for N in ROOTIDS bind (Y ← 0) do (SETQ Y (IPLUS Y (BRH/LAYOUT N 0 Y NIL (GETNODEFROMID N NODELST] (create GRAPH GRAPHNODES ← NODELST SIDESFLG ← T DIRECTEDFLG ← NIL]) (BROWSE/LAYOUT/HORIZ/COMPACTLY [LAMBDA (ROOTS) (DECLARE (USEDFREE NODELST MOTHERD)) (* kvl "10-Aug-84 19:56") (* See comments on BRH/LAYOUT and BRH/LAYOUT/DAUGHTERS first. This differs in that it keeps (on the stack) a representation of the shape of the tree that fills the node's box. The representation is a list of POSITIONs. If one starts drawing a line from left to right starting at the CAR, each point is a step in the line, and the point begins the new plateau (or valley). The last point is where the line would turn around and head back to the left.) (* builds dummy top node for ROOTS if necessary, and adjusts the horizontal distance accordingly.) [PROG (RETURNTTC RETURNBTC) (DECLARE (SPECVARS RETURNTTC RETURNBTC)) (COND ((NLISTP ROOTS) (BRHC/LAYOUT ROOTS 0 NIL (GETNODEFROMID ROOTS NODELST)) (BRHC/OFFSET ROOTS 0)) ((NULL (CDR ROOTS)) (BRHC/LAYOUT (CAR ROOTS) 0 NIL (GETNODEFROMID (CAR ROOTS) NODELST)) (BRHC/OFFSET (CAR ROOTS) 0)) (T (PROG ((GN (create GRAPHNODE NODELABEL ←(PACK) NODEID ←(CONS) TONODES ← ROOTS NODEWIDTH ← 0 NODEHEIGHT ← 0)) TOPNODE) (push NODELST GN) (SETQ TOPNODE (fetch (GRAPHNODE NODEID) of GN)) (BRHC/LAYOUT TOPNODE (IMINUS MOTHERD) NIL GN) (BRHC/OFFSET TOPNODE 0) [for N GN in ROOTS do (replace (GRAPHNODE FROMNODES) of (SETQ GN (FASSOC N NODELST)) with (DREMOVE TOPNODE (fetch (GRAPHNODE FROMNODES) of GN] (SETQ NODELST (DREMOVE GN NODELST] (create GRAPH GRAPHNODES ← NODELST SIDESFLG ← T DIRECTEDFLG ← NIL]) (BROWSE/LAYOUT/LATTICE [LAMBDA (NS) (* kvl "10-Aug-84 19:56") (* almost the same as BROWSE/LAYOUT/HORIZ, except that it doesn't box nodes unless there are cycles. Instead, a single node is placed at the rightmost of the positions that would be laid out by for all of its (boxed) occurrences by BROWSE/LAYOUT/HORIZ.) (DECLARE (USEDFREE NODELST)) [for N in NS bind (Y ← 0) do (SETQ Y (IPLUS Y (BRHL/LAYOUT N 0 Y NIL (GETNODEFROMID N NODELST] (create GRAPH GRAPHNODES ← NODELST SIDESFLG ← T DIRECTEDFLG ← NIL]) (BRV/OFFSET [LAMBDA (N ABSX) (* kvl "31-DEC-81 16:03") (* Adds in offset which are kept in car of NODEPOSITION. TERMY is Y of lowest node. Adding it in raises tree so lowest node is at zero.) (DECLARE (USEDFREE NODELST TERMY)) (PROG ((GN (FASSOC N NODELST)) P) (OR GN (ERROR "No GRAPHNODE for NODEID" N)) [SETQ ABSX (IPLUS ABSX (pop (fetch (GRAPHNODE NODEPOSITION) of GN] (replace XCOORD of (SETQ P (fetch (GRAPHNODE NODEPOSITION) of GN)) with (IPLUS ABSX (fetch XCOORD of P))) (replace YCOORD of P with (IDIFFERENCE (fetch YCOORD of P) TERMY)) (for D in (fetch (GRAPHNODE TONODES) of GN) do (BRV/OFFSET D ABSX]) (EXTEND/TRANSITION/CHAIN [LAMBDA (LTC RTC) (* kvl "21-DEC-83 11:00") (* Extends the left transition chain by appending the part of the right transition chain that is to the right of the end of the left transition chain. End point of left transition chain is changed to intersect right transition chain) (PROG ((LTAIL LTC) (RTAIL RTC) LX RX) L [COND ((NULL (CDR RTAIL)) (replace YCOORD of (CAR (FLAST LTAIL)) with (fetch YCOORD of (CAR RTAIL))) (RETURN LTC)) ((NULL (CDR LTAIL)) (RPLACD LTAIL (CDR RTAIL)) (replace YCOORD of (CAR LTAIL) with (fetch YCOORD of (CAR RTAIL))) (RETURN LTC)) ([IEQP (SETQ LX (fetch XCOORD of (CADR LTAIL))) (SETQ RX (fetch XCOORD of (CADR RTAIL] (SETQ LTAIL (CDR LTAIL)) (SETQ RTAIL (CDR RTAIL))) ((ILESSP LX RX) (SETQ LTAIL (CDR LTAIL))) (T (SETQ RTAIL (CDR RTAIL] (GO L]) (FOREST/BREAK/CYCLES [LAMBDA (NODE) (* kvl "14-Aug-84 09:19") (* Breaks any cycles by inserting new nodes and boxing) (DECLARE (USEDFREE NODELST)) (replace (GRAPHNODE NODEPOSITION) of NODE with T) (for DTAIL DN on (fetch (GRAPHNODE TONODES) of NODE) do (SETQ DN (GETNODEFROMID (CAR DTAIL) NODELST)) (COND ((fetch (GRAPHNODE NODEPOSITION) of DN) (* We've seen this before) (SETQ DN (NEW/INSTANCE/OF/GRAPHNODE DN)) (RPLACA DTAIL (fetch (GRAPHNODE NODEID) of DN))) (T (FOREST/BREAK/CYCLES DN]) (INIT/NODES/FOR/LAYOUT [LAMBDA (NS FORMAT ROOTIDS FONT) (* hdj " 5-Sep-84 10:37") (for GN in NS do [replace (GRAPHNODE NODEPOSITION) of GN with (NOT (NOT (FMEMB (fetch (GRAPHNODE NODEID) of GN) ROOTIDS] (* T Used to indicate prior visitation. Roots are already visited) (OR (fetch (GRAPHNODE NODEFONT) of GN) (replace (GRAPHNODE NODEFONT) of GN with FONT))) [for R in ROOTIDS do (COND ((FMEMB 'LATTICE FORMAT) (LATTICE/BREAK/CYCLES (GETNODEFROMID R NODELST) NIL)) (T (FOREST/BREAK/CYCLES (GETNODEFROMID R NODELST] (for GN in NODELST do (replace (GRAPHNODE NODEPOSITION) of GN with NIL) (SET/LABEL/SIZE GN]) (INTERPRET/MARK/FORMAT [LAMBDA (FORMAT) (* kvl " 5-Sep-84 17:29") (* sets specvars for NEW/INSTANCE/OF/GRAPHNODE and MARK/GRAPH/NODE) (DECLARE (SPECVARS BOX/BOTH/FLG BOX/LEAVES/FLG BORDER/FOR/MARKING LABELSHADE/FOR/MARKING)) (PROG (PL) (AND (EQMEMB (QUOTE COPIES/ONLY) FORMAT) (SETQ BOX/BOTH/FLG NIL)) (AND (EQMEMB (QUOTE NOT/LEAVES) FORMAT) (SETQ BOX/LEAVES/FLG NIL)) (COND ((NLISTP FORMAT) (RETURN)) ((EQ (CAR FORMAT) (QUOTE MARK)) (SETQ PL (CDR FORMAT))) ((SETQ PL (FASSOC (QUOTE MARK) FORMAT)) (SETQ PL (CDR PL))) (T (RETURN))) [COND [(FMEMB (QUOTE BORDER) PL) (SETQ BORDER/FOR/MARKING (LISTGET PL (QUOTE BORDER] (T (SETQ BORDER/FOR/MARKING (QUOTE DON'T] (COND [(FMEMB (QUOTE LABELSHADE) PL) (SETQ LABELSHADE/FOR/MARKING (LISTGET PL (QUOTE LABELSHADE] (T (SETQ LABELSHADE/FOR/MARKING (QUOTE DON'T]) (LATTICE/BREAK/CYCLES [LAMBDA (NODE STACK) (* kvl "14-Aug-84 09:14") (replace (GRAPHNODE NODEPOSITION) of NODE with T) (for DTAIL on (fetch (GRAPHNODE TONODES) of NODE) bind D GN do (SETQ GN (GETNODEFROMID (SETQ D (CAR DTAIL)) NODELST)) (COND ((FMEMB D STACK) (SETQ GN (NEW/INSTANCE/OF/GRAPHNODE GN)) (RPLACA DTAIL (fetch NODEID of GN))) ((NULL (fetch (GRAPHNODE NODEPOSITION) of GN)) (LATTICE/BREAK/CYCLES GN (CONS D STACK]) (LAYOUTFOREST [LAMBDA (NODELST ROOTIDS FORMAT BOXING FONT MOTHERD PERSONALD FAMILYD) (* rmk: " 2-Feb-84 16:55") (* This is an older version of LayoutGraph, kept around temporarily but de-documented) (LAYOUTGRAPH NODELST ROOTIDS (CONS FORMAT BOXING) FONT MOTHERD PERSONALD]) (LAYOUTGRAPH [LAMBDA (NODELST ROOTIDS FORMAT FONT MOTHERD PERSONALD FAMILYD) (* rmk: "15-Sep-84 00:15") (* takes a list of GRAPHNODE records and a list node ids for the top level nodes, where the graphnodes have only the NODEID, NODELABEL and TONODES fields filled in. It fills in the other fields appropriately according the format switch and the boxing switch so that the graph becomes a forest. If there are loops in the graph, they are snapped and the NODELST is extended with Push This function returns a GRAPH record with the display slots filled in appropriately.) (DECLARE (SPECVARS NODELST MOTHERD PERSONALD FAMILYD)) (PROG ((BOX/BOTH/FLG T) (BOX/LEAVES/FLG T) (BORDER/FOR/MARKING T) (LABELSHADE/FOR/MARKING (QUOTE DON'T)) G) (DECLARE (SPECVARS BOX/BOTH/FLG BOX/LEAVES/FLG BORDER/FOR/MARKING LABELSHADE/FOR/MARKING)) (OR (LISTP ROOTIDS) (ERROR "LAYOUTGRAPH needs a LIST of root node ids")) (for R in ROOTIDS unless (FASSOC R NODELST) do (ERROR R "is in ROOTIDS but no GRAPHNODE for it in NODELST.")) (OR FONT (SETQ FONT DEFAULTFONT)) (OR MOTHERD (SETQ MOTHERD (STRINGWIDTH "AAAAAA" FONT))) [OR PERSONALD (SETQ PERSONALD (COND ((EQMEMB (QUOTE VERTICAL) FORMAT) (STRINGWIDTH "AA" FONT)) (T 0] [OR FAMILYD (SETQ FAMILYD (HALF (FONTPROP FONT (QUOTE ASCENT] (INTERPRET/MARK/FORMAT FORMAT) (INIT/NODES/FOR/LAYOUT NODELST FORMAT ROOTIDS FONT) (AND (EQMEMB (QUOTE VERTICAL) FORMAT) (SWITCH/NODE/HEIGHT/WIDTH NODELST)) [SETQ G (COND ((EQMEMB (QUOTE LATTICE) FORMAT) (BROWSE/LAYOUT/LATTICE ROOTIDS)) ((EQMEMB (QUOTE FAST) FORMAT) (BROWSE/LAYOUT/HORIZ ROOTIDS)) (T (BROWSE/LAYOUT/HORIZ/COMPACTLY ROOTIDS] [for N in NODELST do (OR (type? POSITION (fetch NODEPOSITION of N)) (ERROR "Disconnected graph. Root(s) didn't connect to:" (fetch NODELABEL of N] [COND ((EQMEMB (QUOTE VERTICAL) FORMAT) (SWITCH/NODE/HEIGHT/WIDTH NODELST) (REFLECT/GRAPH/DIAGONALLY G) (OR (EQMEMB (QUOTE REVERSE) FORMAT) (REFLECT/GRAPH/VERTICALLY G)) (AND (EQMEMB (QUOTE REVERSE/DAUGHTERS) FORMAT) (REFLECT/GRAPH/HORIZONTALLY G))) (T (AND (EQMEMB (QUOTE REVERSE) FORMAT) (REFLECT/GRAPH/HORIZONTALLY G)) (AND (EQMEMB (QUOTE REVERSE/DAUGHTERS) FORMAT) (REFLECT/GRAPH/VERTICALLY G] (RETURN G]) (LAYOUTLATTICE [LAMBDA (NODELST ROOTIDS FORMAT FONT MOTHERD PERSONALD FAMILYD) (* rmk: "15-Sep-84 00:15") (* takes a list of GRAPHNODE records and a list node ids for the top level nodes, where the graphnodes have only the NODEID, NODELABEL and TONODES fields filled in. It fills in the other fields appropriately according the format switch If there are loops in the graph, they are detected in BRHL/MOVE/RIGHT and an error occurs. This function returns a GRAPH record with the display slots filled in appropriately.) (DECLARE (SPECVARS NODELST MOTHERD PERSONALD FAMILYD)) (for R in ROOTIDS unless (FASSOC R NODELST) do (ERROR R "is in ROOTIDS but no GRAPHNODE for it in NODELST.")) (SETQ FONT (OR FONT DEFAULTFONT)) (INIT/NODES/FOR/LAYOUT NODELST ROOTIDS FORMAT FONT) [OR FAMILYD (SETQ FAMILYD (HALF (FONTPROP FONT (QUOTE ASCENT] (OR MOTHERD (SETQ MOTHERD (STRINGWIDTH "AAAAAA" FONT))) [OR PERSONALD (SETQ PERSONALD (COND ((EQ FORMAT (QUOTE VERTICAL)) (STRINGWIDTH "AA" FONT)) (T 0] (BROWSE/LAYOUT/LATTICE ROOTIDS]) (LAYOUTSEXPR [LAMBDA (TREE FORMAT BOXING FONT MOTHERD PERSONALD FAMILYD) (* rmk: "10-Apr-84 12:15") (* assumes CAR of tree is node label, CDR is daughter trees.) (PROG (RESULT) (DECLARE (SPECVARS RESULT)) (LAYOUTSEXPR1 TREE) (RETURN (LAYOUTGRAPH RESULT (LIST TREE) (APPEND (MKLIST FORMAT) BOXING) FONT MOTHERD PERSONALD FAMILYD]) (LAYOUTSEXPR1 [LAMBDA (TREE) (* kvl "28-APR-82 10:21") (DECLARE (SPECVARS RESULT)) (COND ((NULL TREE)) [(for R in RESULT thereis (EQ TREE (fetch (GRAPHNODE NODEID) of R] ((NLISTP TREE) (push RESULT (create GRAPHNODE NODEID ← TREE NODELABEL ← TREE))) (T [push RESULT (create GRAPHNODE NODEID ← TREE NODELABEL ←(CAR TREE) TONODES ←(APPEND (CDR TREE] (for D in (CDR TREE) do (LAYOUTSEXPR1 D]) (MARK/GRAPH/NODE [LAMBDA (NODE) (* rmk: "15-Sep-84 00:18") (* changes appearance of graph node to indicate that a link has been snapped.) (DECLARE (USEDFREE BORDER/FOR/MARKING LABELSHADE/FOR/MARKING)) (OR (EQ BORDER/FOR/MARKING (QUOTE DON'T)) (replace NODEBORDER of NODE with BORDER/FOR/MARKING)) (OR (EQ LABELSHADE/FOR/MARKING (QUOTE DON'T)) (replace NODELABELSHADE of NODE with LABELSHADE/FOR/MARKING]) (NEW/INSTANCE/OF/GRAPHNODE [LAMBDA (GN) (DECLARE (USEDFREE NODELST BOX/LEAVES/FLG BOX/BOTH/FLG)) (* kvl " 5-Sep-84 16:30") (* returns a second instance of the node, boxing it appropriately. No daughters.) (PROG [(NEW (create GRAPHNODE NODEID ←(LIST (fetch (GRAPHNODE NODEID) of GN)) NODELABEL ←(fetch (GRAPHNODE NODELABEL) of GN) NODEFONT ←(fetch (GRAPHNODE NODEFONT) of GN) NODEWIDTH ←(fetch (GRAPHNODE NODEWIDTH) of GN) NODEHEIGHT ←(fetch (GRAPHNODE NODEHEIGHT) of GN) NODEBORDER ←(COPY (fetch (GRAPHNODE NODEBORDER) of GN)) NODELABELSHADE ←(fetch NODELABELSHADE of GN] (push NODELST NEW) [COND ((OR BOX/LEAVES/FLG (fetch (GRAPHNODE TONODES) of GN)) (MARK/GRAPH/NODE NEW) (COND (BOX/BOTH/FLG (MARK/GRAPH/NODE GN] (RETURN NEW]) (RAISE/TRANSITION/CHAIN [LAMBDA (TC RAISE) (* kvl "21-DEC-83 10:25") (* raises a daughters transition chain by adding in the offset of the daughter's box relative to the mother's box.) (for P in TC do (add (fetch YCOORD of P) RAISE) finally (RETURN TC]) (REFLECT/GRAPH/DIAGONALLY [LAMBDA (GRAPH) (* kvl "26-DEC-83 10:58") (replace (GRAPH SIDESFLG) of GRAPH with (NOT (fetch (GRAPH SIDESFLG) of GRAPH))) [for N in (fetch (GRAPH GRAPHNODES) of GRAPH) do (SETQ N (fetch (GRAPHNODE NODEPOSITION) of N)) (replace XCOORD of N with (PROG1 (fetch YCOORD of N) (replace YCOORD of N with (fetch XCOORD of N] GRAPH]) (REFLECT/GRAPH/HORIZONTALLY [LAMBDA (GRAPH) (* kvl "10-Aug-84 17:23") (for N in (fetch (GRAPH GRAPHNODES) of GRAPH) bind [W ←(IPLUS (MAX/RIGHT (fetch (GRAPH GRAPHNODES) of GRAPH)) (MIN/LEFT (fetch (GRAPH GRAPHNODES) of GRAPH] do (SETQ N (fetch (GRAPHNODE NODEPOSITION) of N)) (replace XCOORD of N with (IDIFFERENCE W (fetch XCOORD of N]) (REFLECT/GRAPH/VERTICALLY [LAMBDA (GRAPH) (* kvl "10-Aug-84 16:48") (for N in (fetch (GRAPH GRAPHNODES) of GRAPH) bind [H ←(IPLUS (MAX/TOP (fetch (GRAPH GRAPHNODES) of GRAPH)) (MIN/BOTTOM (fetch (GRAPH GRAPHNODES) of GRAPH] do (SETQ N (fetch (GRAPHNODE NODEPOSITION) of N)) (replace YCOORD of N with (IDIFFERENCE H (fetch YCOORD of N]) (SWITCH/NODE/HEIGHT/WIDTH [LAMBDA (NL) (* rmk: " 2-Feb-84 22:19") (for N in NL do (swap (fetch (GRAPHNODE NODEWIDTH) of N) (fetch (GRAPHNODE NODEHEIGHT) of N]) ) (RPAQQ DEFAULT.GRAPH.NODEBORDER NIL) (RPAQQ DEFAULT.GRAPH.NODEFONT NIL) (RPAQQ DEFAULT.GRAPH.NODELABELSHADE NIL) (RPAQQ CACHE/NODE/LABEL/BITMAPS NIL) (RPAQQ EDITGRAPHMENU NIL) (RPAQQ GRAPHEDITWINDOW NIL) (RPAQQ NODEBORDERWIDTH 1) (RPAQ ORIGIN (CREATEPOSITION 0 0)) (MOVD? (FUNCTION NILL) (FUNCTION IMAGEOBJP) T) (DECLARE: DOEVAL@COMPILE DONTCOPY (LOCALVARS) ) (DECLARE: DOEVAL@COMPILE DONTCOPY (GLOBALVARS EDITGRAPHMENU GRAPHEDITWINDOW NODEBORDERWIDTH ORIGIN) ) [DECLARE: EVAL@COMPILE (RECORD GRAPHNODE (NODEID NODEPOSITION NODELABELBITMAP NIL NODELABELSHADE NODEWIDTH NODEHEIGHT TONODES FROMNODES NODEFONT NODELABEL NODEBORDER) NODEBORDER ← DEFAULT.GRAPH.NODEBORDER NODELABELSHADE ← DEFAULT.GRAPH.NODELABELSHADE NODEFONT ← DEFAULT.GRAPH.NODEFONT) (RECORD GRAPH (GRAPHNODES SIDESFLG DIRECTEDFLG GRAPH.MOVENODEFN GRAPH.ADDNODEFN GRAPH.DELETENODEFN GRAPH.ADDLINKFN GRAPH.DELETELINKFN GRAPH.FONTCHANGEFN GRAPH.INVERTBORDERFN GRAPH.INVERTLABELFN)) ] (DECLARE: DONTCOPY (DECLARE: EVAL@COMPILE (PUTPROPS HALF MACRO ((X) (LRSH X 1))) ) ) (PUTPROPS GRAPHER COPYRIGHT ("Xerox Corporation" 1983 1984 1985)) (DECLARE: DONTCOPY (FILEMAP (NIL (3392 68648 (ADD/AND/DISPLAY/LINK 3402 . 3943) (APPLYTOSELECTEDNODE 3945 . 6310) ( CALL.MOVENODEFN 6312 . 6666) (CHANGE.NODEFONT.SIZE 6668 . 7655) (CHOOSE.GRAPH.FONT 7657 . 8089) ( CLOSEST/NODE 8091 . 8707) (DEFAULT.ADDNODEFN 8709 . 9446) (DELETE/AND/DISPLAY/LINK 9448 . 10370) ( DISPLAY/NAME 10372 . 10517) (DISPLAYGRAPH 10519 . 12023) (DISPLAYLINK 12025 . 14048) (DISPLAYLINK/LR 14050 . 14796) (DISPLAYLINK/TB 14798 . 15544) (EDITTOGGLEBORDER 15546 . 16659) (ERASE/GRAPHNODE 16661 . 17502) (DISPLAYNODE 17504 . 17910) (DISPLAYNODELINKS 17912 . 18596) (DRAW/GRAPHNODE/BORDER 18598 . 19808) (DRAWAREABOX 19810 . 21239) (EDITADDLINK 21241 . 21593) (EDITADDNODE 21595 . 22383) ( EDITAPPLYTOLINK 22385 . 23585) (EDITCHANGEFONT 23587 . 24387) (EDITDELETELINK 24389 . 24749) ( EDITDELETENODE 24751 . 26462) (EDITGRAPH 26464 . 27314) (EDITGRAPH1 27316 . 28943) (EDITGRAPHMENU 28945 . 29553) (EDITMOVENODE 29555 . 31076) (EDITTOGGLELABEL 31078 . 32186) (FLIPNODE 32188 . 32702) ( FONTNAMELIST 32704 . 32957) (FROMLINKS 32959 . 33103) (GETNODEFROMID 33105 . 33294) (GN/BOTTOM 33296 . 33530) (GN/LEFT 33532 . 33763) (GN/RIGHT 33765 . 34178) (GN/TOP 34180 . 34644) (GRAPHADDLINK 34646 . 35147) (GRAPHADDNODE 35149 . 35761) (GRAPHDELETELINK 35763 . 36379) (GRAPHDELETENODE 36381 . 36771) (GRAPHEDITCOMMANDFN 36773 . 38295) (GRAPHEDITEVENTFN 38297 . 38936) (GRAPHER/CENTERPRINTINAREA 38938 . 39764) (GRAPHMOVENODE 39766 . 40262) (GRAPHNODE/BORDER/WIDTH 40264 . 40773) (GRAPHREGION 40775 . 41618) (HARDCOPYGRAPH 41620 . 42006) (INTERSECT/REGIONP/LBWH 42008 . 42540) (INVERTED/GRAPHNODE/BORDER 42542 . 43080) (INVERTED/SHADE/FOR/GRAPHER 43082 . 43715) (LAYOUT/POSITION 43717 . 43870) ( MANHATTANDIST 43872 . 44292) (MAX/RIGHT 44294 . 44499) (MAX/TOP 44501 . 44702) (MEASUREGRAPHNODE 44704 . 45095) (MIN/BOTTOM 45097 . 45417) (MIN/LEFT 45419 . 45733) (MOVENODE 45735 . 46644) (NODECREATE 46646 . 47209) (NODELST/AS/MENU 47211 . 48012) (NODEREGION 48014 . 48393) (PRINTDISPLAYNODE 48395 . 51727) (FILL/GRAPHNODE/LABEL 51729 . 52494) (PROMPTINWINDOW 52496 . 54834) (READ/NODE 54836 . 55579) ( REDISPLAYGRAPH 55581 . 56041) (RESET/NODE/BORDER 56043 . 57230) (RESET/NODE/LABELSHADE 57232 . 57951) (SCALE/GRAPH 57953 . 58948) (SCALE/GRAPHNODE/BORDER 58950 . 59554) (SET/LABEL/SIZE 59556 . 61574) ( SET/LAYOUT/POSITION 61576 . 62009) (SHIFTP 62011 . 62283) (SHOWGRAPH 62285 . 64011) (SIZE/GRAPH/WINDOW 64013 . 65700) (TOGGLE/DIRECTEDFLG 65702 . 66274) (TOGGLE/SIDESFLG 66276 . 66889) (TOLINKS 66891 . 67031) (TRACKCURSOR 67033 . 68098) (TRACKNODE 68100 . 68646)) (68649 68909 ( DEFAULTGRAPHERCOPYBUTTONEVENTFN 68659 . 68907)) (69109 71350 (NEXTSIZEFONT 69119 . 70223) ( DECREASING.FONT.LIST 70225 . 70645) (SCALE.FONT 70647 . 71348)) (71568 103887 (BRH/LAYOUT 71578 . 73060) (BRH/LAYOUT/DAUGHTERS 73062 . 73847) (BRH/OFFSET 73849 . 74248) (BRHC/INTERTREE/SPACE 74250 . 75498) (BRHC/LAYOUT 75500 . 77087) (BRHC/LAYOUT/DAUGHTERS 77089 . 79594) (BRHC/LAYOUT/TERMINAL 79596 . 80241) (BRHC/OFFSET 80243 . 81033) (BRHL/LAYOUT 81035 . 82778) (BRHL/LAYOUT/DAUGHTERS 82780 . 84138 ) (BRHL/MOVE/RIGHT 84140 . 85044) (BROWSE/LAYOUT/HORIZ 85046 . 85594) (BROWSE/LAYOUT/HORIZ/COMPACTLY 85596 . 87613) (BROWSE/LAYOUT/LATTICE 87615 . 88281) (BRV/OFFSET 88283 . 89175) ( EXTEND/TRANSITION/CHAIN 89177 . 90344) (FOREST/BREAK/CYCLES 90346 . 91108) (INIT/NODES/FOR/LAYOUT 91110 . 92054) (INTERPRET/MARK/FORMAT 92056 . 93347) (LATTICE/BREAK/CYCLES 93349 . 93977) ( LAYOUTFOREST 93979 . 94419) (LAYOUTGRAPH 94421 . 97384) (LAYOUTLATTICE 97386 . 98674) (LAYOUTSEXPR 98676 . 99259) (LAYOUTSEXPR1 99261 . 99874) (MARK/GRAPH/NODE 99876 . 100486) ( NEW/INSTANCE/OF/GRAPHNODE 100488 . 101565) (RAISE/TRANSITION/CHAIN 101567 . 102015) ( REFLECT/GRAPH/DIAGONALLY 102017 . 102551) (REFLECT/GRAPH/HORIZONTALLY 102553 . 103081) ( REFLECT/GRAPH/VERTICALLY 103083 . 103627) (SWITCH/NODE/HEIGHT/WIDTH 103629 . 103885))))) STOP