(FILECREATED "11-Dec-85 11:51:29" {PHYLUM}<PAPERWORKS>SKETCH.;218 440786 changes to: (FNS SK.BUILD.CACHE SKETCH.RESET SK.MOVE.ELEMENTS SKETCHW.CREATE SK.COPY.BUTTONEVENTFN SK.SEL.AND.CHANGE SK.SEL.AND.MAKE SK.SEL.AND.DELETE SK.SEL.AND.DELETE.KNOT SK.SEL.AND.COPY SK.SEL.AND.MOVE SK.SELECT.MULTIPLE.POINTS SK.SEL.AND.GROUP SK.GROUP.ELEMENTS SK.SEL.AND.UNGROUP SK.UNGROUP.ELEMENT SK.GROUP.UNDO SK.UNGROUP.UNDO SK.SEL.AND.TRANSFORM SK.SEL.AND.TWO.PT.TRANSFORM SK.SEL.AND.THREE.PT.TRANSFORM SK.SEL.COPY.AND.TWO.PT.TRANSFORM SK.SEL.COPY.AND.THREE.PT.TRANSFORM SK.SELECT.ITEM SK.SELECT.MULTIPLE.ITEMS SK.TYPE.OF.FIRST.ARG SK.HOTSPOT.CACHE.FOR.OPERATION SKETCH.SET.A.DEFAULT GROUP.DRAWFN GROUP.EXPANDFN GROUP.REGIONFN SK.DO.GROUP SK.UPDATE.ELEMENT1 SK.DELETE.ELEMENT SKETCH.ADD.ELEMENT SK.CHECK.WHENEDITEDFN SK.CHECK.PREEDITFN READ.POINT.TO.ADD SK.CHECK.WHENPOINTDELETEDFN) (VARS SKETCHCOMS) (PROPS (GROUP EVENTFNS) (UNGROUP EVENTFNS)) (RECORDS LOCALGROUP) previous date: " 5-Dec-85 18:23:25" {PHYLUM}<PAPERWORKS>SKETCH.;210) (* Copyright (c) 1984, 1985 by Xerox Corporation. All rights reserved.) (PRETTYCOMPRINT SKETCHCOMS) (RPAQQ SKETCHCOMS [[DECLARE: FIRST DOCOPY DONTEVAL@LOAD (P (PROG ((NOTECARDSFLG (GETPROP (QUOTE NOTECARDS) (QUOTE FILEDATES))) (SKETCHFLG (AND (BOUNDP (QUOTE ALL.SKETCHES)) ALL.SKETCHES)) TEDITFLG) (* current knows about SKETCH TEDIT and NOTECARDS. Everyone else loses.) [MAP.PROCESSES (FUNCTION (LAMBDA (PROC PROCNAME PROCFORM) (AND (EQ (CAR PROCFORM) (QUOTE \TEDIT2)) (SETQ TEDITFLG T] (COND ((AND (BOUNDP (QUOTE ALL.SKETCHES)) (OR SKETCHFLG NOTECARDSFLG TEDITFLG)) (ERROR (CONCAT "Please close" (COND (SKETCHFLG " all open Sketch windows,") (T "")) (COND (NOTECARDSFLG (CONCAT (COND (SKETCHFLG " and") (T "")) " any open notefiles,")) (T "")) (COND (TEDITFLG (CONCAT (COND ((OR SKETCHFLG NOTECARDSFLG) " and") (T "")) " any TEDIT windows that have sketches in them,")) (T "")) " then type 'RETURN'. To abort loading the new version of Sketch, type '↑'."] (FNS SKETCH.TEST) (FNS DRAW.LOCAL.SKETCH SKETCHW.CREATE SKETCH.RESET SKETCHW.FIG.CHANGED SK.WINDOW.TITLE EDITSLIDE EDITSKETCH SK.FIX.MENU SK.PUT.ON.FILE SK.GET.FROM.FILE SK.ADD.ELEMENTS.TO.SKETCH STATUSPRINT CLEARPROMPTWINDOW CLOSEPROMPTWINDOW MYGETPROMPTWINDOW PROMPT.GETINPUT SK.INSURE.HAS.MENU SKETCH.SET.A.DEFAULT SK.POPUP.SELECTIONFN GETSKETCHWREGION READ.FUNCTION READBRUSHSIZE READANGLE READARCDIRECTION SK.ADD.ELEMENT SK.ADD.ELEMENTS SK.CHECK.WHENADDEDFN SK.APPLY.MENU.COMMAND SK.DELETE.ELEMENT1 SK.MARK.DIRTY SK.MARK.UNDIRTY SK.MENU.AND.RETURN.FIELD SK.SCALE.POSITION.INTO.VIEWER SKETCH.SET.BRUSH.SHAPE SKETCH.SET.BRUSH.SIZE SKETCHW.CLOSEFN SKETCHW.OUTFN SKETCHW.REOPENFN MAKE.LOCAL.SKETCH MAP.SKETCHSPEC.INTO.VIEWER SKETCHW.REPAINTFN SKETCHW.REPAINTFN1 SK.DRAWFIGURE.IF SKETCHW.SCROLLFN SK.UPDATE.EVENT.SELECTION LIGHTGRAYWINDOW SK.ADD.SPACES SK.SKETCH.MENU SK.CHECK.IMAGEOBJ.WHENDELETEDFN SK.APPLY.IMAGEOBJ.WHENDELETEDFN SK.RETURN.TTY SK.TAKE.TTY) (COMS (* fns for dealing with the menu) (FNS SKETCH.COMMANDMENU SKETCH.COMMANDMENU.ITEMS CREATE.SKETCHW.COMMANDMENU SKETCHW.SELECTIONFN)) (COMS (* fns for dealing with sketch structures) (FNS SKETCH.CREATE GETSKETCHPROP PUTSKETCHPROP CREATE.DEFAULT.SKETCH.CONTEXT) (PROP ARGNAMES SKETCH.CREATE)) (COMS (* fns for implementing copy and delete functions under keyboard control.) (FNS SK.COPY.BUTTONEVENTFN SK.BUTTONEVENT.MARK SK.BUILD.IMAGEOBJ SK.BUTTONEVENT.OVERP SK.BUTTONEVENT.SAME.KEYS) (MACROS .DELETEKEYDOWNP. .MOVEKEYDOWNP.)) (* functions for changing elements.) (FNS SK.SEL.AND.CHANGE SK.CHANGE.ELT SK.CHANGE.THING SK.CHANGEFN SK.READCHANGEFN SK.DEFAULT.CHANGEFN CHANGEABLEFIELDITEMS SK.SEL.AND.MAKE SK.APPLY.CHANGE.COMMAND SK.ELEMENTS.CHANGEFN READ.POINT.TO.ADD GLOBAL.KNOT.FROM.LOCAL SK.ADD.KNOT.TO.ELEMENT SK.GROUP.CHANGEFN) (* fns for adding elements) [COMS (* fns for adding elements) (FNS ADD.ELEMENT.TO.SKETCH ADD.SKETCH.VIEWER REMOVE.SKETCH.VIEWER ALL.SKETCH.VIEWERS VIEWER.BUCKET ELT.INSIDE.REGION? ELT.INSIDE.SKWP SCALE.FROM.SKW SK.ADDELT.TO.WINDOW SK.CALC.REGION.VIEWED SK.DRAWFIGURE SK.DRAWFIGURE1 SK.LOCAL.FROM.GLOBAL SKETCH.REGION.VIEWED SKETCH.VIEW.FROM.NAME SK.UPDATE.REGION.VIEWED SKETCH.ADD.AND.DISPLAY SKETCH.ADD.AND.DISPLAY1 SK.ADD.ITEM SKETCHW.ADD.INSTANCE) (* put in for backward compatibility. Can be pulled out 6/1/86 rrb.) (P (MOVD? (QUOTE SKETCH.REGION.VIEWED) (QUOTE SK.REGION.VIEWED] (* fns for deleting things) (FNS SK.SEL.AND.DELETE SK.ERASE.AND.DELETE.ITEM REMOVE.ELEMENT.FROM.SKETCH SK.DELETE.ELEMENT SK.DELETE.KNOT SK.SEL.AND.DELETE.KNOT SK.DELETE.ELEMENT.KNOT SK.CHECK.WHENDELETEDFN SK.CHECK.PREEDITFN SK.CHECK.WHENEDITEDFN SK.CHECK.WHENPOINTDELETEDFN SK.ERASE.ELT SK.DELETE.ELT SK.DELETE.ITEM DELFROMTCONC) (* fns for copying stuff) (FNS SK.COPY.ELT SK.SEL.AND.COPY SK.COPY.ELEMENTS SK.GLOBAL.FROM.LOCAL.ELEMENTS SK.COPY.ITEM SK.INSERT.SKETCH) (COMS (* fns for moving things.) (FNS SK.MOVE.ELT SK.MOVE.ELT.OR.PT SK.APPLY.DEFAULT.MOVE SK.SEL.AND.MOVE SK.MOVE.ELEMENTS SKETCH.MOVE.ELEMENTS SK.TRANSLATE.ELEMENT SK.MAKE.ELEMENT.MOVE.ARG SK.MAKE.ELEMENTS.MOVE.ARG SK.MAKE.POINTS.AND.ELEMENTS.MOVE.ARG SK.SHOW.FIG.FROM.INFO SK.MOVE.THING UPDATE.ELEMENT.IN.SKETCH SK.UPDATE.ELEMENT SK.UPDATE.ELEMENTS SK.UPDATE.ELEMENT1 SK.MOVE.ELEMENT.POINT) (* fns for moving points or a collection of pts.) (FNS SK.MOVE.POINTS SK.SEL.AND.MOVE.POINTS SK.DO.MOVE.ELEMENT.POINTS SK.MOVE.ITEM.POINTS SK.TRANSLATEPTSFN SK.TRANSLATE.POINTS SK.SELECT.MULTIPLE.POINTS SK.CONTROL.POINTS.IN.REGION SK.ADD.PT.SELECTION SK.REMOVE.PT.SELECTION SK.ADD.POINT SK.ELTS.CONTAINING.PTS SK.HOTSPOTS.NOT.ON.LIST) (MACROS .SHIFTKEYDOWNP.) (FNS SK.SET.MOVE.MODE SK.SET.MOVE.MODE.POINTS SK.SET.MOVE.MODE.ELEMENTS SK.SET.MOVE.MODE.COMBINED READMOVEMODE)) (COMS (* stuff for supporting the GROUP sketch element.) (FNS SKETCH.CREATE.GROUP SK.CREATE.GROUP1 SK.UPDATE.GROUP.AFTER.CHANGE SK.GROUP.ELTS SK.SEL.AND.GROUP SK.GROUP.ELEMENTS SK.UNGROUP.ELT SK.SEL.AND.UNGROUP SK.UNGROUP.ELEMENT SK.GLOBAL.REGION.OF.LOCAL.ELEMENTS SK.GLOBAL.REGION.OF.GLOBAL.ELEMENTS SKETCH.REGION.OF.SKETCH SK.FLASHREGION) (FNS INIT.GROUP.ELEMENT GROUP.DRAWFN GROUP.EXPANDFN GROUP.INSIDEFN GROUP.REGIONFN GROUP.GLOBALREGIONFN GROUP.TRANSLATEFN GROUP.TRANSFORMFN GROUP.READCHANGEFN) (FNS REGION.CENTER REMOVE.LAST) (RECORDS GROUP LOCALGROUP) (COMS (* history and undo stuff for groups) (FNS SK.DO.GROUP SK.DO.UNGROUP SK.GROUP.UNDO SK.UNGROUP.UNDO) (IFPROP EVENTFNS GROUP UNGROUP))) [COMS (* fns to implement transformations on the elements) (FNS SK.SEL.AND.TRANSFORM SK.TRANSFORM.ELEMENTS SK.TRANSFORM.ITEM SK.TRANSFORM.ELEMENT SK.TRANSFORM.POINT SK.TRANSFORM.POINT.LIST SK.TRANSFORM.REGION SK.PUT.ELTS.ON.GRID SK.TRANSFORM.GLOBAL.ELEMENTS GLOBALELEMENTP SK.TRANSFORM.SCALE.FACTOR SK.TRANSFORM.BRUSH SK.TRANSFORM.ARROWHEADS SCALE.BRUSH) (FNS TWO.PT.TRANSFORMATION.INPUTFN SK.TWO.PT.TRANSFORM.ELTS SK.SEL.AND.TWO.PT.TRANSFORM SK.APPLY.AFFINE.TRANSFORM SK.COMPUTE.TWO.PT.TRANSFORMATION SK.COMPUTE.SLOPE SK.THREE.PT.TRANSFORM.ELTS SK.COMPUTE.THREE.PT.TRANSFORMATION SK.SEL.AND.THREE.PT.TRANSFORM THREE.PT.TRANSFORMATION.INPUTFN) (FNS SK.COPY.AND.TWO.PT.TRANSFORM.ELTS SK.SEL.COPY.AND.TWO.PT.TRANSFORM SK.COPY.AND.THREE.PT.TRANSFORM.ELTS SK.SEL.COPY.AND.THREE.PT.TRANSFORM SK.COPY.AND.TRANSFORM.ELEMENTS SK.COPY.AND.TRANSFORM.ITEM) (DECLARE: DONTCOPY (RECORDS AFFINETRANSFORMATION)) (UGLYVARS FIRSTPTMARK SECONDPTMARK THIRDPTMARK NEWFIRSTPTMARK NEWSECONDPTMARK) (GLOBALVARS FIRSTPTMARK SECONDPTMARK THIRDPTMARK NEWFIRSTPTMARK NEWSECONDPTMARK) (P (COND ((EQ MAKESYSNAME (QUOTE INTERMEZZO)) (FILESLOAD MATRIXUSE)) (T (FILESLOAD MATMULT] (COMS (* programmer interface entries) (FNS SKETCH.ELEMENTS.OF.SKETCH SKETCH.LIST.OF.ELEMENTS SKETCH.ADD.ELEMENT SKETCH.DELETE.ELEMENT DELFROMGROUPELT SKETCH.ELEMENT.TYPE SKETCH.ELEMENT.CHANGED SK.ELEMENT.CHANGED1 SK.UPDATE.GLOBAL.IMAGE.OBJECT.ELEMENT)) (* utility routines for sketch windows.) (FNS INSURE.SKETCH LOCALSPECS.FROM.VIEWER SK.LOCAL.ELT.FROM.GLOBALPART SKETCH.FROM.VIEWER INSPECT.SKETCH) (FNS MAPSKETCHSPECS MAPCOLLECTSKETCHSPECS MAPSKETCHSPECSUNTIL MAPGLOBALSKETCHSPECS MAPGLOBALSKETCHELEMENTS) (COMS (* functions for marking) (FNS SK.SHOWMARKS MARKPOINT SK.MARKHOTSPOTS SK.MARK.SELECTION) (UGLYVARS POINTMARK SPOTMARKER) (GLOBALVARS POINTMARK SPOTMARKER) (CURSORS POINTREADINGCURSOR) (* hit detection functions.) (FNS SK.SELECT.ITEM IN.SKETCH.ELT? SK.MARK.HOTSPOT SK.MARK.POSITION SK.SELECT.ELT SK.DESELECT.ELT) (CONSTANTS (SK.POINT.WIDTH 4)) (* fns to support caching of hotspots.) (FNS SK.HOTSPOT.CACHE SK.HOTSPOT.CACHE.FOR.OPERATION SK.BUILD.CACHE SK.ELEMENT.PROTECTED? SK.HAS.SOME.HOTSPOTS SK.SET.HOTSPOT.CACHE SK.CREATE.HOTSPOT.CACHE SK.ELTS.FROM.HOTSPOT SK.ADD.HOTSPOTS.TO.CACHE SK.ADD.HOTSPOTS.TO.CACHE1 SK.ADD.HOTSPOT.TO.CACHE SK.REMOVE.HOTSPOTS.FROM.CACHE SK.REMOVE.HOTSPOTS.FROM.CACHE1 SK.REMOVE.HOTSPOT.FROM.CACHE SK.REMOVE.VALUE.FROM.CACHE.BUCKET SK.FIND.CACHE.BUCKET SK.ADD.VALUE.TO.CACHE.BUCKET)) (COMS (* multiple selection and copy select functions) (FNS SK.ADD.SELECTION SK.COPY.INSERTFN SK.FIGUREIMAGE SCREENELEMENTP SK.ITEM.REGION SK.ELEMENT.GLOBAL.REGION SK.LOCAL.ITEMS.IN.REGION SK.REGIONFN SK.GLOBAL.REGIONFN SK.REMOVE.SELECTION SK.SELECT.MULTIPLE.ITEMS SK.PUT.MARKS.UP SK.TAKE.MARKS.DOWN SK.TRANSLATE.GLOBALPART SK.TRANSLATE.ITEM SK.TRANSLATEFN TRANSLATE.SKETCH) (CONSTANTS (SK.NO.MOVE.DISTANCE 4)) (DECLARE: DONTCOPY (RECORDS SKFIGUREIMAGE))) (INITVARS (ALLOW.MULTIPLE.SELECTION.FLG T)) (* functions for determining what is inside of a window.) (FNS ELT.INSIDE.SKETCHWP SK.INSIDE.REGION) (COMS (* stuff for changing the input scale) (FNS SK.INPUT.SCALE SK.UPDATE.SKETCHCONTEXT SK.SET.INPUT.SCALE SK.SET.INPUT.SCALE.CURRENT SK.SET.INPUT.SCALE.VALUE)) (COMS (* stuff for setting feedback amount) (FNS SK.SET.FEEDBACK.MODE SK.SET.FEEDBACK.POINT SK.SET.FEEDBACK.VERBOSE SK.SET.FEEDBACK.ALWAYS) (VARS (SKETCH.VERBOSE.FEEDBACK T)) (GLOBALVARS SKETCH.VERBOSE.FEEDBACK)) (COMS (* functions for zooming) (FNS SKETCHW.SCALE SKETCH.ZOOM SAME.ASPECT.RATIO SKETCH.DO.ZOOM SKETCH.NEW.VIEW ZOOM.UPDATE.ELT SK.UPDATE.AFTER.SCALE.CHANGE SKETCH.AUTOZOOM SKETCH.GLOBAL.REGION.ZOOM) (INITVARS (AUTOZOOM.FACTOR .8) (AUTOZOOM.REPAINT.TIME 3000)) (UGLYVARS AUTOZOOMCURSOR ZOOMINCURSOR ZOOMOUTCURSOR) (GLOBALVARS AUTOZOOM.FACTOR AUTOZOOM.REPAINT.TIME ZOOMINCURSOR ZOOMOUTCURSOR)) (COMS (* fns for changing the view) (FNS SKETCH.HOME SK.FRAME.IT SK.MOVE.TO.VIEW SK.NAME.CURRENT.VIEW SKETCH.ADD.VIEW SK.RESTORE.VIEW SK.FORGET.VIEW) (DECLARE: DONTCOPY (RECORDS SKETCHVIEW))) (COMS (* grid stuff) (FNS SK.SET.GRID SK.DISPLAY.GRID SK.DISPLAY.GRID.POINTS SK.REMOVE.GRID.POINTS SK.TAKE.DOWN.GRID SK.SHOW.GRID SK.GRIDFACTOR SK.TURN.GRID.ON SK.TURN.GRID.OFF SK.MAKE.GRID.LARGER SK.MAKE.GRID.SMALLER SK.CHANGE.GRID GRID.FACTOR1 LEASTPOWEROF2GT GREATESTPOWEROF2LT SK.DEFAULT.GRIDFACTOR SK.PUT.ON.GRID MAP.WINDOW.ONTO.GRID MAP.SCREEN.ONTO.GRID MAP.GLOBAL.PT.ONTO.GRID MAP.GLOBAL.REGION.ONTO.GRID MAP.WINDOW.POINT.ONTO.GLOBAL.GRID MAP.WINDOW.ONTO.GLOBAL.GRID SK.UPDATE.GRIDFACTOR SK.MAP.FROM.WINDOW.TO.GLOBAL.GRID SK.MAP.INPUT.PT.TO.GLOBAL SK.MAP.FROM.WINDOW.TO.NEAREST.GRID) (INITVARS (DEFAULTGRIDSIZE 8) (DEFAULTMINGRIDSIZE 4) (DEFAULTMAXGRIDSIZE 32))) (COMS (* sketch icon support) (FNS SKETCH.TITLE SK.SHRINK.ICONCREATE) (UGLYVARS SKETCH.TITLED.ICON.TEMPLATE)) (COMS (* history and undo stuff) (FNS SK.ADD.HISTEVENT SK.SEL.AND.UNDO SK.UNDO.LAST SK.UNDO.NAME SKEVENTTYPEFNS SK.TYPE.OF.FIRST.ARG) (FNS SK.DELETE.UNDO SK.ADD.UNDO) (FNS SK.CHANGE.UNDO SK.CHANGE.REDO) (FNS SK.UNDO.UNDO SK.UNDO.MENULABEL SK.LABEL.FROM.TYPE) (DECLARE: DONTCOPY (RECORDS SKHISTEVENT SKEVENTTYPE)) (INITVARS (SKETCH.#.UNDO.ITEMS 30)) (GLOBALVARS SKETCH.#.UNDO.ITEMS) (IFPROP EVENTFNS ADD DELETE CHANGE UNDO MOVE COPY ZOOM ANNOTATE LINK)) (COMS (* functions for hardcopying) (FNS SKETCHW.HARDCOPYFN \SK.LIST.PAGE.IMAGE SK.LIST.IMAGE SK.LIST.IMAGE.ON.FILE SK.SET.HARDCOPY.MODE SK.UNSET.HARDCOPY.MODE SK.UPDATE.AFTER.HARDCOPY DEFAULTPRINTINGIMAGETYPE SK.SWITCH.REGION.X.AND.Y) (CONSTANTS MICASPERPT IMICASPERPT PTSPERMICA)) (COMS (* functions for displaying the global coordinate space values.) (FNS SHOW.GLOBAL.COORDS LOCATOR.CLOSEFN SKETCHW.FROM.LOCATOR SKETCHW.UPDATE.LOCATORS LOCATOR.UPDATE UPDATE.GLOBAL.LOCATOR UPDATE.GLOBALCOORD.LOCATOR ADD.GLOBAL.DISPLAY ADD.GLOBAL.GRIDDED.DISPLAY CREATE.GLOBAL.DISPLAYER UPDATE.GLOBAL.GRIDDED.COORD.LOCATOR) (VARS (SKETCHW.LASTCURSORPTX 0) (SKETCHW.LASTCURSORY 0)) (GLOBALVARS SKETCHW.LASTCURSORPTX SKETCHW.LASTCURSORPTY)) (COMS (* fns for reading in various values) (FNS READBRUSHSHAPE) (FNS SK.CHANGE.DASHING READ.AND.SAVE.NEW.DASHING READ.NEW.DASHING READ.DASHING.CHANGE DASHINGP SK.CACHE.DASHING SK.DASHING.LABEL) (FNS READ.FILLING.CHANGE SK.CACHE.FILLING READ.AND.SAVE.NEW.FILLING SK.FILLING.LABEL) (INITVARS (SK.DASHING.PATTERNS) (SK.FILLING.PATTERNS)) (GLOBALVARS SK.DASHING.PATTERNS SK.FILLING.PATTERNS) (P (SK.CACHE.DASHING (QUOTE (2 4))) (SK.CACHE.DASHING (QUOTE (6 3 1 3))) (SK.CACHE.FILLING BLACKSHADE) (SK.CACHE.FILLING GRAYSHADE) (SK.CACHE.FILLING HIGHLIGHTSHADE))) (COMS (* fns for reading colors) (FNS DISPLAYREADCOLORHLSLEVELS DISPLAYREADCOLORLEVEL DRAWREADCOLORBOX READ.CHANGE.COLOR READCOLOR1 READCOLORCOMMANDMENUSELECTEDFN READCOLOR2) (FNS CREATE.CNS.MENU) (VARS COLORMENUHEIGHT COLORMENUWIDTH) (DECLARE: DOEVAL@COMPILE EVAL@LOAD DONTCOPY (FILES (LOADCOMP) LLCOLOR))) (FNS SCALE.POSITION.INTO.SKETCHW UNSCALE UNSCALE.REGION) (COMS (* stuff for reading input positions) (FNS SK.GETGLOBALPOSITION GETSKWPOSITION SKETCH.TRACK.ELEMENTS SK.READ.POINT.WITH.FEEDBACK NEAREST.HOT.SPOT GETWREGION GET.BITMAP.POSITION SK.TRACK.BITMAP1) (RECORDS INPUTPT)) (INITVARS (ALL.SKETCHES) (INITIAL.SCALE 1.0) (DEFAULT.VISIBLE.SCALE.FACTOR 10.0) (MINIMUM.VISIBLE.SCALE.FACTOR 4.0)) (VARS (SKETCH.ELEMENT.TYPES) (SKETCH.ELEMENT.TYPE.NAMES)) (GLOBALVARS ALL.SKETCHES INITIAL.SCALE DEFAULT.VISIBLE.SCALE.FACTOR MINIMUM.VISIBLE.SCALE.FACTOR SKETCH.ELEMENT.TYPES SKETCH.ELEMENT.TYPE.NAMES SK.SELECTEDMARK SK.LOCATEMARK COPYSELECTIONMARK MOVESELECTIONMARK DELETESELECTIONMARK) (UGLYVARS SK.SELECTEDMARK SK.LOCATEMARK COPYSELECTIONMARK MOVESELECTIONMARK DELETESELECTIONMARK OTHERCONTROLPOINTMARK) (* accessing functions for the methods of a sketch type.) (FNS SK.DRAWFN SK.TRANSFORMFN SK.EXPANDFN SK.INPUT SK.INSIDEFN SK.UPDATEFN) (INITRECORDS SKETCHTYPE) (DECLARE: DONTCOPY (RECORDS SCREENELT GLOBALPART COMMONGLOBALPART INDIVIDUALGLOBALPART LOCALPART SKETCH SKETCHTYPE SKETCHCONTEXT)) (ADDVARS (BackgroundMenuCommands (Sketch (QUOTE (SKETCHW.CREATE NIL NIL (GETREGION) NIL NIL T T)) "Opens a sketch window for use."))) (VARS (BackgroundMenu)) (FILES SKETCHELEMENTS GRAPHZOOM SKETCHEDIT SKETCHOBJ SKETCHBMELT TEDIT) (DECLARE: DOEVAL@COMPILE EVAL@LOAD DONTCOPY (FILES (LOADCOMP) SKETCHELEMENTS SKETCHOBJ SKETCHEDIT)) (P (INIT.GROUP.ELEMENT)) (COMS (* version checking stuff) (CONSTANTS (SKETCH.VERSION 3)) (FNS SK.CHECK.SKETCH.VERSION SK.INSURE.RECORD.LENGTH SK.INSURE.HAS.LENGTH SK.SET.RECORD.LENGTHS) (MACROS SK.SET.RECORD.LENGTHS.MACRO) (GLOBALVARS SKETCH.RECORD.LENGTHS) (P (SK.SET.RECORD.LENGTHS))) (DECLARE: DONTEVAL@LOAD DOEVAL@COMPILE DONTCOPY COMPILERVARS (ADDVARS (NLAMA) (NLAML) (LAMA SKETCH.CREATE STATUSPRINT]) (DECLARE: FIRST DOCOPY DONTEVAL@LOAD [PROG ((NOTECARDSFLG (GETPROP (QUOTE NOTECARDS) (QUOTE FILEDATES))) (SKETCHFLG (AND (BOUNDP (QUOTE ALL.SKETCHES)) ALL.SKETCHES)) TEDITFLG) (* current knows about SKETCH TEDIT and NOTECARDS. Everyone else loses.) [MAP.PROCESSES (FUNCTION (LAMBDA (PROC PROCNAME PROCFORM) (AND (EQ (CAR PROCFORM) (QUOTE \TEDIT2)) (SETQ TEDITFLG T] (COND ((AND (BOUNDP (QUOTE ALL.SKETCHES)) (OR SKETCHFLG NOTECARDSFLG TEDITFLG)) (ERROR (CONCAT "Please close" (COND (SKETCHFLG " all open Sketch windows,") (T "")) (COND (NOTECARDSFLG (CONCAT (COND (SKETCHFLG " and") (T "")) " any open notefiles,")) (T "")) (COND (TEDITFLG (CONCAT (COND ((OR SKETCHFLG NOTECARDSFLG) " and") (T "")) " any TEDIT windows that have sketches in them,")) (T "")) " then type 'RETURN'. To abort loading the new version of Sketch, type '↑'."] ) (DEFINEQ (SKETCH.TEST [LAMBDA NIL (* rrb " 1-Nov-85 14:57") (* test the programmer's interface a little.) (PROG (SKELTS SK SKELT) [SETQ SKELTS (LIST [PROG1 (SETQ SKELT (SKETCH.CREATE.BITMAP (CAR SKETCH.TITLED.ICON.TEMPLATE) (QUOTE (0 . 0)) 1.0)) (PUTSKETCHELEMENTPROP SKELT (QUOTE ACTIVEREGION) (CREATEREGION 0 0 (BITMAPWIDTH (CAR SKETCH.TITLED.ICON.TEMPLATE)) (BITMAPHEIGHT (CAR SKETCH.TITLED.ICON.TEMPLATE] (SKETCH.CREATE.TEXT (QUOTE ("this is a two line" "piece of text")) (QUOTE (0 . 100)) (QUOTE (MODERN 12 BOLD)) NIL NIL 1.0) (SKETCH.CREATE.TEXTBOX "text box with carriage returns in it but only after text box." (QUOTE (75 75 100 50)) NIL (QUOTE (LEFT TOP)) 3 (QUOTE (4 4)) GRAYSHADE NIL 1.0) (SKETCH.CREATE.BOX (QUOTE (75 0 20 20))) (SKETCH.CREATE.WIRE (QUOTE ((75 . 75) (60 . 100) (75 . 200))) 2 NIL (QUOTE (NIL T)) 1.0) (SKETCH.CREATE.CLOSED.WIRE (QUOTE ((75 . 75) (100 . 60) (200 . 75))) 2 NIL 15 1.0) (SKETCH.CREATE.OPEN.CURVE (QUOTE ((50 . 200) (60 . 100) (75 . 200))) 2 NIL (QUOTE (NIL T)) 1.0) (SKETCH.CREATE.CLOSED.CURVE (QUOTE ((200 . 50) (100 . 60) (200 . 75))) 2 NIL 15 1.0) (SKETCH.CREATE.CIRCLE (QUOTE (150 . 150)) (QUOTE (175 . 175)) 5 (QUOTE (1 1)) NIL 1.0) (SKETCH.CREATE.ELLIPSE (QUOTE (150 . 150)) (QUOTE (170 . 150)) (QUOTE (150 . 160)) 2 NIL NIL 1.0) (SKETCH.CREATE.ARC (QUOTE (150 . 150)) (QUOTE (185 . 185)) (QUOTE (150 . 185)) 1 (QUOTE (2 2)) (QUOTE (T T)) NIL 1.0) (SKETCH.CREATE.GROUP [LIST [SKETCH.CREATE.WIRE (QUOTE ((200 . 200) (240 . 200] [SKETCH.CREATE.WIRE (QUOTE ((200 . 200) (200 . 240] [SKETCH.CREATE.WIRE (QUOTE ((240 . 200) (240 . 240] (SKETCH.CREATE.WIRE (QUOTE ((240 . 240) (200 . 240] (QUOTE (220 . 200] (SETQ SK (SKETCH.ADD.ELEMENT NIL NIL)) (for ELT in SKELTS do (SKETCH.ADD.ELEMENT ELT SK)) [PUTSKETCHPROP SK (QUOTE WHENADDEDFN) (FUNCTION (LAMBDA (X) (X) (PRINT "When added called." PROMPTWINDOW] [PUTSKETCHPROP SK (QUOTE WHENDELETEDFN) (FUNCTION (LAMBDA (X) (X) (PRINT "When deleted called." PROMPTWINDOW] [PUTSKETCHPROP SK (QUOTE WHENCHANGEDFN) (FUNCTION (LAMBDA (X) (X) (PRINT "When changed called." PROMPTWINDOW] [PUTSKETCHPROP SK (QUOTE PREMOVEFN) (FUNCTION (LAMBDA (X) (X) (PRINT "Premove called." PROMPTWINDOW] [PUTSKETCHPROP SK (QUOTE WHENMOVEDFN) (FUNCTION (LAMBDA (X) (X) (PRINT "When moved called." PROMPTWINDOW] [PUTSKETCHPROP SK (QUOTE PRECOPYFN) (FUNCTION (LAMBDA (X) (X) (PRINT "Pre Copy called." PROMPTWINDOW] [PUTSKETCHPROP SK (QUOTE WHENCOPIEDFN) (FUNCTION (LAMBDA (X) (X) (PRINT "When copied called." PROMPTWINDOW] [PUTSKETCHPROP SK (QUOTE WHENGROUPED) (FUNCTION (LAMBDA (X) (X) (PRINT "When grouped called." PROMPTWINDOW] [PUTSKETCHPROP SK (QUOTE WHENUNGROUPED) (FUNCTION (LAMBDA (X) (X) (PRINT "When ungrouped called." PROMPTWINDOW] [PUTSKETCHPROP SK (QUOTE WHENDEFAULTSETFN) (FUNCTION (LAMBDA (X) (X) (PRINT "When default set fn." PROMPTWINDOW] [PUTSKETCHPROP SK (QUOTE BUTTONEVENTINFN) (FUNCTION (LAMBDA (X) (X) (PRINT "When button event in fn called." PROMPTWINDOW] (SKETCHW.CREATE SK NIL (QUOTE (200 200 300 300)) "test SKETCH" NIL T]) ) (DEFINEQ (DRAW.LOCAL.SKETCH [LAMBDA (LOCALSPECS STREAM STREAMREGION SCALE) (* rrb " 8-May-85 09:34") (* * draws the local specs on a stream) (MAPSKETCHSPECS LOCALSPECS (FUNCTION SK.DRAWFIGURE) STREAM STREAMREGION (OR (NUMBERP SCALE) (AND (WINDOWP STREAM) (WINDOW.SCALE STREAM]) (SKETCHW.CREATE [LAMBDA (SKETCH SKETCHREGION SCREENREGION TITLE INITIALSCALE BRINGUPMENU INITIALGRID) (* rrb "11-Dec-85 10:56") (* creates a sketch window and returns it.) (PROG (W SCALE SKPROC SKETCHSTRUCTURE) [SETQ SKETCHSTRUCTURE (SK.CHECK.SKETCH.VERSION (COND ((NULL SKETCH) (SKETCH.CREATE NIL)) [(LITATOM SKETCH) (* save the sketch on its name for use by EDITSLIDE.) (OR (GETPROP SKETCH (QUOTE SKETCH)) (PUTPROP SKETCH (QUOTE SKETCH) (SKETCH.CREATE SKETCH] ((type? SKETCH SKETCH) SKETCH) ((type? IMAGEOBJ SKETCH) (* pull things out of the image object.) (SETQ SKPROC (IMAGEOBJPROP SKETCH (QUOTE OBJECTDATUM))) (OR (REGIONP SKETCHREGION) (SETQ SKETCHREGION (fetch (SKETCHIMAGEOBJ SKIO.REGION) of SKPROC))) (OR (NUMBERP INITIALSCALE) (SETQ INITIALSCALE (fetch (SKETCHIMAGEOBJ SKIO.SCALE) of SKPROC))) (OR (NUMBERP INITIALGRID) (SETQ INITIALGRID (fetch (SKETCHIMAGEOBJ SKIO.GRID) of SKPROC))) (fetch (SKETCHIMAGEOBJ SKIO.SKETCH) of SKPROC)) ((AND (LITATOM (CAR SKETCH)) (for ELT in (CDR SKETCH) always (GLOBALELEMENTP ELT))) (* old form, probably written out by notecards, update to new form.) (PROG (X) (SETQ X ( SKIO.UPDATE.FROM.OLD.FORM SKETCH)) (* smash sketch so this won't have to happen every time.) (RPLACA SKETCH (CAR X)) (RPLACD SKETCH (CDR X)) (RETURN X))) (T (\ILLEGAL.ARG SKETCH] [SETQ W (COND ((WINDOWP SCREENREGION) (AND TITLE (WINDOWPROP SCREENREGION (QUOTE TITLE) TITLE)) SCREENREGION) (T (CREATEW (COND ((REGIONP SCREENREGION)) (T (CREATEREGION LASTMOUSEX LASTMOUSEY 10 10))) (OR TITLE (SK.WINDOW.TITLE SKETCHSTRUCTURE)) NIL T] (AND BRINGUPMENU (SK.FIX.MENU W T BRINGUPMENU)) (COND ((OR (REGIONP SCREENREGION) (WINDOWP SCREENREGION)) (* user gave a region, don't interact) NIL) (T (* let prompting for reshape show room for both menu and window.) (SHAPEW W))) (* set the right margin so that text will never run into it. This can be removed when character positions are kept in points so \DSPPRINTCHAR doesn't have to look at the right margin.) (DSPRIGHTMARGIN 64000 W) (WINDOWPROP W (QUOTE SKETCH) SKETCHSTRUCTURE) [WINDOWPROP W (QUOTE SCALE) (SETQ SCALE (COND ((NUMBERP INITIALSCALE)) [(REGIONP SKETCHREGION) (* determine the scale and offsets so that the given region of the sketch fits into the given window.) (FQUOTIENT (fetch (REGION HEIGHT) of SKETCHREGION) (fetch (REGION HEIGHT) of (DSPCLIPPINGREGION NIL W] ((NULL SKETCHREGION) INITIAL.SCALE) (T (\ILLEGAL.ARG SKETCHREGION] (* check to make sure a context exists on the sketch because before July 1985 it didn't exist.) [WINDOWPROP W (QUOTE SKETCHCONTEXT) (OR (GETSKETCHPROP SKETCHSTRUCTURE (QUOTE SKETCHCONTEXT)) (PUTSKETCHPROP SKETCHSTRUCTURE (QUOTE SKETCHCONTEXT) (CREATE.DEFAULT.SKETCH.CONTEXT] (COND ((REGIONP SKETCHREGION) (* if given a region, translate to it.) (WXOFFSET (IMINUS (FIX (QUOTIENT (fetch (REGION LEFT) of SKETCHREGION) SCALE))) W) (WYOFFSET (IMINUS (FIX (QUOTIENT (fetch (REGION BOTTOM) of SKETCHREGION) SCALE))) W))) (SK.UPDATE.REGION.VIEWED W) (* calculate the sketch region being viewed before mapping the sketch into it.) (MAP.SKETCHSPEC.INTO.VIEWER SKETCHSTRUCTURE W) (SK.CREATE.HOTSPOT.CACHE W) [WINDOWPROP W (QUOTE GRIDFACTOR) (COND ((NUMBERP INITIALGRID) (LEASTPOWEROF2GT INITIALGRID)) (T (SK.DEFAULT.GRIDFACTOR W] (WINDOWPROP W (QUOTE USEGRID) (COND (INITIALGRID T))) (WINDOWPROP W (QUOTE BUTTONEVENTFN) (FUNCTION WB.BUTTON.HANDLER)) (WINDOWPROP W (QUOTE COPYBUTTONEVENTFN) (FUNCTION SK.COPY.BUTTONEVENTFN)) (WINDOWPROP W (QUOTE COPYINSERTFN) (FUNCTION SK.COPY.INSERTFN)) (WINDOWPROP W (QUOTE RIGHTBUTTONFN) (FUNCTION WB.BUTTON.HANDLER)) (WINDOWPROP W (QUOTE CURSOROUTFN) (FUNCTION SKETCHW.OUTFN)) (WINDOWPROP W (QUOTE REPAINTFN) (FUNCTION SKETCHW.REPAINTFN)) (WINDOWADDPROP W (QUOTE RESHAPEFN) (FUNCTION RESHAPEBYREPAINTFN)) (WINDOWADDPROP W (QUOTE RESHAPEFN) (FUNCTION SKETCHW.FIG.CHANGED)) (WINDOWADDPROP W (QUOTE RESHAPEFN) (FUNCTION SK.UPDATE.REGION.VIEWED)) (WINDOWADDPROP W (QUOTE SHRINKFN) (FUNCTION SK.SHRINK.ICONCREATE)) (WINDOWADDPROP W (QUOTE SHRINKFN) (FUNCTION SK.RETURN.TTY)) (WINDOWADDPROP W (QUOTE EXPANDFN) (FUNCTION SK.TAKE.TTY)) (WINDOWPROP W (QUOTE SCROLLFN) (FUNCTION SKETCHW.SCROLLFN)) (WINDOWPROP W (QUOTE HARDCOPYFN) (FUNCTION SKETCHW.HARDCOPYFN)) (* I'm not sure why this ever gets called but it did once so to be sure, turn it off.) (WINDOWPROP W (QUOTE PAGEFULLFN) (FUNCTION NILL)) [WINDOWPROP W (QUOTE PROCESS) (SETQ SKPROC (ADD.PROCESS (LIST (FUNCTION WB.EDITOR) (KWOTE W)) (QUOTE RESTARTABLE) T (QUOTE TTYENTRYFN) (QUOTE SK.TTYENTRYFN) (QUOTE TTYEXITFN) (QUOTE SK.TTYEXITFN] (WINDOWPROP W (QUOTE SCROLLEXTENTUSE) T) (WINDOWADDPROP W (QUOTE CLOSEFN) (FUNCTION SKETCHW.CLOSEFN) T) (OPENW W) (ADD.SKETCH.VIEWER SKETCHSTRUCTURE W) (SKETCHW.REPAINTFN W) (RETURN W]) (SKETCH.RESET [LAMBDA (SKETCH) (* rrb "11-Dec-85 11:24") (* resets a sketch structure and all of the viewers onto it.) (PROG ((SKSTRUC (INSURE.SKETCH SKETCH))) (* delete all sketch elements) (replace (SKETCH SKETCHTCELL) of SKSTRUC with (CONS)) (for VIEWER in (ALL.SKETCH.VIEWERS SKSTRUC) do (SKED.CLEAR.SELECTION VIEWER) (DSPRESET VIEWER) (WINDOWPROP VIEWER (QUOTE SCALE) INITIAL.SCALE) (SK.UPDATE.REGION.VIEWED VIEWER) (MAP.SKETCHSPEC.INTO.VIEWER SKSTRUC VIEWER) (SK.CREATE.HOTSPOT.CACHE VIEWER) (WINDOWPROP VIEWER (QUOTE GRIDFACTOR) (SK.DEFAULT.GRIDFACTOR VIEWER)) (WINDOWPROP VIEWER (QUOTE USEGRID) NIL) (WINDOWPROP VIEWER (QUOTE SKETCHHISTORY) NIL) (WINDOWPROP VIEWER (QUOTE SKETCHCHANGED) NIL]) (SKETCHW.FIG.CHANGED [LAMBDA (W) (* rrb "29-Nov-84 17:59") (* W is a sketch window that is being reshaped. Mark this fact in case it came out of a document.) (OR (WINDOWPROP W (QUOTE SKETCHCHANGED)) (WINDOWPROP W (QUOTE SKETCHCHANGED) (QUOTE OLD]) (SK.WINDOW.TITLE [LAMBDA (SKETCH) (* rrb " 7-May-85 14:00") (* returns the window title of a window onto a sketch.) (COND ((fetch (SKETCH SKETCHNAME) of SKETCH) (CONCAT "Viewer onto " (fetch (SKETCH SKETCHNAME) of SKETCH))) (T "Viewer onto a sketch"]) (EDITSLIDE [LAMBDA (SLIDENAME) (* rrb "25-Oct-84 11:23") (* creates a sketch in a window the size of a screen.) (SKETCHW.CREATE (SETQ SLIDENAME (OR SLIDENAME (GENSYM "SLIDE"))) NIL (GETBOXREGION 612 792) NIL NIL T 16.0) SLIDENAME]) (EDITSKETCH [LAMBDA (SLIDENAME) (* rrb "14-Nov-84 17:15") (* edits a named sketch) (SKETCHW.CREATE (SETQ SLIDENAME (OR SLIDENAME (GENSYM "SLIDE"))) NIL NIL NIL NIL T 16.0) SLIDENAME]) (SK.FIX.MENU [LAMBDA (SKETCHW DONTOPENFLG MENU?) (* rrb "24-Jan-85 11:21") (* attached the sketchops menu to the window.) (PROG (MENUW) [COND ((type? MENU MENU?) (* put the given menu as the fixed one and establish the standard one as the SKETCHPOPUPMENU) (SETQ MENUW (MENUWINDOW MENU? T)) (WINDOWPROP SKETCHW (QUOTE SKETCHFIXEDMENU) MENUW) (SK.INSURE.HAS.MENU SKETCHW T)) (T (SETQ MENUW (SK.INSURE.HAS.MENU SKETCHW] (WINDOWPROP MENUW (QUOTE MINSIZE) (CONS [BITMAPWIDTH (UPDATE/MENU/IMAGE (CAR (WINDOWPROP MENUW (QUOTE MENU] 20)) (COND ((NOT (MEMB MENUW (ATTACHEDWINDOWS SKETCHW))) (ATTACHWINDOW MENUW SKETCHW (QUOTE RIGHT) (QUOTE TOP) (QUOTE LOCALCLOSE)) (WINDOWADDPROP MENUW (QUOTE CLOSEFN) (FUNCTION DETACHWINDOW)) (OR DONTOPENFLG (OPENW MENUW]) (SK.PUT.ON.FILE [LAMBDA (SKETCHW) (* rrb "12-May-85 19:05") (* saves a sketch on a Tedit file.) (* also changes the name of the sketch to be the same as the name of the file.) (PROG ((SKETCH (INSURE.SKETCH (SKETCH.FROM.VIEWER SKETCHW))) NOWNAME NEWNAME TEXTSTREAM) (SETQ NOWNAME (fetch (SKETCH SKETCHNAME) of SKETCH)) (OR [SETQ NEWNAME (MKATOM (PROMPT.GETINPUT SKETCHW "File to PUT to: " (COND ((STRPOS " " NOWNAME) (* don't put up dummy names that contain spaces) NIL) (T NOWNAME] (RETURN NIL)) [COND ((NEQ NOWNAME NEWNAME) (* change the name of the sketch to be the same as the file name.) (replace (SKETCH SKETCHNAME) of SKETCH with NEWNAME) (* change the titles of the viewers onto this sketch.) (for SKW in (ALL.SKETCH.VIEWERS SKETCH) do (WINDOWPROP SKW (QUOTE TITLE) (CONCAT "Viewer onto " NEWNAME] (* make a text stream with nothing in it except the sketch.) [SETQ TEXTSTREAM (OPENTEXTSTREAM "" NIL NIL NIL (LIST (QUOTE PUTFN) (WINDOWPROP SKETCHW (QUOTE TEDIT.PUTFN)) (QUOTE PROMPTWINDOW) (GETPROMPTWINDOW SKETCHW] (TEDIT.INSERT.OBJECT (SKETCHIMAGEOBJ.FROM.VIEWER SKETCHW) TEXTSTREAM 1) (TEDIT.PUT TEXTSTREAM NEWNAME) (AND (OPENP NEWNAME) (CLOSEF NEWNAME)) (SK.MARK.UNDIRTY SKETCH) (RETURN NEWNAME]) (SK.GET.FROM.FILE [LAMBDA (SKETCHW) (* rrb "19-Jul-85 09:17") (* saves a sketch on a file.) (* also changes the name of the sketch to be the same as the name of the file.) (PROG ((SKETCH (SKETCH.FROM.VIEWER SKETCHW)) NOWNAME NEWNAME TEXTSTREAM IMAGEOBJ DIRTYSTATUS) (SETQ NOWNAME (fetch (SKETCH SKETCHNAME) of SKETCH)) (SETQ NEWNAME (MKATOM (PROMPT.GETINPUT SKETCHW "File to GET: "))) (COND ((MEMB NEWNAME (QUOTE (NIL %]))) (CLOSEPROMPTWINDOW SKETCHW) (RETURN))) (STATUSPRINT SKETCHW " ...") [SETQ TEXTSTREAM (OPENTEXTSTREAM NEWNAME NIL NIL NIL (LIST (QUOTE PROMPTWINDOW) (GETPROMPTWINDOW SKETCHW] (SETQ IMAGEOBJ (BIN TEXTSTREAM)) (AND (OPENP NEWNAME) (CLOSEF NEWNAME)) (COND ((NOT (IMAGEOBJP IMAGEOBJ)) (STATUSPRINT SKETCHW NEWNAME " is not a sketch file.") (RETURN NIL))) (PROG [(OBJ (IMAGEOBJPROP IMAGEOBJ (QUOTE OBJECTDATUM] (PROG ((SKREG (fetch (SKETCHIMAGEOBJ SKIO.REGION) of OBJ)) (SCALE (fetch (SKETCHIMAGEOBJ SKIO.SCALE) of OBJ)) (READSKETCH (fetch (SKETCHIMAGEOBJ SKIO.SKETCH) of OBJ)) DEFAULTS) (* for now just stick all the elements in.) (COND ((NOT (type? SKETCH READSKETCH)) (STATUSPRINT SKETCHW NEWNAME " is not a sketch file.") (RETURN))) [COND ((NEQ NOWNAME NEWNAME) (* change the name of the sketch to be the same as the file name.) (replace (SKETCH SKETCHNAME) of SKETCH with NEWNAME) (* change the name of the sketch to be the same as the file name.) (for SKW in (ALL.SKETCH.VIEWERS SKETCH) do (WINDOWPROP SKW (QUOTE TITLE) (SK.WINDOW.TITLE SKETCH] (COND ((fetch (SKETCH SKETCHELTS) of SKETCH) (* note whether there were any elements of the sketch before the GET. If there were, the sketch should be left marked dirty.) (SETQ DIRTYSTATUS T)) (T (PUTSKETCHPROP SKETCH (QUOTE SKETCHCONTEXT) DEFAULTS))) [COND ((SETQ DEFAULTS (GETSKETCHPROP READSKETCH (QUOTE SKETCHCONTEXT))) (* determine whether to replace the current context with the one stored with the sketch.) (AND (COND ([AND (fetch (SKETCH SKETCHELTS) of SKETCH) (NOT (EQUAL DEFAULTS (GETSKETCHPROP SKETCH (QUOTE SKETCHCONTEXT] (* if there are existing elements, ask whether to replace) (MENU (create MENU ITEMS ←(QUOTE ((Yes T "Will use the defaults of the retrieved sketch.") (No NIL "Will not change the defaults."))) CENTERFLG ← T TITLE ← "Use the defaults from the retrieved sketch?" MENUCOLUMNS ← 2))) (T T)) (PUTSKETCHPROP SKETCH (QUOTE SKETCHCONTEXT) DEFAULTS] (SK.ADD.ELEMENTS.TO.SKETCH (fetch (SKETCH SKETCHELTS) of READSKETCH) SKETCHW) (* copy properties from the read sketch.) [for SKPROP in (fetch (SKETCH SKETCHPROPS) of READSKETCH) by (CDDR SKPROP) do (SELECTQ SKPROP (SKETCHCONTEXT NIL) [VIEWS (PUTSKETCHPROP SKETCH (QUOTE VIEWS) (UNION (GETSKETCHPROP READSKETCH (QUOTE VIEWS)) (GETSKETCHPROP SKETCH (QUOTE VIEWS] (PUTSKETCHPROP SKETCH SKPROP (GETSKETCHPROP READSKETCH SKPROP] (SK.CHANGE.GRID (fetch (SKETCHIMAGEOBJ SKIO.GRID) of OBJ) SKETCHW) (COND ((NULL DIRTYSTATUS) (* if sketch was empty before, mark it as not needing to be dumped.) (SK.MARK.UNDIRTY SKETCH))) (STATUSPRINT SKETCHW " done."]) (SK.ADD.ELEMENTS.TO.SKETCH [LAMBDA (ELTS SKW) (* rrb "28-Nov-84 11:12") (* adds a group of elements to a sketch) (for ELT in ELTS do (SK.ADD.ELEMENT ELT SKW]) (STATUSPRINT [LAMBDA NEXPS (* rrb "26-Jun-84 09:42") (* prints a list of expressions in the status window associated with another window. If the first arg is a window or a process, its prompt window is used. Otherwise, the global prompt window is used.) (OR (EQ NEXPS 0) (PROG (WIN (BEG 1)) (COND ((WINDOWP (ARG NEXPS 1)) (SETQ BEG 2) (SETQ WIN (MYGETPROMPTWINDOW (ARG NEXPS 1) 2))) [(PROCESSP (ARG NEXPS 1)) (SETQ BEG 2) (COND ([AND (HASTTYWINDOWP (ARG NEXPS 1)) (SETQ WIN (OPENWP (PROCESS.TTY (ARG NEXPS 1] (SETQ WIN (GETPROMPTWINDOW WIN))) (T (SETQ WIN PROMPTWINDOW] ((EQ (ARG NEXPS 1) T) (SETQ BEG 2) (SETQ WIN (TTYDISPLAYSTREAM))) [(HASTTYWINDOWP (THIS.PROCESS)) (SETQ WIN (GETPROMPTWINDOW (TTYDISPLAYSTREAM] (T (SETQ WIN PROMPTWINDOW))) (for X from BEG to NEXPS do (PRIN1 (ARG NEXPS X) WIN]) (CLEARPROMPTWINDOW [LAMBDA (W) (* rrb "28-Nov-84 11:20") (* clears the prompt window of a window. IF W is NIL, clears the global one.) (COND [(WINDOWP W) (PROG (PWIN) (AND (SETQ PWIN (GETPROMPTWINDOW W NIL NIL T)) (OPENWP PWIN) (CLEARW PWIN] (T (CLRPROMPT]) (CLOSEPROMPTWINDOW [LAMBDA (WINDOW) (* rrb "20-Nov-85 10:26") (* clears and closes the prompt window for a window.) (PROG [(PROMPTW (OPENWP (GETPROMPTWINDOW WINDOW NIL NIL T] (COND (PROMPTW (CLEARW PROMPTW) (DETACHWINDOW PROMPTW) (CLOSEW PROMPTW]) (MYGETPROMPTWINDOW [LAMBDA (MAINW NLINES FONT DONTCREATE) (* rrb "28-Aug-85 11:10") (* a version of GETPROMPTWINDOW that is locally closable.) (PROG ((PROMPTW (GETPROMPTWINDOW (ARG NEXPS 1) 2 (OR FONT (DEFAULTFONT (QUOTE DISPLAY))) DONTCREATE))) [COND (PROMPTW (* make it locally closeable) (WINDOWADDPROP PROMPTW (QUOTE CLOSEFN) (FUNCTION DETACHWINDOW] (RETURN PROMPTW]) (PROMPT.GETINPUT [LAMBDA (WINDOW PROMPTSTRING DEFAULTSTRING DELIMITER.LIST) (* rrb "23-May-84 14:39") (* Ask for input (file names, &c) perhaps with a default.) (PROG (PROMPTWIN) (COND (WINDOW (SETQ PROMPTWIN (GETPROMPTWINDOW WINDOW)) (FRESHLINE PROMPTWIN)) ((SETQ PROMPTWIN PROMPTWINDOW) (CLEARW PROMPTWIN))) (RETURN (PROMPTFORWORD PROMPTSTRING DEFAULTSTRING NIL PROMPTWIN NIL NIL (OR DELIMITER.LIST (CHARCODE (EOL LF TAB ESCAPE))) NIL]) (SK.INSURE.HAS.MENU [LAMBDA (SKETCHW POPUPFLG INCLUDEFIXITEMFLG) (* rrb "17-Oct-85 10:50") (* makes sure a sketch window has a menu.) (COND [(WINDOWPROP SKETCHW (COND (POPUPFLG (QUOTE SKETCHPOPUPMENU)) (T (QUOTE SKETCHFIXEDMENU] (T (PROG ((OPMENUW (MENUWINDOW (CREATE.SKETCHW.COMMANDMENU NIL INCLUDEFIXITEMFLG T) T))) (WINDOWPROP SKETCHW (COND (POPUPFLG (QUOTE SKETCHPOPUPMENU)) (T (QUOTE SKETCHFIXEDMENU))) OPMENUW) (RETURN OPMENUW]) (SKETCH.SET.A.DEFAULT [LAMBDA (SKW) (* rrb "10-Dec-85 14:57") (* allows the user to set a default) (\CURSOR.IN.MIDDLE.MENU (create MENU ITEMS ←[QUOTE ((Line SKETCH.SET.BRUSH.SIZE "Sets the characteristics of the default brush." (SUBITEMS (Size SKETCH.SET.BRUSH.SIZE "Sets the size of the default brush") (Shape SKETCH.SET.BRUSH.SHAPE "Sets the shape of the default brush") (Add% arrowhead SK.SET.LINE.ARROWHEAD "Sets the arrowhead characteristics of new lines.") ("Mouse line specs" SK.SET.LINE.LENGTH.MODE "Sets whether the lines drawn with the middle mouse button connect to each other."))) (Arrowhead SK.SET.ARROWHEAD.LENGTH "Sets the characteristics of the default arrowhead." (SUBITEMS (Size SK.SET.ARROWHEAD.LENGTH) (Angle SK.SET.ARROWHEAD.ANGLE) (Type SK.SET.ARROWHEAD.TYPE))) (Text SK.SET.TEXT.SIZE "Sets the size of newly added text." (SUBITEMS ("Font size" SK.SET.TEXT.SIZE "Sets the size of newly added text.") ("Font family" SK.SET.TEXT.FONT "Sets the font family of newly added text.") ("Horizontal justification" SK.SET.TEXT.HORIZ.ALIGN "Sets the horizontal justification mode of new text.") ("Vertical justification" SK.SET.TEXT.VERT.ALIGN "Sets the vertical justification of new text.") ("Bold and/or italic" SK.SET.TEXT.LOOKS "Sets the bold and italic look of new text."))) (Text% Box SK.SET.TEXTBOX.HORIZ.ALIGN "Sets the alignment of text within new text boxes." (SUBITEMS ( "Horizontal justification" SK.SET.TEXTBOX.HORIZ.ALIGN "Sets the horizontal alignment of text within new text boxes.") ( "Vertical justification" SK.SET.TEXTBOX.VERT.ALIGN "Sets the vertical alignment of text within new text boxes."))) (Arc SK.SET.ARC.DIRECTION "Sets the direction arcs go around their circle." (SUBITEMS ("Clockwise" SK.SET.ARC.DIRECTION.CW "Makes new arcs go around in the clockwise direction") ("Counterclockwise" SK.SET.ARC.DIRECTION.CCW "Makes new arcs go around in the counterclockwise direction"))) ("Input scale" SK.SET.INPUT.SCALE "Sets the scale for newly added lines and text." (SUBITEMS ( "Read new input scale" SK.SET.INPUT.SCALE "Reads a new input scale.") ( "Make input scale current" SK.SET.INPUT.SCALE.CURRENT "makes the input scale be the scale of the current view."))) (Feedback SK.SET.FEEDBACK.MODE "Controls the amount of feedback when adding new curves, circles, etc." (SUBITEMS ("Points only" SK.SET.FEEDBACK.POINT "Only the control points will be shown when entering elements.") ("Fast figures" SK.SET.FEEDBACK.VERBOSE "Wires, circles and ellipses are shown while they are being entered.") ("All figures" SK.SET.FEEDBACK.ALWAYS "Most elements are shown while they are being entered. This will be slow for arcs and curves."] CENTERFLG ← T WHENSELECTEDFN ←(FUNCTION SK.POPUP.SELECTIONFN) MENUFONT ←(FONTNAMELIST (FONTCREATE BOLDFONT]) (SK.POPUP.SELECTIONFN [LAMBDA (ITEM MENU) (* rrb " 3-Sep-85 14:27") (* * calls the function appropriate for the item selected from the command menu associated with a figure window.) (* uses SKW freely from enclosing call to MENU.) (CLOSEPROMPTWINDOW SKW) (SK.APPLY.MENU.COMMAND (CADR ITEM) SKW]) (GETSKETCHWREGION [LAMBDA (SKETCHWINDOW) (* Feuerman "27-Feb-84 10:04") (UNSCALE.REGION (GETWREGION SKETCHWINDOW) (SKETCHW.SCALE SKETCHWINDOW]) (READ.FUNCTION [LAMBDA (PRMPT W) (* rrb "11-May-84 15:41") (PROG ((PROMPTWIN (GETPROMPTWINDOW W 3)) OLDTTYDS LST) (SETQ OLDTTYDS (TTYDISPLAYSTREAM PROMPTWIN)) (COND (PRMPT (printout PROMPTWIN PRMPT T ">> "))) (* grab the tty.) (TTY.PROCESS NIL) (SETQ LST (CONS (READ T) (READLINE))) (CLOSEW (TTYDISPLAYSTREAM OLDTTYDS)) (RETURN (CAR LST]) (READBRUSHSIZE [LAMBDA (NOWSIZE) (* rrb " 3-Sep-85 16:14") (PROG ((N (RNUMBER (COND (NOWSIZE (CONCAT "Current size is " NOWSIZE ". Enter new brush size.")) (T "Enter new brush size.")) NIL NIL NIL T T))) (RETURN (COND ((EQUAL N 0) NIL) (T N]) (READANGLE [LAMBDA NIL (* rrb "31-May-85 15:41") (* interacts to get whether a line size should be increased or decreased.) (PROG ((NEWVALUE (RNUMBER "Enter arc angle in degrees." NIL NIL NIL T))) (RETURN (COND ((EQ NEWVALUE 0) NIL) (T NEWVALUE]) (READARCDIRECTION [LAMBDA (MENUTITLE) (* rrb " 6-Nov-85 09:53") (* interacts to get whether an arc should go clockwise or counterclockwise) (\CURSOR.IN.MIDDLE.MENU (create MENU TITLE ←(OR MENUTITLE "Which way should the arc go?") ITEMS ←(QUOTE (("Clockwise" (QUOTE CLOCKWISE) "The arc will be drawn clockwise from the first point to the second point.") ("Counterclockwise" (QUOTE COUNTERCLOCKWISE) "The arc will be drawn counterclockwise from the first point to the second point."))) CENTERFLG ← T]) (SK.ADD.ELEMENT [LAMBDA (GELT SKETCHW DONTCLEARCURSOR GROUPFLG) (* rrb "19-Oct-85 17:33") (* adds a new element to a sketch window and handles propagation to all other figure windows) (COND (GELT (PROG ((GELTTOADD (SK.CHECK.WHENADDEDFN SKETCHW GELT)) (SKETCH (SKETCH.FROM.VIEWER SKETCHW)) ADDEDELT) (* take down the caret.) (OR GELTTOADD (RETURN)) (OR DONTCLEARCURSOR (SKED.CLEAR.SELECTION SKETCHW)) (* add the element to the sketch.) (ADD.ELEMENT.TO.SKETCH GELT SKETCH) (* do the window that the interaction occurred in first.) (SETQ ADDEDELT (SKETCH.ADD.AND.DISPLAY1 GELT SKETCHW (SCALE.FROM.SKW SKETCHW) GROUPFLG)) (* propagate to other windows.) (for SKW in (ALL.SKETCH.VIEWERS SKETCH) when (AND (NEQ SKW SKETCHW) (ELT.INSIDE.SKETCHWP GELT SKW)) do (SKETCH.ADD.AND.DISPLAY1 GELT SKW GROUPFLG)) (RETURN ADDEDELT]) (SK.ADD.ELEMENTS [LAMBDA (ELEMENTS SKW) (* adds a list of global elements to a viewer but doesn't make an entry on the history list.) (for ELT in ELEMENTS do (SK.ADD.ELEMENT ELT SKW]) (SK.CHECK.WHENADDEDFN [LAMBDA (VIEWER GELT) (* rrb "19-Oct-85 17:36") (* checks if the sketch has a when added fn and if so, calls it and interprets the result. Returns a list of the elements that should be deleted.) (PROG ((SKETCH (INSURE.SKETCH VIEWER)) ADDFN RESULT) (COND ([NULL (SETQ ADDFN (GETSKETCHPROP SKETCH (QUOTE WHENADDEDFN] (RETURN GELT))) (SETQ RESULT (APPLY* ADDFN VIEWER GELT)) (COND ((EQ RESULT (QUOTE DON'T)) (RETURN NIL)) ((GLOBALELEMENTP RESULT) (RETURN RESULT)) (T (RETURN GELT]) (SK.APPLY.MENU.COMMAND [LAMBDA (COMMAND SKETCHW) (* rrb " 3-Jan-85 13:17") (* calls the function appropriate for the item selected from the command menu associated with a figure window.) (* This is a separate function so it can be called by both pop up and fixed menu operations.) (COND ((NULL COMMAND) NIL) ((type? SKETCHTYPE COMMAND) (* if the selected item is an element type, add an instance.) (SKETCHW.ADD.INSTANCE COMMAND SKETCHW)) [(LISTP COMMAND) (* EVAL it) (EVAL (APPEND COMMAND (CONS (KWOTE SKETCHW] (T (APPLY* COMMAND SKETCHW]) (SK.DELETE.ELEMENT1 [LAMBDA (OLDGELT SKETCHW GROUPFLG) (* rrb "19-Oct-85 17:09") (* deletes an element to a sketch window and handles propagation to all other figure windows) (* GROUPFLG indicates that this is part of a group operation and hence display and image object deleted fns don't need to be called.) (PROG ((SKETCH (SKETCH.FROM.VIEWER SKETCHW)) LOCALELT) (* delete the element to the sketch.) (OR (REMOVE.ELEMENT.FROM.SKETCH OLDGELT SKETCH) (RETURN NIL)) (* do the window that the interaction occurred in first.) (SK.ERASE.AND.DELETE.ITEM (SK.LOCAL.ELT.FROM.GLOBALPART OLDGELT SKETCHW) SKETCHW GROUPFLG) (* propagate to other windows.) (for SKW in (ALL.SKETCH.VIEWERS SKETCH) when (AND (NEQ SKW SKETCHW) (SETQ LOCALELT ( SK.LOCAL.ELT.FROM.GLOBALPART OLDGELT SKW))) do (SK.ERASE.AND.DELETE.ITEM LOCALELT SKW GROUPFLG)) (OR GROUPFLG (SK.CHECK.IMAGEOBJ.WHENDELETEDFN OLDGELT SKETCHW)) (RETURN OLDGELT]) (SK.MARK.DIRTY [LAMBDA (SKETCH) (* rrb "27-Nov-84 12:28") (* marks a sketch as having been changed. Puts a flag on its viewers.) (for SKW in (ALL.SKETCH.VIEWERS SKETCH) do (WINDOWPROP SKW (QUOTE SKETCHCHANGED) T]) (SK.MARK.UNDIRTY [LAMBDA (SKETCH) (* rrb "29-Nov-84 18:03") (* marks a sketch as having been changed. Puts a flag on its viewers.) (for SKW in (ALL.SKETCH.VIEWERS SKETCH) do (WINDOWPROP SKW (QUOTE SKETCHCHANGED) (QUOTE OLD]) (SK.MENU.AND.RETURN.FIELD [LAMBDA (ELEMENTTYPE) (* rrb "11-May-84 16:03") (* returns a field list of the field to be changed.) (PROG ((ITEMS (CHANGEABLEFIELDITEMS ELEMENTTYPE))) (RETURN (COND ((NULL ITEMS) NIL) [(NULL (CDR ITEMS)) (EVAL (CADR (CAR ITEMS] (T (MENU (create MENU ITEMS ← ITEMS CENTERFLG ← T TITLE ← "Choose which property to change"]) (SK.SCALE.POSITION.INTO.VIEWER [LAMBDA (POS SCALE) (* rrb "29-Jan-85 14:51") (* scales a position into window coordinates from global coordinates.) (create POSITION XCOORD ←(FIXR (QUOTIENT (fetch (POSITION XCOORD) of POS) SCALE)) YCOORD ←(FIXR (QUOTIENT (fetch (POSITION YCOORD) of POS) SCALE]) (SKETCH.SET.BRUSH.SHAPE [LAMBDA (W) (* rrb "11-Dec-84 15:31") (* Sets the shape of the current brush) (PROG [(NEWSHAPE (PAINTW.READBRUSHSHAPE)) (NOWBRUSH (fetch (SKETCHCONTEXT SKETCHBRUSH) of (WINDOWPROP W (QUOTE SKETCHCONTEXT] (RETURN (AND NEWSHAPE (replace (SKETCHCONTEXT SKETCHBRUSH) of (WINDOWPROP W (QUOTE SKETCHCONTEXT)) with (create BRUSH using NOWBRUSH BRUSHSHAPE ← NEWSHAPE]) (SKETCH.SET.BRUSH.SIZE [LAMBDA (W) (* rrb "12-Jan-85 10:13") (* sets the size of the current brush) (SK.SET.DEFAULT.BRUSH.SIZE [READBRUSHSIZE (fetch (BRUSH BRUSHSIZE) of (fetch (SKETCHCONTEXT SKETCHBRUSH) of (WINDOWPROP W (QUOTE SKETCHCONTEXT] W]) (SKETCHW.CLOSEFN [LAMBDA (SKW) (* rrb "12-Nov-85 10:46") (* close function for a viewer. Removes itself from the list of viewers.) (PROG (PROCINFO) [COND [(SETQ PROCINFO (WINDOWPROP SKW (QUOTE DOCUMENTINFO))) (* this window came from a tedit document.) [COND ((WINDOWPROP SKW (QUOTE SKETCHCHANGED)) (COND ((EQ (UPDATE.IMAGE.IN.DOCUMENT SKW) (QUOTE DON'T)) (RETURN (QUOTE DON'T] (COND ([OR (TTY.PROCESSP (THIS.PROCESS)) (TTY.PROCESSP (WINDOWPROP SKW (QUOTE PROCESS] (* if this process or the sketch process has the tty, give it back to the Tedit that this window came from.) (AND [PROCESSP (SETQ PROCINFO (WINDOWPROP (fetch (SKETCHDOCUMENTINFO FROMTEDITWINDOW) of PROCINFO) (QUOTE PROCESS] (TTY.PROCESS PROCINFO] ((AND (NOT (WINDOWPROP SKW (QUOTE DONTQUERYCHANGES))) (EQ (WINDOWPROP SKW (QUOTE SKETCHCHANGED)) T)) (* ask if user really wants to close) (STATUSPRINT SKW " ") (COND ((MOUSECONFIRM "unsaved changes ... press LEFT to close anyway" T ( GETPROMPTWINDOW SKW)) (* close the prompt window which MOUSECONFIRM brought up.) (CLOSEPROMPTWINDOW SKW)) (T (RETURN (QUOTE DON'T] (REMOVE.SKETCH.VIEWER (WINDOWPROP SKW (QUOTE SKETCH)) SKW) (* kill the process that supports the typing.) (DEL.PROCESS (WINDOWPROP SKW (QUOTE PROCESS) NIL)) (WINDOWADDPROP SKW (QUOTE OPENFN) (QUOTE SKETCHW.REOPENFN]) (SKETCHW.OUTFN [LAMBDA (SKW) (* rrb "24-Jan-85 10:06") (* the cursor is leaving the window, updates any structures that may be spread out for efficiency.) NIL]) (SKETCHW.REOPENFN [LAMBDA (SKW) (* rrb " 7-Feb-84 11:31") (* reopenfn for viewers. Adds it back onto the list of global viewers.) (ADD.SKETCH.VIEWER (WINDOWPROP SKW (QUOTE SKETCH)) SKW) (WINDOWPROP SKW (QUOTE PROCESS) (ADD.PROCESS (LIST (FUNCTION WB.EDITOR) (KWOTE SKW]) (MAKE.LOCAL.SKETCH [LAMBDA (SKETCH SKETCHREGION SCALE STREAM EVERYTHINGFLG) (* rrb "22-Apr-85 16:45") (* * calculate the local parts for the region of the sketch at a given scale. EVERYTHINGFLG provides a way to override the inside check. This is necessary because the inside check works on local elements. When the inside check is change to work on global elements, this can be removed.) (for SKELT in (fetch (SKETCH SKETCHELTS) of (INSURE.SKETCH SKETCH)) when (OR EVERYTHINGFLG (SK.INSIDE.REGION SKELT SKETCHREGION)) collect (SK.LOCAL.FROM.GLOBAL SKELT STREAM SCALE]) (MAP.SKETCHSPEC.INTO.VIEWER [LAMBDA (SKETCH SKW) (* rrb "12-May-85 17:02") (* creates the local parts of a sketch and puts it onto the viewer.) (PROG ((SKREGION (WINDOWPROP SKW (QUOTE REGION.VIEWED))) SPECS) (* local specs are kept as a TCONC cell so that additions to the end are fast.) (RETURN (WINDOWPROP SKW (QUOTE SKETCHSPECS) (CONS [SETQ SPECS (CONS (fetch (SKETCH SKETCHNAME) of SKETCH) (for SKELT in (fetch (SKETCH SKETCHELTS) of SKETCH) when (SK.INSIDE.REGION SKELT SKREGION) collect (SK.LOCAL.FROM.GLOBAL SKELT SKW] (LAST SPECS]) (SKETCHW.REPAINTFN [LAMBDA (W REG STOPIFMOUSEDOWN NEWGRIDFLG) (* rrb " 3-Sep-85 16:01") (* redisplays the sketch in a window) (* for now ignore the region.) (* if STOPIFMOUSEDOWN is T, it displays some but stops if the button left or middle button is still down and returns STOPPED) (DSPOPERATION (QUOTE PAINT) W) (DSPRIGHTMARGIN 65000 W) (* I don't know exactly how scrolling ever gets turned on but it has.) (DSPSCROLL (QUOTE OFF) W) (PROG1 (SKETCHW.REPAINTFN1 W REG (AND STOPIFMOUSEDOWN (SETUPTIMER AUTOZOOM.REPAINT.TIME)) NEWGRIDFLG) (SKED.SELECTION.FEEDBACK W]) (SKETCHW.REPAINTFN1 [LAMBDA (SKW REGION TIMER NEWGRIDFLG) (* rrb " 3-Sep-85 16:00") (* Draws all of the local elements in the sketch window SKW. internal function to SKETCHW.REPAINTFN This entry is provided so that SK.DRAWFIGURE.IF can RETFROM it if the timer has expired and a button is down.) (MAPSKETCHSPECS (LOCALSPECS.FROM.VIEWER SKW) (COND (TIMER (* call a version of SK.DRAWFIGURE that checks the time.) (FUNCTION SK.DRAWFIGURE.IF)) (T (FUNCTION SK.DRAWFIGURE))) SKW REGION (WINDOW.SCALE SKW)) (COND ((WINDOWPROP SKW (QUOTE GRIDUP)) (* if grid is up, redisplay it) (SK.DISPLAY.GRID.POINTS SKW NEWGRIDFLG]) (SK.DRAWFIGURE.IF [LAMBDA (SCREENELT STREAM REGION SCALE) (* rrb "22-Jan-85 11:34") (* draws an element of a sketch in a window. If the free variable TIMER has expired and a button is down, it RETFROMs the repainting function.) (PROG1 (SK.DRAWFIGURE SCREENELT STREAM REGION SCALE) (AND TIMER (MOUSESTATE (OR LEFT MIDDLE)) (TIMEREXPIRED? TIMER) (RETFROM (QUOTE SKETCHW.REPAINTFN1) (QUOTE STOPPED]) (SKETCHW.SCROLLFN [LAMBDA (SKW XDELTA YDELTA CONTINUOUSFLG) (* rrb "29-Aug-85 19:13") (* scroll function for a sketch window. It must check to see which elements need to get added and deleted from the ones currently viewed as a result of the scrolling. Also if an element gets added, the clipping region must be expanded because part of the display of the object may be in the already visible part of the window.) (PROG ([SKETCH (fetch (SKETCH SKETCHELTS) of (INSURE.SKETCH (SKETCH.FROM.VIEWER SKW] (NOWREG (DSPCLIPPINGREGION NIL SKW)) NEWREGION NEWLOCALREGION INNEW? NEWONES LOCALELT SCALE) (* clear the caret.) (SKED.CLEAR.SELECTION SKW) [COND (CONTINUOUSFLG (* set XDELTA and YDELTA for continuous scrolling) [COND ((AND XDELTA (NEQ XDELTA 0)) (COND ((IGREATERP XDELTA 0) (SETQ XDELTA 12)) (T (SETQ XDELTA -12] (COND ((AND YDELTA (NEQ YDELTA 0)) (COND ((IGREATERP YDELTA 0) (SETQ YDELTA 12)) (T (SETQ YDELTA -12] [SETQ NEWREGION (UNSCALE.REGION (SETQ NEWLOCALREGION (CREATEREGION (DIFFERENCE (fetch (REGION LEFT) of NOWREG) (COND (XDELTA) (0))) (DIFFERENCE (fetch (REGION BOTTOM) of NOWREG) (COND (YDELTA) (0))) (fetch (REGION WIDTH) of NOWREG) (fetch (REGION HEIGHT) of NOWREG))) (SETQ SCALE (WINDOW.SCALE SKW] (* update the current image to contain the things that will be there after the scroll, then scroll.) [for GELT in SKETCH do (SETQ INNEW? (SK.INSIDE.REGION GELT NEWREGION)) (COND [(SETQ LOCALELT (SK.LOCAL.ELT.FROM.GLOBALPART GELT SKW)) (* if it is not supposed to be in the new region, remove it.) (OR INNEW? (COND ((REGIONSINTERSECTP NEWLOCALREGION (SK.ITEM.REGION LOCALELT)) (* part of image may overlap the part of sketch that is still showing) (SK.ERASE.AND.DELETE.ITEM LOCALELT SKW)) (T (SK.DELETE.ITEM LOCALELT SKW] (INNEW? (* just came in) (SETQ NEWONES (CONS GELT NEWONES] (SCROLLBYREPAINTFN SKW XDELTA YDELTA) (SKETCHW.FIG.CHANGED SKW) (SK.UPDATE.REGION.VIEWED SKW) (for GELT in NEWONES do (SKETCH.ADD.AND.DISPLAY1 GELT SKW SCALE]) (SK.UPDATE.EVENT.SELECTION [LAMBDA (HOTSPOTCACHE X1 Y1 X2 Y2 SCALE WINDOW COPYMODE DELETEMODE) (* rrb "31-Jan-85 11:35") (* * internal function to SK.COPY.BUTTONEVENTFN that determines the elements within the given bounds and selects or deselects them.) (PROG (SELITEMS) (RETURN (COND ((LASTMOUSESTATE UP) (* don't do anything with button up.) NIL) ((SETQ SELITEMS (SK.LOCAL.ITEMS.IN.REGION HOTSPOTCACHE (MIN X1 X2) (MIN Y1 Y2) (MAX X1 X2) (MAX Y1 Y2))) (* OLD CODE (SETQ SELITEMS (SK.LOCAL.ITEMS.IN.REGION HOTSPOTCACHE (REGION.FROM.COORDINATES X1 Y1 X2 Y2) SCALE))) (COND [(LASTMOUSESTATE (OR (ONLY LEFT) (ONLY MIDDLE))) (* left or middle only selects.) (for SELITEM in SELITEMS do (SK.ADD.SELECTION SELITEM WINDOW (SK.BUTTONEVENT.MARK COPYMODE DELETEMODE] (T (* anything but left only should cause deselect.) (for SELITEM in SELITEMS do (SK.REMOVE.SELECTION SELITEM WINDOW (SK.BUTTONEVENT.MARK COPYMODE DELETEMODE]) (LIGHTGRAYWINDOW [LAMBDA (WINDOW) (* rrb "28-Jun-84 10:27") (DSPFILL NIL 1 (QUOTE INVERT) WINDOW) WINDOW]) (SK.ADD.SPACES [LAMBDA (STRLST) (* rrb "19-Jul-85 15:11") (* adds eols between the elements of STRLST) (for STR in STRLST join (COND ((EQUAL STR "") NIL) ((EQ (NTHCHARCODE STR -1) (CHARCODE EOL)) (* if it already ends in CR, don't add one.) (LIST STR)) (T (LIST STR " "]) (SK.SKETCH.MENU [LAMBDA (SKW) (* rrb "12-Sep-85 11:50") (* brings up the normal sketch command menu.) (SK.MIDDLE.TITLEFN SKW T]) (SK.CHECK.IMAGEOBJ.WHENDELETEDFN [LAMBDA (GELT SKETCHW) (* rrb "19-Oct-85 17:10") (* check to see if a when deleted function needs to be applied and applies it.) (SELECTQ (fetch (GLOBALPART GTYPE) of GELT) (SKIMAGEOBJ (* deleting an image object apply WHENDELETEDFN) (SK.APPLY.IMAGEOBJ.WHENDELETEDFN GELT SKETCHW)) (GROUP (for GELT in (fetch (GROUP LISTOFGLOBALELTS) of GELT) do (SK.CHECK.IMAGEOBJ.WHENDELETEDFN GELT SKETCHW))) NIL]) (SK.APPLY.IMAGEOBJ.WHENDELETEDFN [LAMBDA (GELT SKETCHW) (* rrb "30-Jul-85 15:35") (* applies the when deleted function for an image object.) (PROG (IMAGEOBJ FN) (COND ((AND (SETQ FN (IMAGEOBJPROP (SETQ IMAGEOBJ (fetch (SKIMAGEOBJ SKIMAGEOBJ) of (fetch (GLOBALPART INDIVIDUALGLOBALPART) of GELT))) (QUOTE WHENDELETEDFN))) (NEQ FN (QUOTE NILL))) (* documentation calls for passing text streams as well but there aren't any.) (APPLY* FN IMAGEOBJ SKETCHW]) (SK.RETURN.TTY [LAMBDA (W) (* rrb "29-Aug-85 11:09") (* gives up the tty when the window is shrunken.) (AND (TTY.PROCESSP (WINDOWPROP W (QUOTE PROCESS))) (TTY.PROCESS T]) (SK.TAKE.TTY [LAMBDA (W) (* rrb "29-Aug-85 11:10") (* takes the tty when the window is expanded) (TTY.PROCESS (WINDOWPROP W (QUOTE PROCESS]) ) (* fns for dealing with the menu) (DEFINEQ (SKETCH.COMMANDMENU [LAMBDA (ITEMS TITLE) (* rrb "17-Oct-85 10:38") (create MENU ITEMS ← ITEMS CENTERFLG ← T WHENSELECTEDFN ←(FUNCTION SKETCHW.SELECTIONFN) MENUFONT ←(FONTNAMELIST (FONTCREATE BOLDFONT)) TITLE ← TITLE]) (SKETCH.COMMANDMENU.ITEMS [LAMBDA (ADDFIXITEM ELEMENTTYPES) (* rrb "19-Nov-85 13:25") (* returns a list of the items that are in the sketch command menu.) (APPEND [QUOTE ((Delete SK.DELETE.ELT "Deletes one or more elements from the sketch." (SUBITEMS ("Delete element(s)" SK.DELETE.ELT "Deletes one or more elements from the sketch.") ("Delete point" SK.DELETE.KNOT "Deletes a control point from a wire or curve."] [QUOTE ((Move SK.APPLY.DEFAULT.MOVE "Moves a control point, or one or more elements." (SUBITEMS (Move% point SK.MOVE.ELEMENT.POINT "Moves one of the control points.") ("Move points" SK.MOVE.POINTS "Moves a collection of control points.") ("Move elements" SK.MOVE.ELT "Moves one or more elements of the sketch.") ("Move onto grid" SK.PUT.ELTS.ON.GRID "Moves control points to nearest grid point.") ("Two pt transform" SK.TWO.PT.TRANSFORM.ELTS "Moves one or more sketch elements with a two point transformation.") ("Three pt transform" SK.THREE.PT.TRANSFORM.ELTS "Moves one or more sketch elements with a three point transformation.") ("Set MOVE command mode" SK.SET.MOVE.MODE "changes whether the MOVE command applies to points or elements." (SUBITEMS (Points SK.SET.MOVE.MODE.POINTS "Top level MOVE command will be the same as MOVE POINTS command.") (Elements SK.SET.MOVE.MODE.ELEMENTS "Top level MOVE command will be the same as MOVE ELEMENTS command.") (Combined SK.SET.MOVE.MODE.COMBINED "MOVE command will move points if a single point is clicked; elements otherwise"] [QUOTE ((Copy SK.COPY.ELT "Copies a piece of the sketch." (SUBITEMS ("Copy elements" SK.COPY.ELT "copies one or more elements of the sketch.") ( "Copy w/2 pt trans" SK.COPY.AND.TWO.PT.TRANSFORM.ELTS "Copies one or more sketch elements with a two point transformation.") ( "Copy w/3 pt trans" SK.COPY.AND.THREE.PT.TRANSFORM.ELTS "Copies one or more sketch elements with a three point transformation."] (QUOTE ((Change SK.CHANGE.ELT "Changes a property of a piece."))) [AND (GETD (QUOTE SK.SEL.AND.SHOW.ANNOTE)) (QUOTE ((Annotate SK.SEL.AND.SHOW.ANNOTE "Manipulates the annotations from a selected element." (SUBITEMS (Add% Annotation SK.SEL.AND.ADD.ANNOTE "Adds an annotation to an element.") (Delete% Annotation SK.SEL.AND.DELETE.ANNOTE "Deletes the annotation from an element.") (Show% Annotation SK.SEL.AND.SHOW.ANNOTE "Shows the annotation of an element."] (for ELEMENT in (COND ((EQ ELEMENTTYPES T) SKETCH.ELEMENT.TYPE.NAMES) (T ELEMENTTYPES)) when [fetch (SKETCHTYPE LABEL) of (SETQ ELEMENT (GETPROP ELEMENT (QUOTE SKETCHTYPE] collect (* add the sketch elements that have a label.) (LIST (fetch (SKETCHTYPE LABEL) of ELEMENT) ELEMENT (fetch (SKETCHTYPE DOCSTR) of ELEMENT))) [AND (GETD (QUOTE SK.SEL.AND.SHOW.ANNOTE)) (QUOTE ((Link SK.ADD.ANNOTATION "Adds an annotation object."] [AND (GETD (QUOTE GROUP.DRAWFN)) (QUOTE ((Group SK.GROUP.ELTS "groups a collection of elements into a single unit."] [AND (GETD (QUOTE GROUP.DRAWFN)) (QUOTE ((UnGroup SK.UNGROUP.ELT "replaces a group element by its constituents."] [QUOTE ((Undo SK.UNDO.LAST "undoes the previous event. Or the latest one that hasn't been undone." (SUBITEMS (?Undo SK.SEL.AND.UNDO "allows selection of an event to undo.") (Undo SK.UNDO.LAST "undoes the previous event. Or the latest one that hasn't been undone."] [QUOTE ((Defaults SKETCH.SET.A.DEFAULT "Changes one of the default characteristics." (SUBITEMS (Line SKETCH.SET.BRUSH.SIZE "Sets the characteristics of the default brush." (SUBITEMS (Size SKETCH.SET.BRUSH.SIZE "Sets the size of the default brush") (Shape SKETCH.SET.BRUSH.SHAPE "Sets the shape of the default brush") (Add% arrowhead SK.SET.LINE.ARROWHEAD "Sets the arrowhead characteristics of new lines.") ("Mouse line specs" SK.SET.LINE.LENGTH.MODE "Sets whether the lines drawn with the middle mouse button connect to each other."))) (Arrowhead SK.SET.ARROWHEAD.LENGTH "Sets the characteristics of the default arrowhead." (SUBITEMS (Size SK.SET.ARROWHEAD.LENGTH) (Angle SK.SET.ARROWHEAD.ANGLE) (Type SK.SET.ARROWHEAD.TYPE))) (Text SK.SET.TEXT.SIZE "Sets the size of newly added text." (SUBITEMS ("Font size" SK.SET.TEXT.SIZE "Sets the size of newly added text.") ("Font family" SK.SET.TEXT.FONT "Sets the font family of newly added text.") ("Horizontal justification" SK.SET.TEXT.HORIZ.ALIGN "Sets the horizontal justification mode of new text.") ("Vertical justification" SK.SET.TEXT.VERT.ALIGN "Sets the vertical justification of new text.") ("Bold and/or italic" SK.SET.TEXT.LOOKS "Sets the bold and italic look of new text."))) (Text% Box SK.SET.TEXTBOX.HORIZ.ALIGN "Sets the alignment of text within new text boxes." (SUBITEMS ("Horizontal justification" SK.SET.TEXTBOX.HORIZ.ALIGN "Sets the horizontal alignment of text within new text boxes.") ("Vertical justification" SK.SET.TEXTBOX.VERT.ALIGN "Sets the vertical alignment of text within new text boxes."))) (Arc SK.SET.ARC.DIRECTION "Sets the direction arcs go around their circle." (SUBITEMS ("Clockwise" SK.SET.ARC.DIRECTION.CW "Makes new arcs go around in the clockwise direction") ("Counterclockwise" SK.SET.ARC.DIRECTION.CCW "Makes new arcs go around in the counterclockwise direction"))) ("Input scale" SK.SET.INPUT.SCALE "Sets the scale for newly added lines and text." (SUBITEMS ("Read new input scale" SK.SET.INPUT.SCALE "Reads a new input scale.") ("Make input scale current" SK.SET.INPUT.SCALE.CURRENT "makes the input scale be the scale of the current view."))) (Feedback SK.SET.FEEDBACK.MODE "Controls the amount of feedback when adding new curves, circles, etc." (SUBITEMS ("Points only" SK.SET.FEEDBACK.POINT "Only the control points will be shown when entering elements.") ("Fast figures" SK.SET.FEEDBACK.VERBOSE "Wires, circles and ellipses are shown while they are being entered.") ("All figures" SK.SET.FEEDBACK.ALWAYS "Most elements are shown while they are being entered. This will be slow for arcs and curves."] [QUOTE ((Grid SK.SET.GRID "Flips between using the grid and not using the grid." (SUBITEMS (Turn% grid% ON SK.TURN.GRID.ON "turns on a grid. Only pts on the grid can be selected.") (Turn% grid% OFF SK.TURN.GRID.OFF "turns off the grid. Any point can be selected.") (LARGER% Grid SK.MAKE.GRID.LARGER "doubles the distance between the grid points.") (smaller% Grid SK.MAKE.GRID.SMALLER "halves the distance between the grid points.") ("Display grid" SK.DISPLAY.GRID "XORs a point at each grid point. If grid is visible, this will erase it.") ("Remove grid display" SK.TAKE.DOWN.GRID "XORs a point at each grid point. If grid is visible, this will erase it."] [QUOTE (("Move view" SKETCH.ZOOM "makes a new region the part of the sketch visible." (SUBITEMS ("Move view" SKETCH.ZOOM "changes the scale of the display.") (AutoZoom SKETCH.AUTOZOOM "changes the scale around a selected point.") (Home SKETCH.HOME "returns to the origin at the original scale") ("Fit it" SK.FRAME.IT "moves so that the entire sketch just fits in the window") ("Restore view" SK.RESTORE.VIEW "Moves to a previously saved view." (SUBITEMS ("Restore view" SK.RESTORE.VIEW "Moves to a previously saved view.") ("Save view" SK.NAME.CURRENT.VIEW "saves the current view (position and scale) of the sketch for easy return.") ("Forget view" SK.FORGET.VIEW "Deletes a previously saved view."))) ("Coord window" ADD.GLOBAL.DISPLAY "creates a window that shows the cursor in global coordinates." (SUBITEMS ("Coord window" ADD.GLOBAL.DISPLAY "creates a window that shows the cursor position in global coordinates.") ("Grid coord window" ADD.GLOBAL.GRIDDED.DISPLAY "creates a window that shows the grid position nearest the cursor in global coordinates."))) (New% window SKETCH.NEW.VIEW "opens another viewer onto this sketch"] [QUOTE ((HardCopy HARDCOPYIMAGEW "sends a copy of the current window contents on the default printer." (SUBITEMS ("To a file" HARDCOPYIMAGEW.TOFILE "Puts image on a file; prompts for filename and format") ("To a printer" HARDCOPYIMAGEW.TOPRINTER "Sends image to a printer of your choosing") ("Whole sketch" SK.LIST.IMAGE "Sends the image of the whole sketch at the current scale to the printer." (SUBITEMS ("To a file" SK.LIST.IMAGE.ON.FILE "Sends the image of the whole sketch at the current scale on a file.") ("To a printer" SK.LIST.IMAGE "Sends the image of the whole sketch at the current scale to the printer."))) (Hardcopy% Display SK.SET.HARDCOPY.MODE "Makes the display correspond to the hardcopy image on the default printer.") (Normal% Display SK.UNSET.HARDCOPY.MODE "Changes the display to use display fonts."] (QUOTE ((Put SK.PUT.ON.FILE "saves this sketch on a file"))) (QUOTE ((Get SK.GET.FROM.FILE "gets a sketch from a file."))) [AND ADDFIXITEM (QUOTE ((Fix% Menu SK.FIX.MENU "leaves up the menu of sketch operations."] (AND (EQUAL (USERNAME) "BURTON.PA") (QUOTE ((inspect INSPECT.SKETCH "Calls the Inspector on the figure data structures."]) (CREATE.SKETCHW.COMMANDMENU [LAMBDA (MENUTITLE ADDFIXITEM ELEMENTTYPES) (* rrb "17-Oct-85 10:50") (* returns the control menu for a figure window.) (SKETCH.COMMANDMENU (SKETCH.COMMANDMENU.ITEMS ADDFIXITEM ELEMENTTYPES) MENUTITLE]) (SKETCHW.SELECTIONFN [LAMBDA (ITEM MENU) (* rrb "24-Jan-85 10:15") (* calls the function appropriate for the item selected from the command menu associated with a figure window.) (PROG ((SKW (WINDOWPROP (WFROMMENU MENU) (QUOTE MAINWINDOW))) PROMPTW) (* clear the prompt window if there is one.) (CLOSEPROMPTWINDOW SKW) (* reset the line being drawn if there is one.) (RESET.LINE.BEING.INPUT SKW) (RETURN (SK.APPLY.MENU.COMMAND (CADR ITEM) SKW]) ) (* fns for dealing with sketch structures) (DEFINEQ (SKETCH.CREATE [LAMBDA ARGS (* rrb " 6-Nov-85 11:16") (PROG [(SKETCH (create SKETCH SKETCHNAME ←(AND (GREATERP ARGS 0) (ARG ARGS 1] (PUTSKETCHPROP SKETCH (QUOTE SKETCHCONTEXT) (CREATE.DEFAULT.SKETCH.CONTEXT)) (PUTSKETCHPROP SKETCH (QUOTE VERSION) SKETCH.VERSION) (* pick out the props that are context,) [COND ((GREATERP ARGS 1) (for I from 2 to ARGS by 2 do (PUTSKETCHPROP SKETCH (ARG ARGS I) (ARG ARGS (ADD1 I] (RETURN SKETCH]) (GETSKETCHPROP [LAMBDA (SKETCH PROPERTY) (* rrb " 5-Nov-85 15:35") (* retrieves the property of a sketch) (PROG ((SKETCH (INSURE.SKETCH SKETCH)) SKETCHCONTEXT) (SETQ SKETCHCONTEXT (LISTGET (fetch (SKETCH SKETCHPROPS) of SKETCH) (QUOTE SKETCHCONTEXT))) (RETURN (SELECTQ PROPERTY (BRUSH (fetch (SKETCHCONTEXT SKETCHBRUSH) of SKETCHCONTEXT)) (SHAPE (fetch (BRUSH BRUSHSHAPE) of (fetch (SKETCHCONTEXT SKETCHBRUSH) of SKETCHCONTEXT))) (SIZE (fetch (BRUSH BRUSHSIZE) of (fetch (SKETCHCONTEXT SKETCHBRUSH) of SKETCHCONTEXT))) (COLOR (fetch (BRUSH BRUSHCOLOR) of (fetch (SKETCHCONTEXT SKETCHBRUSH) of SKETCHCONTEXT))) (FONT (fetch (SKETCHCONTEXT SKETCHFONT) of SKETCHCONTEXT)) (TEXTALIGNMENT (fetch (SKETCHCONTEXT SKETCHTEXTALIGNMENT) of SKETCHCONTEXT)) (ARROWHEAD (fetch (SKETCHCONTEXT SKETCHARROWHEAD) of SKETCHCONTEXT)) (DASHING (fetch (SKETCHCONTEXT SKETCHDASHING) of SKETCHCONTEXT)) (USEARROWHEAD (fetch (SKETCHCONTEXT SKETCHUSEARROWHEAD) of SKETCHCONTEXT)) (TEXTBOXALIGNMENT (fetch (SKETCHCONTEXT SKETCHTEXTBOXALIGNMENT) of SKETCHCONTEXT)) (TEXTURE (fetch (SKFILLING FILLING.COLOR) of (fetch (SKETCHCONTEXT SKETCHFILLING) of SKETCHCONTEXT))) ((FILLINGCOLOR BACKCOLOR) (fetch (SKFILLING FILLING.TEXTURE) of (fetch (SKETCHCONTEXT SKETCHFILLING) of SKETCHCONTEXT))) (LINEMODE (fetch (SKETCHCONTEXT SKETCHLINEMODE) of SKETCHCONTEXT) ) (ARCDIRECTION (fetch (SKETCHCONTEXT SKETCHARCDIRECTION) of SKETCHCONTEXT)) (MOVEMODE (fetch (SKETCHCONTEXT SKETCHMOVEMODE) of SKETCHCONTEXT) ) (ELEMENTS (fetch (SKETCH SKETCHELTS) of SKETCH)) (NAME (fetch (SKETCH SKETCHNAME) of SKETCH)) (LISTGET (fetch (SKETCH SKETCHPROPS) of SKETCH) PROPERTY]) (PUTSKETCHPROP [LAMBDA (SKETCH PROPERTY VALUE) (* rrb " 4-Dec-85 21:26") (* stores a property on a sketch Returns VALUE. Knows about the form of a sketch and does value checking (or should.)) (PROG ((SKETCH (INSURE.SKETCH SKETCH)) SKETCHCONTEXT PLIST) (SETQ PLIST (fetch (SKETCH SKETCHPROPS) of SKETCH)) (SETQ SKETCHCONTEXT (LISTGET (fetch (SKETCH SKETCHPROPS) of SKETCH) (QUOTE SKETCHCONTEXT))) [SELECTQ PROPERTY (BRUSH (replace (SKETCHCONTEXT SKETCHBRUSH) of SKETCHCONTEXT with VALUE)) (SHAPE (replace (SKETCHCONTEXT SKETCHBRUSH) of SKETCHCONTEXT with (create BRUSH using (fetch (SKETCHCONTEXT SKETCHBRUSH) of SKETCHCONTEXT) BRUSHSHAPE ← VALUE))) (SIZE (replace (SKETCHCONTEXT SKETCHBRUSH) of SKETCHCONTEXT with (create BRUSH using (fetch (SKETCHCONTEXT SKETCHBRUSH) of SKETCHCONTEXT) BRUSHSIZE ← VALUE))) (COLOR (replace (SKETCHCONTEXT SKETCHBRUSH) of SKETCHCONTEXT with (create BRUSH using (fetch (SKETCHCONTEXT SKETCHBRUSH) of SKETCHCONTEXT) BRUSHCOLOR ← VALUE))) (FONT (replace (SKETCHCONTEXT SKETCHFONT) of SKETCHCONTEXT with VALUE)) (TEXTALIGNMENT (replace (SKETCHCONTEXT SKETCHTEXTALIGNMENT) of SKETCHCONTEXT with VALUE)) (ARROWHEAD (replace (SKETCHCONTEXT SKETCHARROWHEAD) of SKETCHCONTEXT with VALUE)) (DASHING (replace (SKETCHCONTEXT SKETCHDASHING) of SKETCHCONTEXT with VALUE)) (USEARROWHEAD (replace (SKETCHCONTEXT SKETCHUSEARROWHEAD) of SKETCHCONTEXT with VALUE)) (TEXTBOXALIGNMENT (replace (SKETCHCONTEXT SKETCHTEXTBOXALIGNMENT) of SKETCHCONTEXT with VALUE)) (TEXTURE (replace (SKETCHCONTEXT SKETCHFILLING) of SKETCHCONTEXT with (create SKFILLING using (fetch (SKETCHCONTEXT SKETCHFILLING) of SKETCHCONTEXT) FILLING.TEXTURE ← VALUE))) ((BACKCOLOR FILLINGCOLOR) (replace (SKETCHCONTEXT SKETCHFILLING) of SKETCHCONTEXT with (create SKFILLING using (fetch (SKETCHCONTEXT SKETCHFILLING) of SKETCHCONTEXT) FILLING.COLOR ← VALUE))) (LINEMODE (replace (SKETCHCONTEXT SKETCHLINEMODE) of SKETCHCONTEXT with VALUE)) (ARCDIRECTION (replace (SKETCHCONTEXT SKETCHARCDIRECTION) of SKETCHCONTEXT with VALUE)) (MOVEMODE (replace (SKETCHCONTEXT SKETCHMOVEMODE) of SKETCHCONTEXT with VALUE)) [ELEMENTS (replace (SKETCH SKETCHTCELL) of SKETCH with (CONS VALUE (LAST VALUE] (NAME (replace (SKETCH SKETCHNAME) of SKETCH with VALUE)) (COND (PLIST (LISTPUT PLIST PROPERTY VALUE)) (T (replace (SKETCH SKETCHPROPS) of SKETCH with (LIST PROPERTY VALUE] (RETURN VALUE]) (CREATE.DEFAULT.SKETCH.CONTEXT [LAMBDA NIL (* rrb " 1-Nov-85 09:52") (* returns a default sketch context) (create SKETCHCONTEXT SKETCHBRUSH ← SK.DEFAULT.BRUSH SKETCHFONT ←[OR SK.DEFAULT.FONT (SK.FONT.LIST (DEFAULTFONT (QUOTE DISPLAY] SKETCHTEXTALIGNMENT ← SK.DEFAULT.TEXT.ALIGNMENT SKETCHARROWHEAD ←(create ARROWHEAD ARROWTYPE ← SK.DEFAULT.ARROW.TYPE ARROWANGLE ← SK.DEFAULT.ARROW.ANGLE ARROWLENGTH ← SK.DEFAULT.ARROW.LENGTH) SKETCHDASHING ← SK.DEFAULT.DASHING SKETCHUSEARROWHEAD ← NIL SKETCHTEXTBOXALIGNMENT ← SK.DEFAULT.TEXTBOX.ALIGNMENT SKETCHFILLING ←(SK.CREATE.DEFAULT.FILLING) SKETCHLINEMODE ← T SKETCHINPUTSCALE ← 1.0]) ) (PUTPROPS SKETCH.CREATE ARGNAMES (NIL (NAME . DEFAULTS&VALUES) . U)) (* fns for implementing copy and delete functions under keyboard control.) (DEFINEQ (SK.COPY.BUTTONEVENTFN [LAMBDA (WINDOW) (* rrb "10-Dec-85 16:41") (* * handles the button event when a copy key and/or the delete is held down. allows the user to select a group of the sketch elements from the sketch WINDOW. This is very similar to SK.SELECT.MULTIPLE.ITEMS) (* the selection protocol is left to add, right to delete. Multiple clicking in the same place upscales for both select and deselect. Sweeping will select or deselect all of the items in the swept out area.) (COND ([AND (TTY.PROCESSP (WINDOWPROP WINDOW (QUOTE PROCESS))) (OR (.MOVEKEYDOWNP.) (AND (.COPYKEYDOWNP.) (.DELETEKEYDOWNP.] (* this is going to be a move command.) (SELECTQ (fetch (SKETCHCONTEXT SKETCHMOVEMODE) of (WINDOWPROP WINDOW (QUOTE SKETCHCONTEXT))) (POINTS (SK.SEL.AND.MOVE.POINTS WINDOW)) (SK.SEL.AND.MOVE WINDOW))) ((LASTMOUSESTATE (NOT UP)) (PROG ((COPYMODE (OR (.COPYKEYDOWNP.) (.MOVEKEYDOWNP.))) [DELETEMODE (AND (TTY.PROCESSP (WINDOWPROP WINDOW (QUOTE PROCESS))) (OR (.DELETEKEYDOWNP.) (.MOVEKEYDOWNP.] HOTSPOTCACHE (SCALE (WINDOW.SCALE WINDOW)) OLDX ORIGX NEWX NEWY OLDY ORIGY MOVEDMUCHFLG SELITEMS RETURNVAL PREVMOUSEBUTTONS NOW MIDDLEONLYFLG OPERATION) [SETQ OPERATION (COND [COPYMODE (COND [(TTY.PROCESSP (WINDOWPROP WINDOW (QUOTE PROCESS))) (* this is not a copy select operation) (COND (DELETEMODE (QUOTE MOVE)) (T (QUOTE COPY] (T (QUOTE COPYSELECT] (DELETEMODE (QUOTE DELETE)) (T (* keys aren't still down.) (RETURN] (* create the cache for the elements that allow the current operation.) (SETQ HOTSPOTCACHE (SK.HOTSPOT.CACHE.FOR.OPERATION WINDOW OPERATION)) (COND ((NOT (SK.HAS.SOME.HOTSPOTS HOTSPOTCACHE)) (* no items don't do anything.) (RETURN))) (TOTOPW WINDOW) (SK.PUT.MARKS.UP WINDOW HOTSPOTCACHE) [STATUSPRINT WINDOW " " "Select elements to " (COND [COPYMODE (COND (DELETEMODE (QUOTE MOVE)) (T (QUOTE COPY] (DELETEMODE (QUOTE DELETE] (* no selections have been made at this point.) STARTOVERLP (GETMOUSESTATE) (COND ((AND (LASTMOUSESTATE UP) (SK.BUTTONEVENT.OVERP COPYMODE DELETEMODE)) (SK.TAKE.MARKS.DOWN WINDOW HOTSPOTCACHE) (RETURN))) (* MIDDLEONLYFLG is used to note case of picking characters out of a sketch.) (SETQ MIDDLEONLYFLG (LASTMOUSESTATE (ONLY MIDDLE))) SELECTLP (GETMOUSESTATE) (COND ((SK.BUTTONEVENT.OVERP COPYMODE DELETEMODE) (* user let up copy key. Put sketch into input buffer.) (SETQ RETURNVAL (WINDOWPROP WINDOW (QUOTE SKETCH.SELECTIONS))) (GO EXIT)) ([AND (LASTMOUSESTATE (NOT UP)) (OR (NOT (INSIDEP (WINDOWPROP WINDOW (QUOTE REGION)) LASTMOUSEX LASTMOUSEY)) (NOT (SK.BUTTONEVENT.SAME.KEYS COPYMODE DELETEMODE] (* if a button is down, and either the keystate is different from entry or the cursor is out of the window, stop this event.) (SETQ RETURNVAL NIL) (GO EXIT))) (* cursor is still inside or buttons are up, leave sketch selected.) (SETQ NEWY (LASTMOUSEY WINDOW)) (SETQ NEWX (LASTMOUSEX WINDOW)) (COND ((NEQ PREVMOUSEBUTTONS LASTMOUSEBUTTONS) (* a button has gone up or down, mark this as the origin of a new box to sweep.) (SETQ ORIGX NEWX) (SETQ ORIGY NEWY) (COND [(AND (EQ PREVMOUSEBUTTONS 0) (NULL MOVEDMUCHFLG) NOW) (* user double clicked and an element was selected.) (SETQ NOW) (COND [[OR (AND (LASTMOUSESTATE (ONLY LEFT)) (NOT (SETQ MIDDLEONLYFLG))) (AND MIDDLEONLYFLG (LASTMOUSESTATE (ONLY MIDDLE] (* select the whole document.) (for SELITEM in (LOCALSPECS.FROM.VIEWER WINDOW) do (SK.ADD.SELECTION SELITEM WINDOW (SK.BUTTONEVENT.MARK COPYMODE DELETEMODE] (T (* thing selected is a the whole sketch, clear everything and start over.) (for SELITEM in (LOCALSPECS.FROM.VIEWER WINDOW) do (SK.REMOVE.SELECTION SELITEM WINDOW (SK.BUTTONEVENT.MARK COPYMODE DELETEMODE))) (* set PREVMOUSEBUTTONS to cause reinitialization.) (SETQ PREVMOUSEBUTTONS) (GO STARTOVERLP] [(LASTMOUSESTATE (NOT UP)) (* add or delete the element if any that the point is in. This uses a different method which takes into account the size of the selection knots which the area sweep doesn't.) (COND ((SETQ NOW (IN.SKETCH.ELT? HOTSPOTCACHE (create POSITION XCOORD ← NEWX YCOORD ← NEWY))) (COND ([OR (AND (LASTMOUSESTATE (ONLY LEFT)) (NOT (SETQ MIDDLEONLYFLG))) (AND MIDDLEONLYFLG (LASTMOUSESTATE (ONLY MIDDLE] (* left or middle selects.) (SK.ADD.SELECTION NOW WINDOW (SK.BUTTONEVENT.MARK COPYMODE DELETEMODE))) ((LASTMOUSESTATE RIGHT) (* right cause deselect.) (SK.REMOVE.SELECTION NOW WINDOW (SK.BUTTONEVENT.MARK COPYMODE DELETEMODE] (T (SETQ MOVEDMUCHFLG))) (SETQ PREVMOUSEBUTTONS LASTMOUSEBUTTONS)) ((COND (MOVEDMUCHFLG (OR (NEQ OLDX NEWX) (NEQ OLDY NEWY))) ((OR (IGREATERP (IABS (IDIFFERENCE ORIGX NEWX)) SK.NO.MOVE.DISTANCE) (IGREATERP (IABS (IDIFFERENCE ORIGY NEWY)) SK.NO.MOVE.DISTANCE)) (* make the first pick move further so that it is easier to multiple click.) (SETQ MOVEDMUCHFLG T))) (* cursor has moved more than the minimum amount since last noticed.) (* add or delete any with in the swept out area.) (SK.UPDATE.EVENT.SELECTION HOTSPOTCACHE ORIGX ORIGY NEWX NEWY SCALE WINDOW COPYMODE DELETEMODE))) (SETQ OLDX NEWX) (SETQ OLDY NEWY) (GO SELECTLP) EXIT (* clear the selections from the window.) (for SEL in (WINDOWPROP WINDOW (QUOTE SKETCH.SELECTIONS)) do (SK.REMOVE.SELECTION SEL WINDOW (SK.BUTTONEVENT.MARK COPYMODE DELETEMODE)) ) (SK.TAKE.MARKS.DOWN WINDOW HOTSPOTCACHE) (CLOSEPROMPTWINDOW WINDOW) (* if middle was the only button used to select, return only the text characters.) (RETURN (AND RETURNVAL (COND [(TTY.PROCESSP (WINDOWPROP WINDOW (QUOTE PROCESS))) (* the results will be going to this same window) (COND ((AND COPYMODE DELETEMODE) (* move the elements) (SK.MOVE.ELEMENTS RETURNVAL WINDOW)) [COPYMODE (* copy them) (COND (MIDDLEONLYFLG (* if middle only, just get the characters.) (COPYINSERT (SK.BUILD.IMAGEOBJ RETURNVAL WINDOW T)) ) (T (SK.COPY.ELEMENTS RETURNVAL WINDOW] (DELETEMODE (* delete them) (SK.DELETE.ELEMENT RETURNVAL WINDOW] (T (COPYINSERT (SK.BUILD.IMAGEOBJ RETURNVAL WINDOW MIDDLEONLYFLG]) (SK.BUTTONEVENT.MARK [LAMBDA (COPYFLG DELETEFLG) (* rrb "29-Dec-84 19:02") (* returns the mark that should be put on the points when they are selected.) (COND (DELETEFLG (COND (COPYFLG MOVESELECTIONMARK) (T DELETESELECTIONMARK))) (T COPYSELECTIONMARK]) (SK.BUILD.IMAGEOBJ [LAMBDA (SCRELTS SKW CHARSONLYFLG) (* rrb "18-Oct-85 10:13") (* builds an imageobj from the list of screen elements.) (COND [CHARSONLYFLG (* return only the text characters.) (PROG [(TEXTELTS (bind GELT for LOCALSKELT in SCRELTS join (SELECTQ (fetch (GLOBALPART GTYPE) of (SETQ GELT (fetch (SCREENELT GLOBALPART) of LOCALSKELT))) (TEXT (LIST (LIST (fetch (TEXT LOCATIONLATLON) of (SETQ GELT (fetch (GLOBALPART INDIVIDUALGLOBALPART) of GELT))) GELT))) (TEXTBOX (LIST (LIST (SK.TEXTBOX.TEXT.POSITION (SETQ GELT (fetch (GLOBALPART INDIVIDUALGLOBALPART) of GELT))) GELT))) NIL] (* sort according to top from the left.) [SORT TEXTELTS (FUNCTION (LAMBDA (A B) (COND [(GREATERP (fetch (POSITION YCOORD) of (SETQ A (CAR A))) (fetch (POSITION YCOORD) of (SETQ B (CAR B] ((EQUAL (fetch (POSITION YCOORD) of A) (fetch (POSITION YCOORD) of B)) (LESSP (fetch (POSITION XCOORD) of A) (fetch (POSITION XCOORD) of B] (RETURN (BUTLAST (for TEXTELT in TEXTELTS join (SK.ADD.SPACES (fetch (TEXT LISTOFCHARACTERS) of (CADR TEXTELT] (T (* return an image object. The sketch is translated to bring its lower left coordinate to 0,0 so that when it is put in a document it is in a canonical place. Maybe don't need to do this anymore.) (SKETCH.IMAGEOBJ [create SKETCH using (INSURE.SKETCH SKW) SKETCHNAME ← NIL SKETCHELTS ←(bind GELT for LOCALSKELT in SCRELTS collect (COND ((EQ (fetch (GLOBALPART GTYPE) of (SETQ GELT (fetch (SCREENELT GLOBALPART) of LOCALSKELT))) (QUOTE SKIMAGEOBJ)) (* apply copy fn) (SK.COPY.IMAGEOBJ GELT)) (T (COPY GELT] (SK.GLOBAL.REGION.OF.LOCAL.ELEMENTS SCRELTS (WINDOW.SCALE SKW)) (WINDOW.SCALE SKW) (SK.GRIDFACTOR SKW]) (SK.BUTTONEVENT.OVERP [LAMBDA (COPYMODE DELETEMODE) (* rrb " 1-Feb-85 18:39") (* determines if this button event is over by looking at the keys that are held down. COPYMODE and DELETEMODE indicate the keystate at the entry point.) (COND [DELETEMODE (AND (NOT (OR (.DELETEKEYDOWNP.) (.MOVEKEYDOWNP.))) (OR (NULL COPYMODE) (NULL (OR (.COPYKEYDOWNP.) (.MOVEKEYDOWNP.] (COPYMODE (NULL (.COPYKEYDOWNP.]) (SK.BUTTONEVENT.SAME.KEYS [LAMBDA (COPYMODE DELETEMODE) (* rrb " 1-Feb-85 18:39") (* determines if the same keys are held down now as were held down at the start. If not, the event will be stopped. COPYMODE and DELETEMODE indicate the keystate at the entry point.) (COND [DELETEMODE (AND (OR (.DELETEKEYDOWNP.) (.MOVEKEYDOWNP.)) (EQ COPYMODE (OR (.COPYKEYDOWNP.) (.MOVEKEYDOWNP.] (COPYMODE (* if we are not in delete mode, ignore the state of the delete key.) (.COPYKEYDOWNP.]) ) (DECLARE: EVAL@COMPILE [PUTPROPS .DELETEKEYDOWNP. MACRO (NIL (OR (KEYDOWNP (QUOTE CTRL)) (KEYDOWNP (QUOTE DELETE] [PUTPROPS .MOVEKEYDOWNP. MACRO (NIL (KEYDOWNP (QUOTE MOVE] ) (* functions for changing elements.) (DEFINEQ (SK.SEL.AND.CHANGE [LAMBDA (W) (* rrb "10-Dec-85 17:07") (* allows the user to select some elements and changes them.) (SK.CHANGE.THING (SK.SELECT.MULTIPLE.ITEMS W T NIL (QUOTE CHANGE)) W]) (SK.CHANGE.ELT [LAMBDA (W) (* edited: " 1-Feb-84 08:46") (EVAL.AS.PROCESS (LIST (QUOTE SK.SEL.AND.CHANGE) W]) (SK.CHANGE.THING [LAMBDA (ELTSTOCHANGE W) (* rrb " 6-Jan-85 19:23") (* ELTSTOCHANGE is a sketch element that was selected for a CHANGE operation.) (* Change according to the first one on the list) (PROG (FIRSTTYPE READCHANGEFN) (* find the first thing that has a change function.) (OR (for ELT in ELTSTOCHANGE when (AND [SETQ READCHANGEFN (SK.READCHANGEFN (SETQ FIRSTTYPE (fetch (SCREENELT GTYPE) of ELT] (NEQ READCHANGEFN (QUOTE NILL))) do (RETURN T)) (RETURN)) (RETURN (SK.APPLY.CHANGE.COMMAND (SK.CHANGEFN FIRSTTYPE) (APPLY* READCHANGEFN W ELTSTOCHANGE) ELTSTOCHANGE W]) (SK.CHANGEFN [LAMBDA (ELEMENTTYPE) (* rrb "21-Jun-85 17:10") (* returns the changefn for an element. The only one that isnt SK.ELEMENTS.CHANGEFN is image objects.) (OR (fetch (SKETCHTYPE CHANGEFN) of (GETPROP ELEMENTTYPE (QUOTE SKETCHTYPE))) (FUNCTION SK.DEFAULT.CHANGEFN]) (SK.READCHANGEFN [LAMBDA (ELEMENTTYPE) (* rrb " 6-Jan-85 18:29") (* used to be (OR & (FUNCTION SK.DEFAULT.CHANGEFN)) If this really isn't necessary, clean out SK.DEFAULT.CHANGEFN and all the things only it calls. If it is necessary, update it to include a readchangefn.) (fetch (SKETCHTYPE READCHANGEFN) of (GETPROP ELEMENTTYPE (QUOTE SKETCHTYPE]) (SK.DEFAULT.CHANGEFN [LAMBDA (SCRNELT W FIELD) (* rrb "14-May-84 15:57") (PROG ([FIELD (OR FIELD (SK.MENU.AND.RETURN.FIELD (fetch (SCREENELT GTYPE) of SCRNELT] (INDVELT (fetch (SCREENELT INDIVIDUALGLOBALPART) of SCRNELT)) (NOSETVALUE "str") CURRENTVAL NEWPROPVALUE FIELDNAME) (COND ((NULL FIELD) (STATUSPRINT W "That element doesn't have any changeable parts.") (RETURN NIL))) (SETQ CURRENTVAL (RECORDACCESS (SETQ FIELDNAME (COND ((LISTP FIELD) (CAR FIELD)) (T FIELD))) INDVELT (RECLOOK (fetch (SCREENELT GTYPE) of SCRNELT)) (QUOTE FETCH))) [COND ((LISTP FIELD) (* cadr is queryfunction which can do special input and return value checking.) (SETQ NEWPROPVALUE (APPLY* (CADR FIELD) SCRNELT FIELD W NOSETVALUE))) (T (* have NIL returned be no change.) (SETQ NEWPROPVALUE (OR (READ.FUNCTION [CONCAT "Enter new " (MKSTRING FIELD) " value. Current value is " (MKSTRING (RECORDACCESS FIELD INDVELT (RECLOOK (fetch (SCREENELT GTYPE) of SCRNELT)) (QUOTE FETCH] W) NOSETVALUE] (OR (EQ NEWPROPVALUE NOSETVALUE) (RECORDACCESS FIELDNAME INDVELT (RECLOOK (fetch (SCREENELT GTYPE) of SCRNELT)) (QUOTE REPLACE) (EVAL NEWPROPVALUE))) (RETURN (fetch (SCREENELT GLOBALPART) of SCRNELT]) (CHANGEABLEFIELDITEMS [LAMBDA (ELEMENTTYPE) (* rrb "11-May-84 15:49") (* returns the list of fields that element type allows to change. Each field should be of the form (FIELDNAMELABEL (QUOTE (FIELDNAME QUERYFN)) "helpstring") - QUERYFN should be a function of four args: the screen element being changed, the "field" returned from this function, the window the sketch is being displayed in, and a value to be returned if no change should be made.) (GETPROP ELEMENTTYPE (QUOTE CHANGEABLEFIELDITEMS]) (SK.SEL.AND.MAKE [LAMBDA (CHANGECOMMAND W) (* rrb "10-Dec-85 17:08") (* lets the user select elements and applies the given change command to them.) (SK.APPLY.CHANGE.COMMAND (FUNCTION SK.ELEMENTS.CHANGEFN) CHANGECOMMAND (SK.SELECT.MULTIPLE.ITEMS W NIL NIL (QUOTE CHANGE)) W]) (SK.APPLY.CHANGE.COMMAND [LAMBDA (CHANGEFN COMMAND SCRELTS SKW) (* rrb " 6-Jan-85 19:23") (* applies a change command to the relevant elements in SCRELTS.) (AND COMMAND (PROG (NEWGLOBALS CHANGES) (COND ((SETQ NEWGLOBALS (APPLY* CHANGEFN SCRELTS SKW COMMAND)) (SK.UPDATE.ELEMENTS (SETQ CHANGES (for NEWG in NEWGLOBALS as OLDG in SCRELTS when NEWG collect (LIST (fetch (SCREENELT GLOBALPART) of OLDG) NEWG))) SKW) (SK.ADD.HISTEVENT (QUOTE CHANGE) CHANGES SKW) (RETURN NEWGLOBALS]) (SK.ELEMENTS.CHANGEFN [LAMBDA (SCRELTS SKW HOW) (* rrb "20-Nov-85 11:02") (* changefn for many sketch elements.) (PROG (CHANGEASPECTFN (CHANGEHOW (CADR HOW))) (OR (SETQ CHANGEASPECTFN (SELECTQ (CAR HOW) (SIZE (FUNCTION SK.CHANGE.BRUSH.SIZE)) (SHAPE (FUNCTION SK.CHANGE.BRUSH.SHAPE)) (ARROW (FUNCTION SK.CHANGE.ARROWHEAD)) (FILLING (FUNCTION SK.CHANGE.FILLING)) (DASHING (FUNCTION SK.CHANGE.DASHING)) (ANGLE (FUNCTION SK.CHANGE.ANGLE)) (DIRECTION (FUNCTION SK.CHANGE.ARC.DIRECTION)) ((TEXT NEWFONT SETSIZE SAME FAMILY&SIZE) (SETQ CHANGEHOW HOW) (FUNCTION SK.CHANGE.TEXT)) [ADDPOINT (* handle this specially because it only works on the first element.) (RETURN (LIST ( SK.ADD.KNOT.TO.ELEMENT (CAR SCRELTS) CHANGEHOW] (BRUSHCOLOR (FUNCTION SK.CHANGE.BRUSH.COLOR)) (FILLINGCOLOR (FUNCTION SK.CHANGE.FILLING.COLOR) ) NIL)) (RETURN)) (RETURN (bind GELT for SCRELT in SCRELTS collect (SETQ GELT (fetch (SCREENELT GLOBALPART) of SCRELT)) (COND ((EQ (fetch (GLOBALPART GTYPE) of GELT) (QUOTE GROUP)) (* handle a group by propagating it) (SK.GROUP.CHANGEFN GELT CHANGEASPECTFN CHANGEHOW SKW)) (T (APPLY* CHANGEASPECTFN GELT CHANGEHOW SKW]) (READ.POINT.TO.ADD [LAMBDA (SCRELT SKVIEWER) (* rrb " 6-Dec-85 10:15") (* asks where a point should be added and where it should be. Return a list (AfterPt NewPt)) (PROG (AFTERPT NEWPT) (STATUSPRINT SKVIEWER "Select the point that the new point should follow.") (OR (SETQ AFTERPT (SK.SELECT.ITEM SKVIEWER NIL (LIST SCRELT))) (PROGN (CLOSEPROMPTWINDOW SKVIEWER) (RETURN))) (STATUSPRINT SKVIEWER "Indicate where the new point should be.") (SETQ NEWPT (GETSKWPOSITION SKVIEWER POINTREADINGCURSOR)) (CLOSEPROMPTWINDOW SKVIEWER) (AND NEWPT (RETURN (LIST (GLOBAL.KNOT.FROM.LOCAL AFTERPT SCRELT) (SK.MAP.INPUT.PT.TO.GLOBAL NEWPT SKVIEWER]) (GLOBAL.KNOT.FROM.LOCAL [LAMBDA (LOCALKNOT SCRELT) (* rrb "20-Nov-85 11:05") (* returns the global knot that corresponds to a local one.) (for LKNOT in (fetch (SCREENELT HOTSPOTS) of SCRELT) as GKNOT in (GETSKETCHELEMENTPROP (fetch (SCREENELT GLOBALPART) of SCRELT) (QUOTE DATA)) when (EQUAL LKNOT LOCALKNOT) do (RETURN GKNOT]) (SK.ADD.KNOT.TO.ELEMENT [LAMBDA (ELTWITHKNOTS PTS SKW) (* rrb "20-Nov-85 11:06") (* adds a point to a knot element. The point (CADR PTS) is added after (CAR PTS)) (SK.CHANGE.ELEMENT.KNOTS (fetch (SCREENELT GLOBALPART) of ELTWITHKNOTS) (for KNOT in (GETSKETCHELEMENTPROP (fetch (SCREENELT GLOBALPART) of ELTWITHKNOTS) (QUOTE DATA)) join (COND ((EQUAL KNOT (CAR PTS)) (LIST KNOT (CADR PTS))) (T (LIST KNOT]) (SK.GROUP.CHANGEFN [LAMBDA (GROUPELT CHANGEASPECTFN CHANGEHOW SKW) (* rrb "11-Jul-85 15:10") (* maps a change function through all the elements of a group and returns a new element if it takes on any of them.) (PROG ((OLDSUBELTS (fetch (GROUP LISTOFGLOBALELTS) of (fetch (GLOBALPART INDIVIDUALGLOBALPART) of GROUPELT))) NEWSUBELTS NEWELT CHANGEDFLG) [SETQ NEWSUBELTS (for SUBELT in OLDSUBELTS collect (COND ([SETQ NEWELT (COND ((EQ (fetch (GLOBALPART GTYPE) of SUBELT) (QUOTE GROUP)) (* handle a group by propagating it) (SK.GROUP.CHANGEFN SUBELT CHANGEASPECTFN CHANGEHOW SKW)) (T (APPLY* CHANGEASPECTFN SUBELT CHANGEHOW SKW] (SETQ CHANGEDFLG T) NEWELT] (OR CHANGEDFLG (RETURN)) (SETQ NEWELT (for OLDSUBELT in OLDSUBELTS as NEWSUBELT in NEWSUBELTS collect (OR NEWSUBELT OLDSUBELT))) (RETURN (create GLOBALPART COMMONGLOBALPART ←(fetch (GLOBALPART COMMONGLOBALPART) of GROUPELT) INDIVIDUALGLOBALPART ←(create GROUP using (fetch (GLOBALPART INDIVIDUALGLOBALPART) of GROUPELT) LISTOFGLOBALELTS ← NEWELT]) ) (* fns for adding elements) (* fns for adding elements) (DEFINEQ (ADD.ELEMENT.TO.SKETCH [LAMBDA (GELT SKETCH) (* rrb "12-May-85 18:17") (* changes the global sketch) (PROG ((REALSKETCH (INSURE.SKETCH SKETCH))) (TCONC (fetch (SKETCH SKETCHTCELL) of REALSKETCH) GELT) (SK.MARK.DIRTY REALSKETCH]) (ADD.SKETCH.VIEWER [LAMBDA (SKETCH VIEWER) (* rrb " 8-APR-83 17:56") (* adds VIEWER as a viewer of SKETCH.) (PROG (VIEWERS) (COND ((SETQ VIEWERS (ALL.SKETCH.VIEWERS SKETCH)) (* already has at least one viewer) (OR (FMEMB VIEWER VIEWERS) (NCONC1 VIEWERS VIEWER))) (T (* doesn't have any viewers yet.) (SETQ ALL.SKETCHES (CONS (LIST SKETCH VIEWER) ALL.SKETCHES]) (REMOVE.SKETCH.VIEWER [LAMBDA (SKETCH VIEWER) (* rrb "26-Apr-85 16:56") (* removes VIEWER as a viewer of SKETCH.) (PROG (VIEWERS) (COND ((SETQ VIEWERS (VIEWER.BUCKET SKETCH)) (* remove it from the list.) (COND ((NULL (CDR (DREMOVE VIEWER VIEWERS))) (* deleted the last viewer.) (SETQ ALL.SKETCHES (REMOVE VIEWERS ALL.SKETCHES]) (ALL.SKETCH.VIEWERS [LAMBDA (SKETCH) (* rrb " 8-APR-83 14:20") (* returns the list of all active viewers of a sketch) (CDR (VIEWER.BUCKET SKETCH]) (VIEWER.BUCKET [LAMBDA (SKETCH) (* rrb " 8-APR-83 14:20") (FASSOC SKETCH ALL.SKETCHES]) (ELT.INSIDE.REGION? [LAMBDA (GLOBALPART WORLDREG) (* rrb " 4-AUG-83 14:51") (* determines if any part of an element is inside the region WORLDREG) (APPLY* (SK.INSIDEFN (fetch (GLOBALPART GTYPE) of GLOBALPART)) GLOBALPART WORLDREG]) (ELT.INSIDE.SKWP [LAMBDA (GLOBALPART SKETCHW) (* rrb "25-Nov-85 17:46") (* determines if a global element is in the world region of a map window.) (ELT.INSIDE.REGION? GLOBALPART (SKETCH.REGION.VIEWED SKETCHW]) (SCALE.FROM.SKW [LAMBDA (WINDOW) (* rrb "11-MAR-83 11:52") (* gets the scale of a sketch window.) (WINDOWPROP WINDOW (QUOTE SCALE]) (SK.ADDELT.TO.WINDOW [LAMBDA (PELT SKETCHW) (* rrb "12-May-85 16:47") (* adds a picture element to a sketch window. Returns the element that was added.) (COND (PELT (TCONC (WINDOWPROP SKETCHW (QUOTE SKETCHSPECS)) PELT) [PROG ((CACHE (SK.HOTSPOT.CACHE SKETCHW))) (COND (CACHE (* if there is a cache, adding an element will change it) (SK.ADD.HOTSPOTS.TO.CACHE1 PELT CACHE)) (T (* if this is the first, must set the window property too.) (SK.SET.HOTSPOT.CACHE SKETCHW (SK.ADD.HOTSPOTS.TO.CACHE1 PELT CACHE] PELT]) (SK.CALC.REGION.VIEWED [LAMBDA (WINDOW SCALE) (* rrb "29-APR-83 08:37") (* returns the region of the sketch visible in window.) (UNSCALE.REGION (DSPCLIPPINGREGION NIL WINDOW) SCALE]) (SK.DRAWFIGURE [LAMBDA (SCREENELT STREAM REGION SCALE) (* rrb "30-Aug-84 14:31") (* draws an element of a sketch in a window. Makes sure the scale of the current drawing is with in the limits of the element. Returns SCREENELT) (PROG (GLOBALPART) [COND ([AND (NUMBERP SCALE) (OR [LESSP SCALE (fetch (COMMONGLOBALPART MINSCALE) of (SETQ GLOBALPART (fetch (SCREENELT COMMONGLOBALPART) of SCREENELT] (GREATERP SCALE (fetch (COMMONGLOBALPART MAXSCALE) of GLOBALPART] (* scale is out of bounds, don't draw it.) NIL) (T (SK.DRAWFIGURE1 SCREENELT STREAM (OR REGION (DSPCLIPPINGREGION NIL STREAM] (RETURN SCREENELT]) (SK.DRAWFIGURE1 [LAMBDA (ELT SKW REGION) (* rrb "14-Sep-84 16:59") (* displays a sketch element in a window) (APPLY* (SK.DRAWFN (fetch (SCREENELT GTYPE) of ELT)) ELT SKW REGION]) (SK.LOCAL.FROM.GLOBAL [LAMBDA (GELT SKSTREAM SCALE) (* rrb "26-Nov-85 15:50") (* returns the element instance of the global element GELT expanded into the window SKW.) (* SKSTREAM can be deleted from call once TEXT.EXPANDFN no longer needs to distinquish INTERPRESS stream from windows.) (PROG ((SCRELT (APPLY* (SK.EXPANDFN (fetch (GLOBALPART GTYPE) of GELT)) GELT (OR (NUMBERP SCALE) (SKETCHW.SCALE SKSTREAM)) SKSTREAM)) ACTIVEREGION) (* do the ACTIVEREGION which is common to all elements.) [AND SCRELT (SETQ ACTIVEREGION (GETSKETCHELEMENTPROP GELT (QUOTE ACTIVEREGION))) (replace (LOCALPART LOCALHOTREGION) of (fetch (SCREENELT LOCALPART) of SCRELT) with (SCALE.REGION ACTIVEREGION (OR (NUMBERP SCALE) (SKETCHW.SCALE SKSTREAM] (RETURN SCRELT]) (SKETCH.REGION.VIEWED [LAMBDA (SKETCHW NEWREGION) (* rrb "25-Nov-85 17:57") (* returns the region in sketch coordinates of the area visible in SKETCHW.) (PROG1 (WINDOWPROP SKETCHW (QUOTE REGION.VIEWED)) (COND (NEWREGION (PROG (NEWVIEW) (RETURN (COND ((REGIONP NEWREGION) (SKETCH.GLOBAL.REGION.ZOOM SKETCHW NEWREGION)) ((EQ NEWREGION (QUOTE HOME)) (SKETCH.HOME SKETCHW)) ((SETQ NEWVIEW (SKETCH.VIEW.FROM.NAME NEWREGION SKETCHW)) (SK.MOVE.TO.VIEW SKETCHW NEWVIEW)) (T (\ILLEGAL.ARG NEWREGION]) (SKETCH.VIEW.FROM.NAME [LAMBDA (VIEWNAME SKETCHW) (* rrb "25-Nov-85 17:55") (* returns the view structure for a view given its name.) (for SAVEDVIEW in (GETSKETCHPROP (INSURE.SKETCH SKETCHW) (QUOTE VIEWS)) when (EQUAL VIEWNAME (fetch (SKETCHVIEW VIEWNAME) of SAVEDVIEW)) do (RETURN SAVEDVIEW]) (SK.UPDATE.REGION.VIEWED [LAMBDA (SKW) (* rrb " 6-NOV-83 11:46") (* updates the REGION.VIEWED property of a window.) (WINDOWPROP SKW (QUOTE REGION.VIEWED) (SK.CALC.REGION.VIEWED SKW (WINDOW.SCALE SKW]) (SKETCH.ADD.AND.DISPLAY [LAMBDA (GELT SKETCHW DONTCLEARCURSOR) (* rrb "14-Nov-84 17:12") (* adds a new element to a sketch window and handles propagation to all other figure windows) (COND (GELT (SK.ADD.HISTEVENT (QUOTE ADD) (LIST GELT) SKETCHW) (SK.ADD.ELEMENT GELT SKETCHW DONTCLEARCURSOR]) (SKETCH.ADD.AND.DISPLAY1 [LAMBDA (GELT SKETCHW SCALE NODISPLAYFLG) (* rrb "30-Jul-85 15:39") (* displays a sketch element and adds it to the window.) (COND (GELT (COND (NODISPLAYFLG (SK.ADD.ITEM GELT SKETCHW)) (T (SK.DRAWFIGURE (SK.ADD.ITEM GELT SKETCHW) SKETCHW NIL (OR SCALE (WINDOW.SCALE SKETCHW]) (SK.ADD.ITEM [LAMBDA (GELT SKETCHW) (* rrb "10-APR-83 13:38") (* adds a global element to a window. Returns the local element that was actually added.) (SK.ADDELT.TO.WINDOW (SK.LOCAL.FROM.GLOBAL GELT SKETCHW) SKETCHW]) (SKETCHW.ADD.INSTANCE [LAMBDA (TYPE SKW) (* rrb "14-Nov-84 17:08") (* reads an instance of type TYPE from the user and displays it in SKW.) (PROG ((ELT (SK.INPUT TYPE SKW))) (AND ELT (SKETCH.ADD.AND.DISPLAY ELT SKW)) (RETURN ELT]) ) (* put in for backward compatibility. Can be pulled out 6/1/86 rrb.) (MOVD? (QUOTE SKETCH.REGION.VIEWED) (QUOTE SK.REGION.VIEWED)) (* fns for deleting things) (DEFINEQ (SK.SEL.AND.DELETE [LAMBDA (W) (* rrb "10-Dec-85 17:08") (* lets the user select elements and deletes them) (SK.DELETE.ELEMENT (SK.SELECT.MULTIPLE.ITEMS W T NIL (QUOTE DELETE)) W]) (SK.ERASE.AND.DELETE.ITEM [LAMBDA (SELELT SKW NODISPLAYFLG) (* rrb "30-Jul-85 15:36") (* removes a sketch element from a viewer.) (COND (SELELT (OR NODISPLAYFLG (SK.ERASE.ELT SELELT SKW)) (SK.DELETE.ITEM SELELT SKW]) (REMOVE.ELEMENT.FROM.SKETCH [LAMBDA (GELT SKETCH INSIDEGROUPFLG) (* rrb "14-Aug-85 16:20") (* changes the global sketch Returns the element or the group element containing the element if the element was found in the sketch. If INSIDEGROUPFLG is T, it will go inside of groups.) (PROG ((SKETCHDATA (INSURE.SKETCH SKETCH))) (COND ((MEMB GELT (fetch (SKETCH SKETCHELTS) of SKETCHDATA)) (DELFROMTCONC (fetch (SKETCH SKETCHTCELL) of SKETCHDATA) GELT) (SK.MARK.DIRTY SKETCH) (RETURN T)) [INSIDEGROUPFLG (RETURN (for ELT on (fetch (SKETCH SKETCHELTS) of SKETCHDATA) do (* look inside groups) (COND ((DELFROMGROUPELT GELT ELT) (SK.MARK.DIRTY SKETCH) (RETURN ELT] (T (RETURN NIL]) (SK.DELETE.ELEMENT [LAMBDA (ELTSTODEL SKETCHW ELTSFORHISTORY) (* rrb " 9-Dec-85 11:47") (* deletes a list of element to a sketch window and handles propagation to all other figure windows) (PROG (OLDGELTS) (OR ELTSTODEL (RETURN)) (SETQ ELTSTODEL (SK.CHECK.WHENDELETEDFN SKETCHW ELTSTODEL)) (* ELTSTODEL is a list of screen elements to delete.) (OR ELTSTODEL (RETURN)) (SKED.CLEAR.SELECTION SKETCHW) (SETQ OLDGELTS (for SCRELT in ELTSTODEL collect (fetch (SCREENELT GLOBALPART) of SCRELT))) (OR (EQ ELTSFORHISTORY (QUOTE DON'T)) (SK.ADD.HISTEVENT (QUOTE DELETE) (OR ELTSFORHISTORY OLDGELTS) SKETCHW)) (for GELT in OLDGELTS do (SK.DELETE.ELEMENT1 GELT SKETCHW)) (RETURN OLDGELTS]) (SK.DELETE.KNOT [LAMBDA (W) (* rrb "20-Nov-85 09:52") (* lets the user select a knot in a curve or wire and deletes it.) (EVAL.AS.PROCESS (LIST (QUOTE SK.SEL.AND.DELETE.KNOT) W]) (SK.SEL.AND.DELETE.KNOT [LAMBDA (W) (* rrb "10-Dec-85 17:03") (* lets the user select a knot and deletes it.) (PROG [(KNOTELTS (SUBSET (LOCALSPECS.FROM.VIEWER W) (FUNCTION (LAMBDA (SCRELT) (AND (MEMB (fetch (SCREENELT GTYPE) of SCRELT) (QUOTE (WIRE CLOSEDWIRE OPENCURVE CLOSEDCURVE))) (NOT (SK.ELEMENT.PROTECTED? (fetch (SCREENELT GTYPE) of SCRELT) (QUOTE CHANGE] (COND ((NULL KNOTELTS) (STATUSPRINT W "There are no curve or wire elements to delete points from.") (RETURN))) (SK.DELETE.ELEMENT.KNOT (SK.SELECT.ITEM W NIL KNOTELTS) KNOTELTS W]) (SK.DELETE.ELEMENT.KNOT [LAMBDA (LOCALKNOT SCRELTS SKW) (* rrb "20-Nov-85 11:02") (* deletes a knot from a curve or wire element.) (SKED.CLEAR.SELECTION SKW) (COND ((NULL LOCALKNOT)) ([OR (POSITIONP LOCALKNOT) (AND (NULL (CDR LOCALKNOT)) (POSITIONP (CAR LOCALKNOT)) (SETQ LOCALKNOT (CAR LOCALKNOT] (PROG ((SCREENELT (for SKELT in SCRELTS when (MEMBER LOCALKNOT (fetch (SCREENELT HOTSPOTS) of SKELT)) do (RETURN SKELT))) LOCALKNOTS GLOBALKNOT GLOBALKNOTS NEWKNOTS NEWELT CHANGES) (COND ((NULL SCREENELT) (RETURN NIL))) (SETQ GLOBALKNOT (for LKNOT in (SETQ LOCALKNOTS (fetch (SCREENELT HOTSPOTS) of SCREENELT)) as GKNOT in (SETQ GLOBALKNOTS (GETSKETCHELEMENTPROP (fetch (SCREENELT GLOBALPART) of SCREENELT) (QUOTE DATA))) when (EQUAL LKNOT LOCALKNOT) do (RETURN GKNOT))) (OR (SK.CHECK.WHENPOINTDELETEDFN SKW SCREENELT GLOBALKNOT) (RETURN)) (RETURN (COND [(SETQ NEWKNOTS (REMOVE GLOBALKNOT GLOBALKNOTS)) (* change the knots and update the element) (COND ((SETQ NEWELT (SK.CHANGE.ELEMENT.KNOTS (fetch (SCREENELT GLOBALPART) of SCREENELT) NEWKNOTS)) (* make history entry and update screen) (SK.UPDATE.ELEMENTS (SETQ CHANGES (CONS (LIST (fetch (SCREENELT GLOBALPART) of SCREENELT) NEWELT))) SKW) (SK.ADD.HISTEVENT (QUOTE CHANGE) CHANGES SKW] (T (* delete the whole element.) (SK.DELETE.ELEMENT (CONS SCREENELT) SKW]) (SK.CHECK.WHENDELETEDFN [LAMBDA (VIEWER SCRELTS) (* rrb "26-Nov-85 15:50") (* checks if the sketch has a when deleted fn and if so, creates the list of global elements and interprets the result. Returns a list of the elements that should be deleted.) (PROG ((SKETCH (INSURE.SKETCH VIEWER)) RESULT DELETEFN GELTS) (COND ([NULL (SETQ DELETEFN (GETSKETCHPROP SKETCH (QUOTE WHENDELETEDFN] (RETURN SCRELTS))) [SETQ RESULT (APPLY* DELETEFN VIEWER (SETQ GELTS (for ELT in SCRELTS collect (fetch (SCREENELT GLOBALPART) of ELT] (COND ((EQ RESULT (QUOTE DON'T)) (RETURN NIL)) ((LISTP RESULT) (RETURN (for SCRELT in SCRELTS as GELT in GELTS when (MEMB GELT RESULT) collect SCRELT))) (T (RETURN SCRELTS]) (SK.CHECK.PREEDITFN [LAMBDA (VIEWER OLDELT) (* rrb " 9-Dec-85 11:52") (* checks if the sketch has a preedit fn and if so, calls it) (PROG ((SKETCH (INSURE.SKETCH VIEWER)) PREEDITFN) (COND ([NULL (SETQ PREEDITFN (GETSKETCHPROP SKETCH (QUOTE PREEDITFN] (RETURN T))) (RETURN (NEQ (APPLY* PREEDITFN VIEWER OLDELT) (QUOTE DON'T]) (SK.CHECK.WHENEDITEDFN [LAMBDA (VIEWER OLDELT NEWELT) (* rrb " 9-Dec-85 16:10") (* checks if the sketch has a preedit fn and if so, calls it) (PROG ((SKETCH (INSURE.SKETCH VIEWER)) PREEDITFN) (COND ([NULL (SETQ PREEDITFN (GETSKETCHPROP SKETCH (QUOTE PREEDITFN] (RETURN T))) (RETURN (NEQ (APPLY* PREEDITFN VIEWER OLDELT) (QUOTE DON'T]) (SK.CHECK.WHENPOINTDELETEDFN [LAMBDA (VIEWER SCRELT CONTROLPOINT) (* rrb " 6-Dec-85 10:15") (* checks if the sketch has a when point deleted fn and if so, calls it and interprets the result. Returns NIL if the point should not be deleted.) (PROG ((SKETCH (INSURE.SKETCH VIEWER)) RESULT DELETEFN) (COND ([NULL (SETQ DELETEFN (GETSKETCHPROP SKETCH (QUOTE WHENPOINTDELETEDFN] (RETURN SCRELT))) (SETQ RESULT (APPLY* DELETEFN VIEWER (fetch (SCREENELT GLOBALPART) of SCRELT) CONTROLPOINT)) (COND ((EQ RESULT (QUOTE DON'T)) (RETURN NIL)) (T (RETURN SCRELT]) (SK.ERASE.ELT [LAMBDA (ELT WINDOW REGION) (* rrb "28-Jun-84 08:21") (* erases a sketch element) (DSPOPERATION (QUOTE ERASE) WINDOW) (SK.DRAWFIGURE ELT WINDOW REGION (SCALE.FROM.SKW WINDOW)) (DSPOPERATION (QUOTE PAINT) WINDOW]) (SK.DELETE.ELT [LAMBDA (W) (* rrb "18-MAR-83 13:16") (* lets the user select an element and deletes it.) (EVAL.AS.PROCESS (LIST (QUOTE SK.SEL.AND.DELETE) W]) (SK.DELETE.ITEM [LAMBDA (ELT SKETCHW) (* rrb "12-May-85 18:10") (* deletes an element from a window) (COND (ELT (DELFROMTCONC (WINDOWPROP SKETCHW (QUOTE SKETCHSPECS)) ELT) (SK.REMOVE.HOTSPOTS.FROM.CACHE1 ELT (SK.HOTSPOT.CACHE SKETCHW)) ELT]) (DELFROMTCONC [LAMBDA (TCONCCELL ELEMENT) (* rrb "31-May-85 10:12") (* deletes an element from a TCONC cell list.) [COND [(EQUAL ELEMENT (CAAR TCONCCELL)) (* first element) (COND ((EQLENGTH (CAR TCONCCELL) 1) (* only one element) (RPLACA TCONCCELL NIL) (RPLACD TCONCCELL NIL)) (T (* remove first element.) (RPLACA TCONCCELL (CDAR TCONCCELL] ((EQUAL ELEMENT (CADR TCONCCELL)) (* elt to delete is the last one on the list, do special case.) (for TAIL on (CAR TCONCCELL) when (EQ (CDR TAIL) (CDR TCONCCELL)) do (* update the TCONC last entry) (RPLACD TCONCCELL TAIL) (* remove the last element) (RPLACD TAIL NIL) (RETURN))) (T (for TAIL on (CAR TCONCCELL) when (EQ ELEMENT (CADR TAIL)) do (RPLACD TAIL (CDDR TAIL)) (RETURN] TCONCCELL]) ) (* fns for copying stuff) (DEFINEQ (SK.COPY.ELT [LAMBDA (W) (* rrb "12-Sep-84 13:23") (* lets the user select an element and copies it.) (EVAL.AS.PROCESS (LIST (QUOTE SK.SEL.AND.COPY) W]) (SK.SEL.AND.COPY [LAMBDA (W) (* rrb "10-Dec-85 17:08") (* lets the user select elements and copies them.) (SK.COPY.ELEMENTS (SK.SELECT.MULTIPLE.ITEMS W T NIL (QUOTE COPY)) W]) (SK.COPY.ELEMENTS [LAMBDA (SCRELTS SKW) (* rrb " 6-Nov-85 11:34") (* create a bitmap of the thing being moved and get its new position. Then translate all the pieces.) (AND SCRELTS (PROG (FIGINFO FIRSTHOTSPOT LOWLFT NEWPOS DELTAPOS NEWELTS COPYFN X SKETCH COPYARGS) (* call PRECOPYFN.) [AND (SETQ COPYFN (GETSKETCHPROP (SETQ SKETCH (INSURE.SKETCH SKW)) (QUOTE PRECOPYFN))) (SETQ NEWPOS (APPLY* COPYFN SKW (SETQ COPYARGS ( SK.GLOBAL.FROM.LOCAL.ELEMENTS SCRELTS] [COND ((EQ DELTAPOS (QUOTE DON'T)) (RETURN)) ((POSITIONP DELTAPOS) (* value returned is the delta by which to move the point. Set up new position) NIL) (T (* read new position from the user) (SETQ FIGINFO (SK.FIGUREIMAGE SCRELTS (DSPCLIPPINGREGION NIL SKW))) (SETQ LOWLFT (fetch (SKFIGUREIMAGE SKFIGURE.LOWERLEFT) of FIGINFO)) [SETQ FIRSTHOTSPOT (CAR (fetch (SCREENELT HOTSPOTS) of (CAR SCRELTS] (* move the image by the first hotspot of the first element chosen. This will align the image on the grid correctly.) (COND ((SETQ NEWPOS (SK.MAP.INPUT.PT.TO.GLOBAL [GET.BITMAP.POSITION SKW (fetch (SKFIGUREIMAGE SKFIGURE.BITMAP) of FIGINFO) (QUOTE PAINT) "move the figure into place and press the left button." (FIXR (DIFFERENCE (fetch (POSITION XCOORD) of LOWLFT) (fetch (POSITION XCOORD) of FIRSTHOTSPOT))) (FIXR (DIFFERENCE (fetch (POSITION YCOORD) of LOWLFT) (fetch (POSITION YCOORD) of FIRSTHOTSPOT] SKW)) (CLRPROMPT)) (T (STATUSPRINT SKW "Position was outside the window. Copy not placed.") (RETURN NIL))) (SETQ DELTAPOS (SK.MAP.FROM.WINDOW.TO.NEAREST.GRID (create POSITION XCOORD ←(DIFFERENCE (fetch (POSITION XCOORD) of NEWPOS) (fetch (POSITION XCOORD) of FIRSTHOTSPOT)) YCOORD ←(DIFFERENCE (fetch (POSITION YCOORD) of NEWPOS) (fetch (POSITION YCOORD) of FIRSTHOTSPOT))) (WINDOW.SCALE SKW] (AND (SETQ COPYFN (GETSKETCHPROP (SETQ SKETCH (INSURE.SKETCH SKW)) (QUOTE WHENCOPIEDFN))) (SETQ X (APPLY* COPYFN SKW (OR COPYARGS ( SK.GLOBAL.FROM.LOCAL.ELEMENTS SCRELTS)) DELTAPOS))) (COND ((EQ X (QUOTE DON'T)) (RETURN)) ((POSITIONP X) (* value returned is the position to put the copy. Set up new position) (SETQ DELTAPOS X))) [SETQ NEWELTS (COND ((AND X (EVERY X (FUNCTION GLOBALELEMENTP))) (* value returns was a list of new global elements.) X) (T (MAPCOLLECTSKETCHSPECS SCRELTS (FUNCTION SK.COPY.ITEM) DELTAPOS SKW] (* add new elements to history list.) (SK.ADD.ELEMENTS NEWELTS SKW) (SK.ADD.HISTEVENT (QUOTE COPY) NEWELTS SKW]) (SK.GLOBAL.FROM.LOCAL.ELEMENTS [LAMBDA (SCRELTS) (* returns the global elements from a list of screen elements) (FOR SCRELT IN SCRELTS COLLECT (FETCH (SCREENELT GLOBALPART) OF SCRELT]) (SK.COPY.ITEM [LAMBDA (SELELT GLOBALDELTAPOS W) (* rrb " 6-Nov-85 11:05") (* SELELT is a sketch element that was selected for a copy operation. GLOBALDELTAPOS is the amount the new item is to be offset from the old.) (PROG ((OLDGLOBAL (fetch (SCREENELT GLOBALPART) of SELELT))) [COND ((EQ (fetch (GLOBALPART GTYPE) of OLDGLOBAL) (QUOTE SKIMAGEOBJ)) (* copying an image obj. Calls its when copied fn.) (SETQ OLDGLOBAL (SK.COPY.IMAGEOBJ OLDGLOBAL W T] (RETURN (SK.TRANSLATE.GLOBALPART OLDGLOBAL GLOBALDELTAPOS]) (SK.INSERT.SKETCH [LAMBDA (W SKETCH REGION SCALE) (* rrb " 6-Nov-85 11:04") (* * inserts the sketch SKETCH into the sketch window W. Called by the copy insert function for sketch windows.) (AND SKETCH (PROG (LOCALSCRELTS FIGINFO FIRSTHOTSPOT LOWLFT NEWPOS WINDOWSCALE NEWELTS) (* map inserted elements into new coordinate space.) [COND ([NOT (EQUAL SCALE (SETQ WINDOWSCALE (WINDOW.SCALE W] (* change the scale of the sketch and the region.) [SETQ SKETCH (create SKETCH using SKETCH SKETCHELTS ←( SK.TRANSFORM.GLOBAL.ELEMENTS (fetch (SKETCH SKETCHELTS) of SKETCH) (FUNCTION SCALE.POSITION) (QUOTIENT SCALE WINDOWSCALE] (SETQ REGION (SCALE.REGION REGION (QUOTIENT SCALE WINDOWSCALE] (OR (SETQ LOCALSCRELTS (MAKE.LOCAL.SKETCH SKETCH REGION WINDOWSCALE W T)) (RETURN)) (SETQ FIGINFO (SK.FIGUREIMAGE LOCALSCRELTS REGION)) [SETQ FIRSTHOTSPOT (CAR (fetch (SCREENELT HOTSPOTS) of (CAR LOCALSCRELTS] (SETQ LOWLFT (fetch (SKFIGUREIMAGE SKFIGURE.LOWERLEFT) of FIGINFO)) (* move the image by the first hotspot of the first element chosen. This will align the image on the grid correctly.) (COND ([SETQ NEWPOS (fetch (INPUTPT INPUT.POSITION) of (GET.BITMAP.POSITION W (fetch (SKFIGUREIMAGE SKFIGURE.BITMAP) of FIGINFO) (QUOTE PAINT) "move the figure into place and press the left button." (IDIFFERENCE (fetch (POSITION XCOORD) of LOWLFT) (fetch (POSITION XCOORD) of FIRSTHOTSPOT)) (IDIFFERENCE (fetch (POSITION YCOORD) of LOWLFT) (fetch (POSITION YCOORD) of FIRSTHOTSPOT] (CLRPROMPT)) (T (STATUSPRINT W " " "Position was outside the window. Copy not placed.") (RETURN NIL))) (SETQ NEWELTS (MAPCOLLECTSKETCHSPECS LOCALSCRELTS (FUNCTION SK.COPY.ITEM) (SK.MAP.FROM.WINDOW.TO.NEAREST.GRID (create POSITION XCOORD ←(IDIFFERENCE (fetch (POSITION XCOORD) of NEWPOS) (fetch (POSITION XCOORD) of FIRSTHOTSPOT)) YCOORD ←(IDIFFERENCE (fetch (POSITION YCOORD) of NEWPOS) (fetch (POSITION YCOORD) of FIRSTHOTSPOT))) WINDOWSCALE) W)) (SK.ADD.ELEMENTS NEWELTS W) (SK.ADD.HISTEVENT (QUOTE COPY) NEWELTS W]) ) (* fns for moving things.) (DEFINEQ (SK.MOVE.ELT [LAMBDA (W) (* rrb "20-Feb-85 20:17") (* lets the user select one or more elements and move them.) (EVAL.AS.PROCESS (LIST (QUOTE SK.SEL.AND.MOVE) W]) (SK.MOVE.ELT.OR.PT [LAMBDA (W) (* rrb "20-Feb-85 20:27") (* lets the user select one or more elements and move them.) (EVAL.AS.PROCESS (LIST (QUOTE SK.SEL.AND.MOVE) W T]) (SK.APPLY.DEFAULT.MOVE [LAMBDA (W) (* rrb " 2-Jun-85 12:52") (* applies the default move mode which can be either points, elements or both.) (SELECTQ (fetch (SKETCHCONTEXT SKETCHMOVEMODE) of (WINDOWPROP W (QUOTE SKETCHCONTEXT))) (POINTS (SK.MOVE.POINTS W)) (ELEMENTS (SK.MOVE.ELT W)) (SK.MOVE.ELT.OR.PT W]) (SK.SEL.AND.MOVE [LAMBDA (W PTFLG) (* rrb "10-Dec-85 17:06") (* lets the user select either a control point or one or more elements and move them.) (SK.MOVE.ELEMENTS [COND ((EQ PTFLG (QUOTE ONLY)) (SK.SELECT.ITEM W NIL NIL (QUOTE MOVE))) (T (SK.SELECT.MULTIPLE.ITEMS W (NULL PTFLG) NIL (QUOTE MOVE] W]) (SK.MOVE.ELEMENTS [LAMBDA (SCRELTS SKW) (* rrb "11-Dec-85 11:51") (SKED.CLEAR.SELECTION SKW) (COND ((NULL SCRELTS)) [[OR (POSITIONP SCRELTS) (AND (NULL (CDR SCRELTS)) (POSITIONP (CAR SCRELTS)) (SETQ SCRELTS (CAR SCRELTS] (* user selected a point, move just that point.) (PROG ((SKETCHELTS (SK.ELTS.FROM.HOTSPOT SCRELTS (SK.HOTSPOT.CACHE SKW))) SKETCHELT OTHERHOTSPOTS NEWPOS MOVEFN GDELTAPOS X MOVEARGS SKETCH) (COND ((NULL SKETCHELTS) (RETURN NIL)) ([NULL (SETQ SKETCHELT (for SCRELT in SKETCHELTS when (NOT (SK.ELEMENT.PROTECTED? (fetch (SCREENELT GLOBALPART) of SCRELT) (QUOTE MOVE))) do (RETURN SCRELT] (* only protected elements at this point, shouldn't happen but don't cause an error.) (RETURN NIL))) [COND ([NULL (SETQ OTHERHOTSPOTS (REMOVE SCRELTS (fetch (SCREENELT HOTSPOTS) of SKETCHELT] (* only one control point, move it with the move element function.) (RETURN (SK.MOVE.ELEMENTS (LIST SKETCHELT) SKW] (* call sketch premovefn if given.) [AND (SETQ MOVEFN (GETSKETCHPROP (SETQ SKETCH (INSURE.SKETCH SKW)) (QUOTE PREMOVEFN))) (SETQ GDELTAPOS (APPLY* MOVEFN SKW (SETQ MOVEARGS ( SK.MAKE.ELEMENT.MOVE.ARG SKETCHELT SCRELTS] [COND ((EQ GDELTAPOS (QUOTE DON'T)) (RETURN)) ((POSITIONP GDELTAPOS) (* value returned is the delta by which to move the point. Set up new position) NIL) (T (* read new position from the user) (for PT in OTHERHOTSPOTS do (MARKPOINT PT SKW OTHERCONTROLPOINTMARK)) (CURSORPOSITION SCRELTS SKW) (SETQ NEWPOS (GETSKWPOSITION SKW)) (for PT in OTHERHOTSPOTS do (MARKPOINT PT SKW OTHERCONTROLPOINTMARK)) (* if user selected outside, don't move anything.) (OR NEWPOS (RETURN NIL)) (* calculate the delta that the selected point moves.) (SETQ GDELTAPOS (SK.MAP.FROM.WINDOW.TO.NEAREST.GRID (create POSITION XCOORD ←(IDIFFERENCE (fetch (POSITION XCOORD) of (fetch (INPUTPT INPUT.POSITION) of NEWPOS)) (fetch (POSITION XCOORD) of SCRELTS)) YCOORD ←(IDIFFERENCE (fetch (POSITION YCOORD) of (fetch (INPUTPT INPUT.POSITION) of NEWPOS)) (fetch (POSITION YCOORD) of SCRELTS))) (WINDOW.SCALE SKW] (AND (SETQ MOVEFN (GETSKETCHPROP SKETCH (QUOTE MOVEFN))) (SETQ X (APPLY* MOVEFN SKW (OR MOVEARGS (SK.MAKE.ELEMENT.MOVE.ARG SKETCHELT SCRELTS)) GDELTAPOS))) (COND ((EQ X (QUOTE DON'T)) (RETURN)) ((POSITIONP X) (* value returned is the delta by which to move the point. Set up new position) (SETQ GDELTAPOS X))) (RETURN (SK.MOVE.THING SKETCHELT SCRELTS GDELTAPOS SKW] (T (* create a bitmap of the thing being moved and get its new position. Then translate all the pieces.) (PROG (FIGINFO FIRSTHOTSPOT NEWPOS LOWLFT IMAGEPOSX IMAGEPOSY IMAGEBM DELTAPOS CHANGES MOVEFN X GDELTAPOS) [AND (SETQ MOVEFN (GETSKETCHPROP (INSURE.SKETCH SKW) (QUOTE PREMOVEFN))) (SETQ GDELTAPOS (APPLY* MOVEFN SKW (SK.MAKE.ELEMENTS.MOVE.ARG SCRELTS] [COND ((EQ GDELTAPOS (QUOTE DON'T)) (RETURN)) ((POSITIONP GDELTAPOS) (* value returned is the delta by which to move the point. Set up new position) NIL) (T (* read new position from the user) (SETQ FIGINFO (SK.FIGUREIMAGE SCRELTS (DSPCLIPPINGREGION NIL SKW))) [SETQ FIRSTHOTSPOT (CAR (fetch (SCREENELT HOTSPOTS) of (CAR SCRELTS] (SETQ IMAGEBM (fetch (SKFIGUREIMAGE SKFIGURE.BITMAP) of FIGINFO)) (SETQ LOWLFT (fetch (SKFIGUREIMAGE SKFIGURE.LOWERLEFT) of FIGINFO)) (* move the image by the first hotspot of the first element chosen. This will align the image on the grid correctly.) (SETQ IMAGEPOSX (fetch (POSITION XCOORD) of LOWLFT)) (SETQ IMAGEPOSY (fetch (POSITION YCOORD) of LOWLFT)) (* put the cursor on the hot spot) (CURSORPOSITION FIRSTHOTSPOT SKW) (COND ([NULL (ERSETQ (PROGN (SK.SHOW.FIG.FROM.INFO IMAGEBM IMAGEPOSX IMAGEPOSY (QUOTE ERASE) SKW) (SETQ NEWPOS (fetch (INPUTPT INPUT.POSITION) of (GET.BITMAP.POSITION SKW IMAGEBM (QUOTE PAINT) "Move image to its new position." (IDIFFERENCE IMAGEPOSX (fetch (POSITION XCOORD) of FIRSTHOTSPOT)) (IDIFFERENCE IMAGEPOSY (fetch (POSITION YCOORD) of FIRSTHOTSPOT] (* error happened, repaint the image.) (SK.SHOW.FIG.FROM.INFO IMAGEBM IMAGEPOSX IMAGEPOSY (QUOTE PAINT) SKW) (CLOSEPROMPTWINDOW SKW) (ERROR!)) ((NULL NEWPOS) (SK.SHOW.FIG.FROM.INFO IMAGEBM IMAGEPOSX IMAGEPOSY (QUOTE PAINT) SKW) (STATUSPRINT SKW "Position was outside the window, copy not placed.") (RETURN NIL))) (* GET.BITMAP.POSITION returns the position that the cursor was in which is the position of the first hotspot.) (* calculate the delta that the selected point moves.) (SETQ GDELTAPOS (SK.MAP.FROM.WINDOW.TO.NEAREST.GRID [SETQ DELTAPOS (create POSITION XCOORD ←(IDIFFERENCE (fetch (POSITION XCOORD) of NEWPOS) (fetch (POSITION XCOORD) of FIRSTHOTSPOT)) YCOORD ←(IDIFFERENCE (fetch (POSITION YCOORD) of NEWPOS) (fetch (POSITION YCOORD) of FIRSTHOTSPOT] (WINDOW.SCALE SKW] (SKETCH.MOVE.ELEMENTS (for ELT in SCRELTS collect (fetch (SCREENELT GLOBALPART) of ELT)) GDELTAPOS SKW T) (* I started noticing cases where the image was a point off on some lines and where the texture alignment was off so I removed this (COND ((AND DELTAPOS (NOT (POSITIONP X))) (* If the user was asked for a new position and the movefn didn't change it, redraw the image in case any of it was erased by the calls to SK.TRANSLATE.ITEM) (SK.SHOW.FIG.FROM.INFO IMAGEBM (IPLUS IMAGEPOSX (fetch (POSITION XCOORD) of DELTAPOS)) (IPLUS IMAGEPOSY (fetch (POSITION YCOORD) of DELTAPOS)) (QUOTE PAINT) SKW)))) (CLOSEPROMPTWINDOW SKW]) (SKETCH.MOVE.ELEMENTS [LAMBDA (ELEMENTS DELTA SKETCHTOUPDATE ADDHISTORY?) (* rrb " 4-Dec-85 21:48") (* moves the elements ELEMENTS by the amount of position DELTA (XCOORD gives x amount, YCOORD gives y delta) and updates the viewers on SKETCHTOUPDATE if it is given.) (PROG (X MOVEFN NEWGLOBALS SKETCH GDELTAPOS VIEWER) (OR (POSITIONP DELTA) (\ILLEGAL.ARG DELTA)) [AND SKETCHTOUPDATE (SETQ SKETCH (INSURE.SKETCH SKETCHTOUPDATE)) (SETQ VIEWER (OR (WINDOWP SKETCHTOUPDATE) (CAR (ALL.SKETCH.VIEWERS SKETCH] (COND [[AND SKETCH (SETQ MOVEFN (GETSKETCHPROP SKETCH (QUOTE MOVEFN] (* call the MOVEFN if any Pass the thing the user passed in if you can't find a viewer.) (COND ((EQ (SETQ X (APPLY* MOVEFN VIEWER (for ELT in ELEMENTS collect (CONS T ELT)) DELTA)) (QUOTE DON'T)) (RETURN)) ((POSITIONP X) (* value returned is the delta by which to move the point. Set up new position) (SETQ GDELTAPOS X)) (T (SETQ GDELTAPOS DELTA] (T (SETQ GDELTAPOS DELTA))) (SETQ NEWGLOBALS (MAPGLOBALSKETCHSPECS ELEMENTS (FUNCTION SK.TRANSLATE.ELEMENT) GDELTAPOS VIEWER)) (AND ADDHISTORY? (SK.ADD.HISTEVENT (QUOTE MOVE) (for NEWG in NEWGLOBALS as OLDG in ELEMENTS when NEWG collect (LIST OLDG NEWG)) VIEWER]) (SK.TRANSLATE.ELEMENT [LAMBDA (GELT GLOBALDELTAPOS W) (* rrb " 4-Dec-85 19:58") (* * GELT is a sketch element to be moved. GLOBALDELTAPOS is the amount the item is to be translated.) (PROG (NEWGLOBAL) (COND ((SETQ NEWGLOBAL (SK.TRANSLATE.GLOBALPART GELT GLOBALDELTAPOS)) (SK.UPDATE.ELEMENT GELT NEWGLOBAL W T) (RETURN NEWGLOBAL]) (SK.MAKE.ELEMENT.MOVE.ARG [LAMBDA (SCRELT SELPOS) (* rrb " 5-Nov-85 14:35") (* makes an argument structure that is suitable to be passed to the sketch movefn. This is a list whose CAR is a list of the numbers of the control points being moved and whose CDR is the global sketch element.) (CONS (CONS (for I from 1 as PT in (fetch (SCREENELT HOTSPOTS) of SCRELT) when (EQUAL PT SELPOS) do (RETURN I))) (fetch (SCREENELT GLOBALPART) of SCRELT]) (SK.MAKE.ELEMENTS.MOVE.ARG [LAMBDA (SCRELTS) (* rrb " 5-Nov-85 14:34") (* makes an argument structure that is suitable to be passed to the sketch movefn. This is a list whose CAR is a list of the numbers of the control points being moved which is in this case T and whose CDR is the global sketch element.) (CONS T (for SCRELT in SCRELTS collect (fetch (SCREENELT GLOBALPART) of SCRELT]) (SK.MAKE.POINTS.AND.ELEMENTS.MOVE.ARG [LAMBDA (SCRELTS SELPTS) (* rrb " 5-Nov-85 15:14") (* makes an argument structure that is suitable to be passed to the sketch movefn. This is a list of lists each of whose CAR is a list of the numbers of the control points being moved and whose CDR is the global sketch element.) (for SCRELT in SCRELTS collect (CONS [CONS (bind NOTALL for I from 1 as PT in (fetch (SCREENELT HOTSPOTS) of SCRELT) when (COND ((MEMBER PT SELPTS)) (T (SETQ NOTALL T) NIL)) collect I finally (OR NOTALL (RETURN T] (fetch (SCREENELT GLOBALPART) of SCRELT]) (SK.SHOW.FIG.FROM.INFO [LAMBDA (IMAGEBM XOFFSET YOFFSET OPERATION WINDOW) (* rrb "14-Nov-84 14:20") (* puts a bitmap onto the sketch window.) (BITBLT IMAGEBM 0 0 WINDOW XOFFSET YOFFSET NIL NIL (QUOTE INPUT) OPERATION]) (SK.MOVE.THING [LAMBDA (SKETCHELT LOCALPT GDELTAPOS SKW) (* rrb " 5-Nov-85 12:23") (* moves a control point in a sketch element.) (PROG (OLDGLOBAL NEWGLOBAL) (* calculate the delta that the selected point moves.) (SETQ NEWGLOBAL (SK.TRANSLATE.POINTS (LIST LOCALPT) GDELTAPOS SKETCHELT SKW)) (* moving a piece of an element.) (SK.UPDATE.ELEMENT (SETQ OLDGLOBAL (fetch (SCREENELT GLOBALPART) of SKETCHELT)) NEWGLOBAL SKW) (SK.ADD.HISTEVENT (QUOTE MOVE) (LIST (LIST OLDGLOBAL NEWGLOBAL)) SKW) (RETURN NEWGLOBAL]) (UPDATE.ELEMENT.IN.SKETCH [LAMBDA (OLDGELT NEWGELT SKETCH SKW UNDOFLG) (* rrb "21-Jun-85 16:51") (* changes the global sketch) (* returns NIL if the old global sketch element is not found in SKETCH. This can happen if things are undone out of order.) (PROG ((SKETCHSTRUCTURE (INSURE.SKETCH SKETCH))) (* if old and new are the same, the change was done destructively; otherwise clobber the new one in.) (RETURN (COND ((OR (EQ OLDGELT NEWGELT) (for GELTTAIL on (fetch (SKETCH SKETCHELTS) of SKETCHSTRUCTURE) when (EQ (CAR GELTTAIL) OLDGELT) do (RPLACA GELTTAIL NEWGELT) (RETURN T))) (SK.MARK.DIRTY SKETCH) T]) (SK.UPDATE.ELEMENT [LAMBDA (OLDGLOBAL NEWGLOBAL SKETCHW REDRAWIFSAMEFLG) (* rrb "21-Jun-85 16:47") (* replaces an old element with a new one. The global part of the old one may be the same as the new global part. This also handles propagation to other windows that have the same figure displayed.) (PROG ((SKETCH (SKETCH.FROM.VIEWER SKETCHW)) UPDATEDELT) (* update the element in the sketch first. If this returns NIL, the element was not found in the sketch.) (OR (UPDATE.ELEMENT.IN.SKETCH OLDGLOBAL NEWGLOBAL SKETCH SKETCHW) (RETURN NIL)) (* do the window that the interaction occurred in first.) (SETQ UPDATEDELT (SK.UPDATE.ELEMENT1 OLDGLOBAL NEWGLOBAL SKETCHW REDRAWIFSAMEFLG)) (* propagate to other windows.) (for SKW in (ALL.SKETCH.VIEWERS SKETCH) when (NEQ SKW SKETCHW) do (* the position may have changed which means that it may have moved in or out of a viewer.) (SK.UPDATE.ELEMENT1 OLDGLOBAL NEWGLOBAL SKW REDRAWIFSAMEFLG)) (RETURN UPDATEDELT]) (SK.UPDATE.ELEMENTS [LAMBDA (OLDNEWPAIRS WINDOW) (* rrb "10-Sep-84 17:01") (* replaces the global parts of a list of old-new pairs and handles updating the screen.) (for PAIR in OLDNEWPAIRS do (SK.UPDATE.ELEMENT (CAR PAIR) (CADR PAIR) WINDOW]) (SK.UPDATE.ELEMENT1 [LAMBDA (OLDGELT NEWGELT SKETCHW REDRAWIFSAME) (* rrb "10-Dec-85 11:00") (* determines what action is needed wrt the viewer SKETCHW when the element OLDGELT is updated to NEWGELT. This works only in the given window.) (PROG (LOCALELT UPDATEFN NEWLOCAL) (COND [(SETQ LOCALELT (SK.LOCAL.ELT.FROM.GLOBALPART OLDGELT SKETCHW)) (COND ((EQ (SKETCH.ELEMENT.TYPE OLDGELT) (QUOTE SKIMAGEOBJ)) (* handle imageobject case specially because changes are often in internal structure) (SK.DELETE.ITEM LOCALELT SKETCHW) (* erase the old image region because often the internal parts of the image object have been clobbered making it impossible to erase by redrawing) (DSPFILL (fetch (LOCALSKIMAGEOBJ SKIMOBJLOCALREGION) of (fetch (SCREENELT LOCALPART) of LOCALELT)) WHITESHADE (QUOTE REPLACE) SKETCHW) (RETURN (SKETCH.ADD.AND.DISPLAY1 NEWGELT SKETCHW))) [[AND (EQUAL OLDGELT NEWGELT) (NOT (MEMB (fetch (GLOBALPART GTYPE) of OLDGELT) (QUOTE (TEXT TEXTBOX] (* text and textbox are special because interactive editing reuses the same element after the first character but they need to use updatefns for speed.) (* replacing something by something else that is identical. Check here because add will not add something that is already there and updatefn may call add first.) (COND (REDRAWIFSAME (* this entry is used from the WB.BUTTON.HANDLER and deals with image objects which we have no control over whether they give us something new or not.) (SK.ERASE.AND.DELETE.ITEM LOCALELT SKETCHW)) (T (SK.DELETE.ITEM LOCALELT SKETCHW) (RETURN (SK.ADD.ITEM NEWGELT SKETCHW] ((AND (SETQ UPDATEFN (SK.UPDATEFN (fetch (GLOBALPART GTYPE) of NEWGELT))) (SETQ NEWLOCAL (APPLY* UPDATEFN LOCALELT NEWGELT SKETCHW))) (* if the old one is visible and the element has an updatefn, use it to update the display. Then delete the old one. The updatefn should have added the new one.) (SK.DELETE.ITEM LOCALELT SKETCHW) (RETURN NEWLOCAL)) (T (* if this type doesn't have a updatefn or it returned NIL, do the erase and redraw method.) (SK.ERASE.AND.DELETE.ITEM LOCALELT SKETCHW] ((NOT (MEMB NEWGELT (SKETCH.ELEMENTS.OF.SKETCH SKETCHW))) (* this element isn't a member of this sketch, quit) (RETURN))) (RETURN (COND ((ELT.INSIDE.SKWP NEWGELT SKETCHW) (SKETCH.ADD.AND.DISPLAY1 NEWGELT SKETCHW]) (SK.MOVE.ELEMENT.POINT [LAMBDA (W) (* rrb "20-Feb-85 20:27") (* lets the user select an element and move it.) (EVAL.AS.PROCESS (LIST (QUOTE SK.SEL.AND.MOVE) W (QUOTE (QUOTE ONLY]) ) (* fns for moving points or a collection of pts.) (DEFINEQ (SK.MOVE.POINTS [LAMBDA (W) (* rrb " 3-May-85 17:35") (* lets the user select a collection of points and move them.) (EVAL.AS.PROCESS (LIST (QUOTE SK.SEL.AND.MOVE.POINTS) W]) (SK.SEL.AND.MOVE.POINTS [LAMBDA (W) (* rrb "17-Oct-85 11:11") (* * lets the user select a collection of control point and moves them.) (SK.DO.MOVE.ELEMENT.POINTS (SK.SELECT.MULTIPLE.POINTS W) W]) (SK.DO.MOVE.ELEMENT.POINTS [LAMBDA (SCRPTS SKW) (* rrb " 5-Nov-85 15:30") (* moves a collection of points) (SKED.CLEAR.SELECTION SKW) (AND SCRPTS (PROG ((SCRELTS (SK.ELTS.CONTAINING.PTS SCRPTS SKW)) NONMOVEDHOTSPOTS ONEPTELTS FIGINFO FIRSTHOTSPOT NEWPOS LOWLFT IMAGEPOSX IMAGEPOSY IMAGEBM DELTAPOS NEWGLOBALS CHANGES MOVEFN X MOVEARGS SKETCH GDELTAPOS) [AND (SETQ MOVEFN (GETSKETCHPROP (SETQ SKETCH (INSURE.SKETCH SKW)) (QUOTE PREMOVEFN))) (SETQ GDELTAPOS (APPLY* MOVEFN SKW (SETQ MOVEARGS ( SK.MAKE.POINTS.AND.ELEMENTS.MOVE.ARG SCRELTS SCRPTS] (COND ((EQ GDELTAPOS (QUOTE DON'T)) (RETURN)) ((POSITIONP GDELTAPOS) (* value returned is the delta by which to move the point. Set up new position) NIL) (T (* read new position from the user) (* create a bitmap of all of the elements that have any point being moved and get its new position. Use only the region that contains the points. points plus a boarder to catch the lines of a box as large as the region.) (SETQ NONMOVEDHOTSPOTS (SK.HOTSPOTS.NOT.ON.LIST SCRPTS SCRELTS)) [SETQ ONEPTELTS (SUBSET SCRELTS (FUNCTION (LAMBDA (ELT) (EQ (LENGTH (fetch (LOCALPART HOTSPOTS) of (fetch (SCREENELT LOCALPART) of ELT))) 1] (SETQ FIGINFO (SK.FIGUREIMAGE SCRELTS NIL (INCREASEREGION (COND [ONEPTELTS (* include the regions of any elements that only have one control point. This picks up text and groups whose image is much larger than the point.) (UNIONREGIONS (REGION.CONTAINING.PTS SCRPTS) ( SK.GLOBAL.REGION.OF.LOCAL.ELEMENTS ONEPTELTS (WINDOW.SCALE SKW] (T (REGION.CONTAINING.PTS SCRPTS))) 4))) (SETQ FIRSTHOTSPOT (CAR SCRPTS)) (SETQ LOWLFT (fetch (SKFIGUREIMAGE SKFIGURE.LOWERLEFT) of FIGINFO)) (SETQ IMAGEBM (fetch (SKFIGUREIMAGE SKFIGURE.BITMAP) of FIGINFO)) (* move the image by the first hotspot of the first element chosen. This will align the image on the grid correctly.) (SETQ IMAGEPOSX (fetch (POSITION XCOORD) of LOWLFT)) (SETQ IMAGEPOSY (fetch (POSITION YCOORD) of LOWLFT)) (* put the cursor on the hot spot) (CURSORPOSITION FIRSTHOTSPOT SKW) (COND ([NULL (ERSETQ (PROGN (SK.SHOW.FIG.FROM.INFO IMAGEBM IMAGEPOSX IMAGEPOSY (QUOTE ERASE) SKW) (for PT in NONMOVEDHOTSPOTS do (MARKPOINT PT SKW OTHERCONTROLPOINTMARK)) (SETQ NEWPOS (fetch (INPUTPT INPUT.POSITION) of (GET.BITMAP.POSITION SKW IMAGEBM (QUOTE PAINT) "Move image to its new position." (IDIFFERENCE IMAGEPOSX (fetch (POSITION XCOORD) of FIRSTHOTSPOT) ) (IDIFFERENCE IMAGEPOSY (fetch (POSITION YCOORD) of FIRSTHOTSPOT] (* error happened, repaint the image.) (SK.SHOW.FIG.FROM.INFO IMAGEBM IMAGEPOSX IMAGEPOSY (QUOTE PAINT) SKW) (for PT in NONMOVEDHOTSPOTS do (MARKPOINT PT SKW OTHERCONTROLPOINTMARK)) (CLOSEPROMPTWINDOW SKW) (ERROR!)) ((NULL NEWPOS) (SK.SHOW.FIG.FROM.INFO IMAGEBM IMAGEPOSX IMAGEPOSY (QUOTE PAINT) SKW) (for PT in NONMOVEDHOTSPOTS do (MARKPOINT PT SKW OTHERCONTROLPOINTMARK)) (STATUSPRINT SKW "Position was outside the window, copy not placed.") (RETURN NIL))) (* GET.BITMAP.POSITION returns the position that the cursor was in which is the position of the first hotspot.) (for PT in NONMOVEDHOTSPOTS do (MARKPOINT PT SKW OTHERCONTROLPOINTMARK)) (SETQ GDELTAPOS (SK.MAP.FROM.WINDOW.TO.NEAREST.GRID (create POSITION XCOORD ←(IDIFFERENCE (fetch (POSITION XCOORD) of NEWPOS) (fetch (POSITION XCOORD) of FIRSTHOTSPOT)) YCOORD ←(IDIFFERENCE (fetch (POSITION YCOORD) of NEWPOS) (fetch (POSITION YCOORD) of FIRSTHOTSPOT))) (WINDOW.SCALE SKW))) (* calculate the delta that the selected point moves.) )) (AND (SETQ MOVEFN (GETSKETCHPROP SKETCH (QUOTE MOVEFN))) (SETQ X (APPLY* MOVEFN SKW (OR MOVEARGS (SK.MAKE.ELEMENTS.MOVE.ARG SCRELTS)) GDELTAPOS))) (COND ((EQ X (QUOTE DON'T)) (RETURN)) ((POSITIONP X) (* value returned is the delta by which to move the point. Set up new position) (SETQ GDELTAPOS X))) (SETQ NEWGLOBALS (MAPCOLLECTSKETCHSPECS SCRELTS (FUNCTION SK.MOVE.ITEM.POINTS) GDELTAPOS SKW SCRPTS)) (SK.ADD.HISTEVENT (QUOTE MOVE) (for NEWG in NEWGLOBALS as OLDG in SCRELTS when NEWG collect (LIST (fetch (SCREENELT GLOBALPART) of OLDG) NEWG)) SKW) (CLOSEPROMPTWINDOW SKW]) (SK.MOVE.ITEM.POINTS [LAMBDA (SELELT GLOBALDELTAPOS W LOCALPTS) (* rrb "11-Jul-85 13:44") (* SELELT is a sketch element at least one of whose points was selected for a translate operation. GLOBALDELTAPOS is the amount the item is to be translated. LOCALPTS is the list of points that was selected. This function moves any of those that belong to SELELT and return the new global. If all of SELELT points are on LOCALPTS this is a SK.TRANSLATE.ITEM.) (PROG ((ELTHOTSPOTS (fetch (LOCALPART HOTSPOTS) of (fetch (SCREENELT LOCALPART) of SELELT))) MOVEDPTS NEWGLOBAL OLDGLOBAL NEWSCREENELT) (* this shouldn't happen but don't cause an error if it does.) (OR (SETQ MOVEDPTS (INTERSECTION ELTHOTSPOTS LOCALPTS)) (RETURN)) (* map the difference point onto a grid location that would have the same screen distance but will leave things on a power of two.) (SETQ OLDGLOBAL (fetch (SCREENELT GLOBALPART) of SELELT)) (COND ((EQ (LENGTH MOVEDPTS) (LENGTH ELTHOTSPOTS)) (* all of its hot spots have been moved, just translate it) (OR (SETQ NEWGLOBAL (SK.TRANSLATE.GLOBALPART OLDGLOBAL GLOBALDELTAPOS W)) (RETURN NIL))) ((SETQ NEWGLOBAL (SK.TRANSLATE.POINTS MOVEDPTS GLOBALDELTAPOS SELELT W))) (T (RETURN NIL))) (SK.UPDATE.ELEMENT OLDGLOBAL NEWGLOBAL W T) (RETURN NEWGLOBAL]) (SK.TRANSLATEPTSFN [LAMBDA (ELEMENTTYPE) (* rrb " 5-May-85 16:25") (* goes from an element type name to its EXPANDFN) (fetch (SKETCHTYPE TRANSLATEPTSFN) of (GETPROP ELEMENTTYPE (QUOTE SKETCHTYPE]) (SK.TRANSLATE.POINTS [LAMBDA (SELPTS GLOBALDELTA SKETCHELT W) (* rrb " 5-May-85 18:51") (* moves the selected points by a global amount.) (AND SKETCHELT (APPLY* (SK.TRANSLATEPTSFN (fetch (SCREENELT GTYPE) of SKETCHELT)) SKETCHELT SELPTS GLOBALDELTA W]) (SK.SELECT.MULTIPLE.POINTS [LAMBDA (SKW) (* rrb "10-Dec-85 16:41") (* * allows the user to select a collection of control points.) (PROG ((INTERIOR (DSPCLIPPINGREGION NIL SKW)) SELECTABLEITEMS HOTSPOTCACHE NOW OLDX ORIGX NEWX NEWY OLDY ORIGY SELPTS PREVMOUSEBUTTONS MOUSEINSIDE?) (COND [(SK.HAS.SOME.HOTSPOTS (SETQ HOTSPOTCACHE (SK.HOTSPOT.CACHE.FOR.OPERATION SKW (QUOTE MOVE] (T (* no items, don't do anything.) (RETURN))) (TOTOPW SKW) (SK.PUT.MARKS.UP SKW HOTSPOTCACHE) (until (MOUSESTATE (NOT UP))) (COND ((INSIDEP INTERIOR (LASTMOUSEX SKW) (LASTMOUSEY SKW))) (T (* first press was outside of the window, don't select anything.) (SK.TAKE.MARKS.DOWN SKW HOTSPOTCACHE) (RETURN))) SELECTLP (COND ((MOUSESTATE UP) (GO SHIFTDOWNLP))) (* this label provides an entry for the code that tests if the shift key is down.) SELAFTERTEST (SETQ NEWY (LASTMOUSEY SKW)) (SETQ NEWX (LASTMOUSEX SKW)) [COND [(NOT MOUSEINSIDE?) (* mouse is outside, don't do anything other than wait for it to come back in. If the user has let up all buttons, the branch to SELECTEXIT will have been taken.) (COND ((INSIDEP INTERIOR NEWX NEWY) (SETQ MOUSEINSIDE? T) (* restore the saved selected items.) (for ELT in SELPTS do (SK.ADD.PT.SELECTION ELT SKW] ((NOT (INSIDEP INTERIOR NEWX NEWY)) (* mouse just went outside, remove selections but save them in case mouse comes back in.) (SETQ MOUSEINSIDE? NIL) (SETQ SELPTS (WINDOWPROP SKW (QUOTE SKETCH.SELECTIONS))) (for ELT in SELPTS do (SK.REMOVE.PT.SELECTION ELT SKW))) [(NEQ PREVMOUSEBUTTONS LASTMOUSEBUTTONS) (* another button has gone down, mark this as the origin of a new box to sweep.) (SETQ PREVMOUSEBUTTONS LASTMOUSEBUTTONS) (SETQ ORIGX (LASTMOUSEX SKW)) (SETQ ORIGY (LASTMOUSEY SKW)) (* add or delete the element that the button press occurred on if any.) (AND (SETQ NOW (IN.SKETCH.ELT? HOTSPOTCACHE (create POSITION XCOORD ← NEWX YCOORD ← NEWY) T)) (COND ((LASTMOUSESTATE (ONLY LEFT)) (* add selection.) (SK.ADD.PT.SELECTION NOW SKW)) ((LASTMOUSESTATE RIGHT) (* remove selection.) (SK.REMOVE.PT.SELECTION NOW SKW] ([AND (OR (NEQ NEWX OLDX) (NEQ NEWY OLDY)) (SETQ SELPTS (SK.CONTROL.POINTS.IN.REGION HOTSPOTCACHE (MIN ORIGX NEWX) (MIN ORIGY NEWY) (MAX ORIGX NEWX) (MAX ORIGY NEWY] (* add or delete any with in the swept out area.) (COND ((LASTMOUSESTATE (ONLY LEFT)) (* left only selects.) (for SELPT in SELPTS do (SK.ADD.PT.SELECTION SELPT SKW))) ((LASTMOUSESTATE RIGHT) (* right cause deselect.) (for SELPT in SELPTS do (SK.REMOVE.PT.SELECTION SELPT SKW] (SETQ OLDX NEWX) (SETQ OLDY NEWY) (GO SELECTLP) SHIFTDOWNLP (COND ((MOUSESTATE (NOT UP)) (* button went down again, initialize the button state and click position.) (SETQ PREVMOUSEBUTTONS NIL) (GO SELAFTERTEST)) ((.SHIFTKEYDOWNP.) [COND [(NOT MOUSEINSIDE?) (* mouse is outside: if it comes back in, mark the selections.) (COND ((INSIDEP INTERIOR (LASTMOUSEX SKW) (LASTMOUSEY SKW)) (SETQ MOUSEINSIDE? T) (* restore the saved selected items.) (for ELT in SELPTS do (SK.ADD.PT.SELECTION ELT SKW] ((NOT (INSIDEP INTERIOR (LASTMOUSEX SKW) (LASTMOUSEY SKW))) (* mouse just went outside, remove marks but keep selections) (SETQ MOUSEINSIDE? NIL) (SETQ SELPTS (WINDOWPROP SKW (QUOTE SKETCH.SELECTIONS))) (for ELT in SELPTS do (SK.REMOVE.PT.SELECTION ELT SKW] (GO SHIFTDOWNLP))) (SETQ SELPTS (WINDOWPROP SKW (QUOTE SKETCH.SELECTIONS))) (for SEL in SELPTS do (SK.REMOVE.PT.SELECTION SEL SKW)) (SK.TAKE.MARKS.DOWN SKW HOTSPOTCACHE) (RETURN SELPTS]) (SK.CONTROL.POINTS.IN.REGION [LAMBDA (HOTSPOTCACHE LEFT BOTTOM RIGHT TOP) (* rrb " 6-May-85 16:22") (* * returns a list of the control points that are within LOCALREGION) (PROG ((RLEFT (DIFFERENCE LEFT SK.POINT.WIDTH)) (RBOTTOM (DIFFERENCE BOTTOM SK.POINT.WIDTH)) (RRIGHT (PLUS RIGHT SK.POINT.WIDTH)) (RTOP (PLUS TOP SK.POINT.WIDTH)) ELTS) [for YBUCKET in HOTSPOTCACHE when (ILEQ (CAR YBUCKET) RTOP) do (COND ((ILESSP (CAR YBUCKET) RBOTTOM) (* stop when Y gets too small.) (RETURN))) (for XBUCKET in (CDR YBUCKET) when (ILEQ (CAR XBUCKET) RRIGHT) do (COND ((ILESSP (CAR XBUCKET) RLEFT) (* stop when X gets too small.) (RETURN))) (* collect the points if there are any elements cached there.) (AND (CDR XBUCKET) (SETQ ELTS (SK.ADD.POINT ELTS (CAR XBUCKET) (CAR YBUCKET] (RETURN ELTS]) (SK.ADD.PT.SELECTION [LAMBDA (PT WINDOW MARKBM) (* rrb " 9-May-85 10:18") (* adds an item to the selection list of WINDOW.) (COND ([NOT (MEMBER PT (WINDOWPROP WINDOW (QUOTE SKETCH.SELECTIONS] (MARKPOINT PT WINDOW MARKBM) (WINDOWADDPROP WINDOW (QUOTE SKETCH.SELECTIONS) PT]) (SK.REMOVE.PT.SELECTION [LAMBDA (PT WINDOW MARKBM) (* rrb " 9-May-85 10:22") (* removes an item from the selection list of WINDOW.) (COND ((MEMBER PT (WINDOWPROP WINDOW (QUOTE SKETCH.SELECTIONS))) (MARKPOINT PT WINDOW MARKBM) (* used to call WINDOWDELPROP but it has a bug that it only removes EQ things.) (WINDOWPROP WINDOW (QUOTE SKETCH.SELECTIONS) (REMOVE PT (WINDOWPROP WINDOW (QUOTE SKETCH.SELECTIONS]) (SK.ADD.POINT [LAMBDA (PTLST X Y) (* rrb " 6-May-85 16:22") (* add the point X Y to PTLST unless it is already a member.) (COND ((for PT in PTLST thereis (AND (EQ (fetch (POSITION XCOORD) of PT) X) (EQ (fetch (POSITION YCOORD) of PT) Y))) PTLST) (T (CONS (CREATE POSITION XCOORD ← X YCOORD ← Y) PTLST]) (SK.ELTS.CONTAINING.PTS [LAMBDA (PTLST SKW) (* rrb " 4-May-85 15:38") (* returns the list of elements that have any points on PTLST.) (bind (HOTSPOTCACHE ←(SK.HOTSPOT.CACHE SKW)) ELTS for POS in PTLST do (SETQ ELTS (UNION (SK.ELTS.FROM.HOTSPOT POS HOTSPOTCACHE) ELTS)) finally (* reverse them so the first selected pt has its element first.) (RETURN (REVERSE ELTS]) (SK.HOTSPOTS.NOT.ON.LIST [LAMBDA (PTLST ELTS) (* rrb "19-Jul-85 13:18") (* returns a list of the hot spots on any of ELTS that aren't on PTLST.) (bind OTHERHOTSPOTS for ELT in ELTS do [for HOTSPOT in (fetch (SCREENELT HOTSPOTS) of ELT) do (OR (MEMBER HOTSPOT PTLST) (MEMBER HOTSPOT OTHERHOTSPOTS) (SETQ OTHERHOTSPOTS (CONS HOTSPOT OTHERHOTSPOTS] finally (RETURN OTHERHOTSPOTS]) ) (DECLARE: EVAL@COMPILE [PUTPROPS .SHIFTKEYDOWNP. MACRO (NIL (OR (KEYDOWNP (QUOTE LSHIFT)) (KEYDOWNP (QUOTE RSHIFT] ) (DEFINEQ (SK.SET.MOVE.MODE [LAMBDA (SKW NEWMODE) (* rrb " 2-Jun-85 12:52") (* * reads a value of move command mode and makes it the default) (PROG [(LOCALNEWMODE (OR NEWMODE (READMOVEMODE] (RETURN (AND LOCALNEWMODE (replace (SKETCHCONTEXT SKETCHMOVEMODE) of (WINDOWPROP SKW (QUOTE SKETCHCONTEXT)) with (SELECTQ NEWMODE ((POINTS ELEMENTS) NEWMODE) NIL]) (SK.SET.MOVE.MODE.POINTS [LAMBDA (SKW) (* rrb " 2-Jun-85 12:47") (* sets the default to move mode to points.) (SK.SET.MOVE.MODE SKW (QUOTE POINTS]) (SK.SET.MOVE.MODE.ELEMENTS [LAMBDA (SKW) (* rrb " 2-Jun-85 12:48") (* sets the default to move mode to elements) (SK.SET.MOVE.MODE SKW (QUOTE ELEMENTS]) (SK.SET.MOVE.MODE.COMBINED [LAMBDA (SKW) (* rrb " 2-Jun-85 12:49") (* sets the default to move mode to combined move.) (SK.SET.MOVE.MODE SKW (QUOTE COMBINED]) (READMOVEMODE [LAMBDA (MENUTITLE) (* rrb " 6-Nov-85 09:54") (* interacts to get whether move mode should be points, elements or both.) (\CURSOR.IN.MIDDLE.MENU (create MENU TITLE ←(OR MENUTITLE "Top level MOVE command should apply to?") ITEMS ←(QUOTE ((Points (QUOTE POINTS) "Top level MOVE command will be the same as MOVE POINTS command.") (Elements (QUOTE ELEMENTS) "Top level MOVE command will be the same as MOVE ELEMENTS command.") (Combined (QUOTE COMBINED) "MOVE command will move points if a single point is clicked; elements otherwise"))) CENTERFLG ← T]) ) (* stuff for supporting the GROUP sketch element.) (DEFINEQ (SKETCH.CREATE.GROUP [LAMBDA (LISTOFSKETCHELEMENTS CONTROLPOINT) (* rrb " 4-Dec-85 21:38") (* creates a sketch group element.) (SK.CREATE.GROUP1 LISTOFSKETCHELEMENTS (OR (POSITIONP CONTROLPOINT) (REGION.CENTER ( SK.GLOBAL.REGION.OF.GLOBAL.ELEMENTS LISTOFSKETCHELEMENTS]) (SK.CREATE.GROUP1 [LAMBDA (GELTS CONTROLPT) (* rrb " 4-Dec-85 21:38") (* creates a group element.) (SK.UPDATE.GROUP.AFTER.CHANGE (create GLOBALPART INDIVIDUALGLOBALPART ←(create GROUP LISTOFGLOBALELTS ← GELTS GROUPCONTROLPOINT ← CONTROLPT]) (SK.UPDATE.GROUP.AFTER.CHANGE [LAMBDA (GROUPELT) (* rrb " 4-Dec-85 21:38") (* updates the dependent field of a group element after a change.) (PROG ((INDGROUPELT (fetch (GLOBALPART INDIVIDUALGLOBALPART) of GROUPELT)) GROUPREGION) (SETQ GROUPREGION (SK.GLOBAL.REGION.OF.GLOBAL.ELEMENTS (fetch (GROUP LISTOFGLOBALELTS) of INDGROUPELT))) (replace (GROUP GROUPREGION) of INDGROUPELT with GROUPREGION) (* use same scales as a box would.) (BOX.SET.SCALES GROUPREGION GROUPELT) (RETURN GROUPELT]) (SK.GROUP.ELTS [LAMBDA (W) (* rrb "11-Jan-85 11:16") (* lets the user select a collection elements and groups them.) (EVAL.AS.PROCESS (LIST (QUOTE SK.SEL.AND.GROUP) W]) (SK.SEL.AND.GROUP [LAMBDA (W) (* rrb "10-Dec-85 17:08") (* lets the user select elements and groups them.) (SK.GROUP.ELEMENTS (SK.SELECT.MULTIPLE.ITEMS W T NIL (QUOTE GROUP)) W]) (SK.GROUP.ELEMENTS [LAMBDA (SCRELTS SKW) (* rrb "10-Dec-85 17:23") (* groups the collection of elements SCRELTS. Does this by creating a group element, adding it and deleting the individual elements.) (AND SCRELTS (PROG (GELTS GROUPELT GROUPREGION GROUPFN X (SCALE (WINDOW.SCALE SKW))) (* call the group fn if there is one.) [AND (SETQ GROUPFN (GETSKETCHPROP (INSURE.SKETCH SKW) (QUOTE WHENGROUPEDFN))) (SETQ X (APPLY* GROUPFN SKW (SK.GLOBAL.FROM.LOCAL.ELEMENTS SCRELTS] (COND ((EQ X (QUOTE DON'T)) (RETURN))) (SETQ GROUPREGION (SK.GLOBAL.REGION.OF.LOCAL.ELEMENTS SCRELTS SCALE)) (SETQ GELTS (for SCRELT in SCRELTS collect (fetch (SCREENELT GLOBALPART) of SCRELT))) (SETQ GROUPELT (SKETCH.CREATE.GROUP GELTS (MAP.GLOBAL.PT.ONTO.GRID (REGION.CENTER GROUPREGION) SKW))) (* do grouping.) (SK.DO.GROUP GROUPELT GELTS SKW) (* record it on the history list.) (SK.ADD.HISTEVENT (QUOTE GROUP) (LIST (LIST GROUPELT GELTS)) SKW) (RETURN GROUPELT]) (SK.UNGROUP.ELT [LAMBDA (W) (* rrb "11-Jan-85 16:02") (* lets the user select a collection elements and groups them.) (EVAL.AS.PROCESS (LIST (QUOTE SK.SEL.AND.UNGROUP) W]) (SK.SEL.AND.UNGROUP [LAMBDA (W) (* rrb "10-Dec-85 18:03") (* lets the user select elements and groups them.) (PROG NIL (RETURN (SK.UNGROUP.ELEMENT [SK.SELECT.MULTIPLE.ITEMS W T (COND [(SUBSET (LOCALSPECS.FROM.VIEWER W) (FUNCTION (LAMBDA (SCRELT) (AND (EQ (fetch (SCREENELT GTYPE) of SCRELT) (QUOTE GROUP)) (NOT (SK.ELEMENT.PROTECTED? (fetch (SCREENELT GLOBALPART) of SCRELT) (QUOTE UNGROUP] (T (* no group elements) (STATUSPRINT W "There are no grouped elements to ungroup.") (RETURN] W]) (SK.UNGROUP.ELEMENT [LAMBDA (SCRELTS SKW) (* rrb "10-Dec-85 17:35") (* ungroups the first group element in SCRELTS.) (PROG ((GROUPELTS (for ELT in SCRELTS when (EQ (fetch (SCREENELT GTYPE) of ELT) (QUOTE GROUP)) collect (fetch (SCREENELT GLOBALPART) of ELT))) GELTS UNGROUPFN LSTOFSUBELTS) (OR GROUPELTS (RETURN)) [SETQ LSTOFSUBELTS (for GROUPELT in GROUPELTS collect (COND ((AND (SETQ UNGROUPFN (GETSKETCHPROP (INSURE.SKETCH SKW) (QUOTE WHENUNGROUPED))) (EQ (APPLY* UNGROUPFN SKW GROUPELT) (QUOTE DON'T))) (* call the ungroup fn if there is one.) NIL) (T (SETQ GELTS (fetch (GROUP LISTOFGLOBALELTS) of (fetch (GLOBALPART INDIVIDUALGLOBALPART) of GROUPELT))) (SK.DO.UNGROUP GROUPELT GELTS SKW) GELTS] (SK.ADD.HISTEVENT (QUOTE UNGROUP) (for GROUPELT in GROUPELTS as SUBELTS in LSTOFSUBELTS when LSTOFSUBELTS collect (LIST GROUPELT SUBELTS)) SKW]) (SK.GLOBAL.REGION.OF.LOCAL.ELEMENTS [LAMBDA (SCRELTS SCALE) (* rrb "18-Feb-85 17:31") (* returns the global region occuppied by a list of local elements.) (PROG (GROUPREGION) [for SCRELT in SCRELTS do (SETQ GROUPREGION (COND (GROUPREGION (* first time because UNIONREGIONS doesn't handle NIL) (UNIONREGIONS GROUPREGION (SK.ITEM.REGION SCRELT) )) (T (SK.ITEM.REGION SCRELT] (RETURN (UNSCALE.REGION GROUPREGION SCALE]) (SK.GLOBAL.REGION.OF.GLOBAL.ELEMENTS [LAMBDA (GELTS) (* rrb "19-Oct-85 13:00") (* returns the global region occuppied by a list of global elements.) (PROG (GROUPREGION) [for GELT in GELTS do (SETQ GROUPREGION (COND (GROUPREGION (* first time because UNIONREGIONS doesn't handle NIL) (UNIONREGIONS GROUPREGION ( SK.ELEMENT.GLOBAL.REGION GELT))) (T (SK.ELEMENT.GLOBAL.REGION GELT] (RETURN GROUPREGION]) (SKETCH.REGION.OF.SKETCH [LAMBDA (SKETCH) (* rrb "23-Oct-85 11:17") (* returns the global region of a sketch.) (SK.GLOBAL.REGION.OF.GLOBAL.ELEMENTS (fetch (SKETCH SKETCHELTS) of (INSURE.SKETCH SKETCH]) (SK.FLASHREGION [LAMBDA (REGION WINDOW TEXTURE) (* rrb "30-Jul-85 15:47") (* flashes a region) (DSPFILL REGION TEXTURE (QUOTE INVERT) WINDOW) (DISMISS 400) (DSPFILL REGION TEXTURE (QUOTE INVERT) WINDOW]) ) (DEFINEQ (INIT.GROUP.ELEMENT [LAMBDA NIL (* rrb "18-Oct-85 17:15") (* initializes the text box element.) (COND ((NOT (SKETCH.ELEMENT.TYPEP (QUOTE GROUP))) (CREATE.SKETCH.ELEMENT.TYPE (QUOTE GROUP) NIL "groups a collection of elements as a single element." (FUNCTION GROUP.DRAWFN) (FUNCTION GROUP.EXPANDFN) (QUOTE OBSOLETE) (FUNCTION SK.ELEMENTS.CHANGEFN) (FUNCTION TEXTBOX.INPUTFN) (FUNCTION GROUP.INSIDEFN) (FUNCTION GROUP.REGIONFN) (FUNCTION GROUP.TRANSLATEFN) NIL (FUNCTION GROUP.READCHANGEFN) (FUNCTION GROUP.TRANSFORMFN) NIL (FUNCTION GROUP.GLOBALREGIONFN]) (GROUP.DRAWFN [LAMBDA (GROUPELT WINDOW REGION OPERATION) (* rrb "10-Dec-85 12:38") (* draws a group element.) (for ELT in (fetch (LOCALGROUP LOCALELEMENTS) of (fetch (SCREENELT LOCALPART) of GROUPELT)) do (APPLY* (SK.DRAWFN (fetch (SCREENELT GTYPE) of ELT)) ELT WINDOW REGION OPERATION]) (GROUP.EXPANDFN [LAMBDA (GROUPELT SCALE STREAM) (* rrb "10-Dec-85 12:37") (* creates a local group screen element from a global group element) (PROG ((GROUPINDVELT (fetch (GLOBALPART INDIVIDUALGLOBALPART) of GROUPELT)) LOCALREGION) (SETQ LOCALREGION (SCALE.REGION (fetch (GROUP GROUPREGION) of GROUPINDVELT) SCALE)) (* put the position in the center.) (RETURN (create SCREENELT LOCALPART ←(create LOCALGROUP GROUPPOSITION ←(SK.SCALE.POSITION.INTO.VIEWER (fetch (GROUP GROUPCONTROLPOINT) of GROUPINDVELT) SCALE) LOCALGROUPREGION ← LOCALREGION LOCALELEMENTS ←(for ELEMENT in (fetch (GROUP LISTOFGLOBALELTS) of GROUPINDVELT) collect ( SK.LOCAL.FROM.GLOBAL ELEMENT STREAM SCALE))) GLOBALPART ← GROUPELT]) (GROUP.INSIDEFN [LAMBDA (GROUPELT WREG) (* rrb "10-Jan-85 10:37") (* determines if the global group element GROUPELT is inside of WREG.) (REGIONSINTERSECTP (fetch (GROUP GROUPREGION) of (fetch (GLOBALPART INDIVIDUALGLOBALPART) of GROUPELT)) WREG]) (GROUP.REGIONFN [LAMBDA (GROUPSCRELT) (* rrb "10-Dec-85 12:38") (* returns the region occuppied by a group) (fetch (LOCALGROUP LOCALGROUPREGION) of (fetch (SCREENELT LOCALPART) of GROUPSCRELT]) (GROUP.GLOBALREGIONFN [LAMBDA (GGROUPELT) (* rrb "18-Oct-85 17:13") (* returns the global region occupied by a global group element.) (fetch (GROUP GROUPREGION) of (fetch (GLOBALPART INDIVIDUALGLOBALPART) of GGROUPELT]) (GROUP.TRANSLATEFN [LAMBDA (SKELT DELTAPOS) (* rrb "28-Apr-85 18:43") (* * returns a group element which has been translated by DELTAPOS) (PROG ((GGROUPELT (fetch (GLOBALPART INDIVIDUALGLOBALPART) of SKELT)) NEWREG) (SETQ NEWREG (REL.MOVE.REGION (fetch (GROUP GROUPREGION) of GGROUPELT) (fetch (POSITION XCOORD) of DELTAPOS) (fetch (POSITION YCOORD) of DELTAPOS))) (* makes a copy of the common global part because it includes the scales which may change for one of the instances.) (RETURN (create GLOBALPART COMMONGLOBALPART ←(APPEND (fetch (GLOBALPART COMMONGLOBALPART) of SKELT)) INDIVIDUALGLOBALPART ←(create GROUP GROUPREGION ← NEWREG LISTOFGLOBALELTS ←(for SUBELT in (fetch (GROUP LISTOFGLOBALELTS) of GGROUPELT) collect ( SK.TRANSLATE.GLOBALPART SUBELT DELTAPOS T)) GROUPCONTROLPOINT ←(PTPLUS (fetch (GROUP GROUPCONTROLPOINT) of GGROUPELT) DELTAPOS]) (GROUP.TRANSFORMFN [LAMBDA (GELT TRANSFORMFN TRANSFORMDATA SCALEFACTOR) (* rrb " 2-Jun-85 13:10") (* * returns a group element which has been transformed by TRANSFORMFN) (COND [(EQ TRANSFORMFN (FUNCTION SK.PUT.ON.GRID)) (* if putting things on a grid, move only the control point.) (PROG ((GGROUPELT (fetch (GLOBALPART INDIVIDUALGLOBALPART) of GELT)) NOWPOS) (SETQ NOWPOS (fetch (GROUP GROUPCONTROLPOINT) of GGROUPELT)) (RETURN (GROUP.TRANSLATEFN GELT (PTDIFFERENCE (SK.TRANSFORM.POINT NOWPOS TRANSFORMFN TRANSFORMDATA) NOWPOS] (T (PROG ((GGROUPELT (fetch (GLOBALPART INDIVIDUALGLOBALPART) of GELT)) NEWREG) (* this transforms the old region to get the new one. This is not as good as recalculating the new one from the transformed elements. The latter is hard because the region function only works on local elements and here we have only global ones.) (SETQ NEWREG (SK.TRANSFORM.REGION (fetch (GROUP GROUPREGION) of GGROUPELT) TRANSFORMFN TRANSFORMDATA)) (* the control point could also profitably be put on a grid point but no other elements points are so done and it would be hard.) (RETURN (BOX.SET.SCALES NEWREG (create GLOBALPART COMMONGLOBALPART ←(fetch (GLOBALPART COMMONGLOBALPART) of GELT) INDIVIDUALGLOBALPART ←(create GROUP GROUPREGION ← NEWREG LISTOFGLOBALELTS ←(for SUBELT in (fetch (GROUP LISTOFGLOBALELTS) of GGROUPELT) collect ( SK.TRANSFORM.ELEMENT SUBELT TRANSFORMFN TRANSFORMDATA SCALEFACTOR)) GROUPCONTROLPOINT ←( SK.TRANSFORM.POINT (fetch (GROUP GROUPCONTROLPOINT) of GGROUPELT) TRANSFORMFN TRANSFORMDATA]) (GROUP.READCHANGEFN [LAMBDA (SKW SCRNELTS) (* rrb " 6-Nov-85 09:56") (* reads how the user wants to change a textbox.) (PROG (ASPECT HOW) (SETQ HOW (SELECTQ (SETQ ASPECT (\CURSOR.IN.MIDDLE.MENU (create MENU TITLE ← "Change which part?" ITEMS ←[APPEND (COND [(SKETCHINCOLORP) (QUOTE (("Brush color" (QUOTE BRUSHCOLOR) "changes the color of any lines or text in the group.") ("Filling color" (QUOTE FILLINGCOLOR) "changes the filling color of any boxes or text boxes in the group."] (T NIL)) (QUOTE ((Arrowheads (QUOTE ARROW) "allows changing of arrow head charactistics.") (Shape (QUOTE SHAPE) "changes the shape of the brush") (Size (QUOTE SIZE) "changes the size of the lines") (Dashing (QUOTE DASHING) "changes the dashing property of the elements with lines.") (Text (QUOTE TEXT) "allows changing the properties of the text."] CENTERFLG ← T))) (TEXT (CADR (TEXT.READCHANGEFN SKW SCRNELTS T))) (SIZE (READSIZECHANGE "Change size how?")) (SHAPE (READBRUSHSHAPE)) (ARROW (READ.ARROW.CHANGE)) (DASHING (READ.DASHING.CHANGE)) (BRUSHCOLOR (READ.COLOR.CHANGE "Change line color how?")) (FILLINGCOLOR (READ.COLOR.CHANGE "Change filling color how?" T)) NIL)) (RETURN (AND HOW (LIST ASPECT HOW]) ) (DEFINEQ (REGION.CENTER [LAMBDA (REGION) (* rrb "11-Jan-85 18:22") (* returns the center of a region) (create POSITION XCOORD ←(PLUS (fetch (REGION LEFT) of REGION) (QUOTIENT (fetch (REGION WIDTH) of REGION) 2)) YCOORD ←(PLUS (fetch (REGION BOTTOM) of REGION) (QUOTIENT (fetch (REGION HEIGHT) of REGION) 2]) (REMOVE.LAST [LAMBDA (LST) (* removes the last element from a list.) (COND ((NULL (CDR LST)) NIL) (T (for TAIL on LST when (NULL (CDDR TAIL)) do (RPLACD TAIL NIL) (RETURN LST]) ) [DECLARE: EVAL@COMPILE (TYPERECORD GROUP (GROUPREGION LISTOFGLOBALELTS GROUPCONTROLPOINT)) (RECORD LOCALGROUP ((GROUPPOSITION) LOCALHOTREGION LOCALGROUPREGION LOCALELEMENTS)) ] (* history and undo stuff for groups) (DEFINEQ (SK.DO.GROUP [LAMBDA (GROUPELT GELTS SKW) (* rrb "10-Dec-85 12:38") (* does a group event. Used to undo UNGROUP too.) (PROG (LOCALELT) (for GELT in GELTS do (SK.DELETE.ELEMENT1 GELT SKW T)) (SETQ LOCALELT (SK.ADD.ELEMENT GROUPELT SKW T T)) (* flash the grouped area to let user know something happened.) (SK.FLASHREGION (fetch (LOCALGROUP LOCALGROUPREGION) of (fetch (SCREENELT LOCALPART) of LOCALELT)) SKW GRAYSHADE) (RETURN LOCALELT]) (SK.DO.UNGROUP [LAMBDA (GROUPELT GELTS SKW) (* rrb "30-Jul-85 16:22") (* does a ungroup event. Used to undo GROUP too.) (SK.DELETE.ELEMENT1 GROUPELT SKW T) (for GELT in GELTS do (SK.ADD.ELEMENT GELT SKW T T)) (SK.FLASHREGION (SCALE.REGION (fetch (GROUP GROUPREGION) of (fetch (GLOBALPART INDIVIDUALGLOBALPART) of GROUPELT)) (WINDOW.SCALE SKW)) SKW GRAYSHADE) GROUPELT]) (SK.GROUP.UNDO [LAMBDA (EVENTARGS SKW) (* rrb "10-Dec-85 17:50") (* undoes a group event) (for GRP in EVENTARGS do (SK.DO.UNGROUP (CAR GRP) (CADR GRP) SKW)) T]) (SK.UNGROUP.UNDO [LAMBDA (EVENTARGS SKW) (* rrb "10-Dec-85 17:50") (* undoes a ungroup event) (for GRP in EVENTARGS do (SK.DO.GROUP (CAR GRP) (CADR GRP) SKW)) T]) ) (PUTPROPS GROUP EVENTFNS (SK.GROUP.UNDO SK.TYPE.OF.FIRST.ARG SK.UNGROUP.UNDO)) (PUTPROPS UNGROUP EVENTFNS (SK.UNGROUP.UNDO SK.TYPE.OF.FIRST.ARG SK.GROUP.UNDO)) (* fns to implement transformations on the elements) (DEFINEQ (SK.SEL.AND.TRANSFORM [LAMBDA (W TRANSFORMFN TRANSFORMDATA) (* rrb "10-Dec-85 17:25") (* lets the user select some elements and moves all of their control points onto the grid.) (SK.TRANSFORM.ELEMENTS (SK.SELECT.MULTIPLE.ITEMS W T NIL (QUOTE MOVE)) TRANSFORMFN TRANSFORMDATA W]) (SK.TRANSFORM.ELEMENTS [LAMBDA (SCRELTS TRANSFORMFN TRANSFORMDATA SKW) (* rrb "26-Apr-85 09:08") (* changes SCRELTS to the elements that have had each of their control points transformed by transformfn. TRANSFORMDATA is arbitrary data that is passed to tranformfn.) (PROG (NEWGLOBALS) (* computes the scale factor inherent in the transformation so that it doesn't have to be done on every element that might need it. It major use is in scaling brush sizes.) (SETQ NEWGLOBALS (MAPCOLLECTSKETCHSPECS SCRELTS (FUNCTION SK.TRANSFORM.ITEM) TRANSFORMFN TRANSFORMDATA ( SK.TRANSFORM.SCALE.FACTOR TRANSFORMFN TRANSFORMDATA) SKW)) (* make a history entry.) (SK.ADD.HISTEVENT (QUOTE MOVE) (for NEWG in NEWGLOBALS as OLDG in SCRELTS when NEWG collect (LIST (fetch (SCREENELT GLOBALPART) of OLDG) NEWG)) SKW) (RETURN NEWGLOBALS]) (SK.TRANSFORM.ITEM [LAMBDA (SELELT TRANSFORMFN TRANSFORMDATA SCALEFACTOR W) (* rrb "26-Apr-85 09:09") (* SELELT is a sketch element that was selected for a transformation operation.) (PROG (NEWGLOBAL OLDGLOBAL) (COND ((SETQ NEWGLOBAL (SK.TRANSFORM.ELEMENT (SETQ OLDGLOBAL (fetch (SCREENELT GLOBALPART) of SELELT)) TRANSFORMFN TRANSFORMDATA SCALEFACTOR)) (SK.UPDATE.ELEMENT OLDGLOBAL NEWGLOBAL W T) (RETURN NEWGLOBAL]) (SK.TRANSFORM.ELEMENT [LAMBDA (GELT TRANSFORMFN TRANSFORMDATA SCALEFACTOR) (* rrb "26-Apr-85 09:14") (* returns a copy of the global element that has had each of its control points transformed by transformfn. TRANSFORMDATA is arbitrary data that is passed to tranformfn.) (APPLY* (SK.TRANSFORMFN (fetch (GLOBALPART GTYPE) of GELT)) GELT TRANSFORMFN TRANSFORMDATA SCALEFACTOR]) (SK.TRANSFORM.POINT [LAMBDA (PT TRANSFORMFN TRANSFORMDATA) (* applies a transformation function to a position and returns the transformed point.) (APPLY* TRANSFORMFN PT TRANSFORMDATA]) (SK.TRANSFORM.POINT.LIST [LAMBDA (PTLST TRANSFORMFN TRANSFORMDATA) (* transforms a list of points) (for PT in PTLST collect (SK.TRANSFORM.POINT PT TRANSFORMFN TRANSFORMDATA]) (SK.TRANSFORM.REGION [LAMBDA (REG TRANSFORMFN TRANSFORMDATA) (* rrb "31-May-85 10:42") (* applies a transformation function to a region and returns the transformed region) (PROG (LOWERLEFT UPPERRIGHT) (* transform the font by changing the scale according to how much the width of the box around the first line of text changes from the transformation.) (SETQ LOWERLEFT (SK.TRANSFORM.POINT (create POSITION XCOORD ←(fetch (REGION LEFT) of REG) YCOORD ←(fetch (REGION BOTTOM) of REG)) TRANSFORMFN TRANSFORMDATA)) (SETQ UPPERRIGHT (SK.TRANSFORM.POINT (create POSITION XCOORD ←(fetch (REGION PRIGHT) of REG) YCOORD ←(fetch (REGION PTOP) of REG)) TRANSFORMFN TRANSFORMDATA)) (* transformation may have changed the relative positions of the upper right and lower left.) (RETURN (CREATEREGION (MIN (fetch (POSITION XCOORD) of LOWERLEFT) (fetch (POSITION XCOORD) of UPPERRIGHT)) (MIN (fetch (POSITION YCOORD) of LOWERLEFT) (fetch (POSITION YCOORD) of UPPERRIGHT)) (ABS (DIFFERENCE (fetch (POSITION XCOORD) of UPPERRIGHT) (fetch (POSITION XCOORD) of LOWERLEFT))) (ABS (DIFFERENCE (fetch (POSITION YCOORD) of UPPERRIGHT) (fetch (POSITION YCOORD) of LOWERLEFT]) (SK.PUT.ELTS.ON.GRID [LAMBDA (W) (* rrb " 7-Feb-85 12:03") (* lets the user select some elements and moves all of their control points onto the grid.) (EVAL.AS.PROCESS (LIST (FUNCTION SK.SEL.AND.TRANSFORM) (KWOTE W) (KWOTE (FUNCTION SK.PUT.ON.GRID)) (KWOTE (SK.GRIDFACTOR W]) (SK.TRANSFORM.GLOBAL.ELEMENTS [LAMBDA (SCRELTS TRANSFORMFN TRANSFORMDATA) (* rrb "29-Apr-85 12:57") (* returns a copy of the global elements that have had each of its control points transformed by transformfn. TRANSFORMDATA is arbitrary data that is passed to tranformfn.) (MAPGLOBALSKETCHSPECS SCRELTS (FUNCTION SK.TRANSFORM.ELEMENT) TRANSFORMFN TRANSFORMDATA (SK.TRANSFORM.SCALE.FACTOR TRANSFORMFN TRANSFORMDATA]) (GLOBALELEMENTP [LAMBDA (ELT?) (* rrb "19-Oct-85 17:35") (* * returns ELT? if it is a global sketch element.) (AND (SKETCH.ELEMENT.NAMEP (fetch (GLOBALPART GTYPE) of (LISTP ELT?))) ELT?]) (SK.TRANSFORM.SCALE.FACTOR [LAMBDA (TRANSFORMFN TRANSFORMDATA) (* rrb "29-Apr-85 12:09") (* calculates scaling factor based on the transform of points. Since the transform is arbitrary in x and y scaling, this can't really do the right thing so it computes the area a unit square would have after transformation and uses that.) (COND ((EQ TRANSFORMFN (FUNCTION SK.PUT.ON.GRID)) (* test for specially in case grid is larger than unit. Don't change the scale.) 1.0) (T (PROG ((ORG (SK.TRANSFORM.POINT (CONSTANT (create POSITION XCOORD ← 0 YCOORD ← 0)) TRANSFORMFN TRANSFORMDATA)) (YUNIT (SK.TRANSFORM.POINT (CONSTANT (create POSITION XCOORD ← 0 YCOORD ← 1)) TRANSFORMFN TRANSFORMDATA)) (XUNIT (SK.TRANSFORM.POINT (CONSTANT (create POSITION XCOORD ← 1 YCOORD ← 0)) TRANSFORMFN TRANSFORMDATA))) (RETURN (SQRT (TIMES (DISTANCEBETWEEN YUNIT ORG) (DISTANCEBETWEEN XUNIT ORG]) (SK.TRANSFORM.BRUSH [LAMBDA (BRUSH SCALEFACTOR) (* rrb "26-Apr-85 09:34") (* returns a brush scaled from size ORGSCALE to NEWSCALE.) (create BRUSH using BRUSH BRUSHSIZE ←(TIMES (fetch (BRUSH BRUSHSIZE) of BRUSH) SCALEFACTOR]) (SK.TRANSFORM.ARROWHEADS [LAMBDA (ARROWHEADS SCALEFACTOR) (* rrb "26-Sep-85 12:17") (* returns a arrowhead specification scaled by SCALEFACTOR) (AND ARROWHEADS (LIST (AND (CAR ARROWHEADS) (create ARROWHEAD using (CAR ARROWHEADS) ARROWLENGTH ← (TIMES (fetch (ARROWHEAD ARROWLENGTH) of (CAR ARROWHEADS)) SCALEFACTOR))) (AND (CADR ARROWHEADS) (create ARROWHEAD using (CADR ARROWHEADS) ARROWLENGTH ← (TIMES (fetch (ARROWHEAD ARROWLENGTH) of (CADR ARROWHEADS)) SCALEFACTOR))) (CADDR ARROWHEADS]) (SCALE.BRUSH [LAMBDA (BRUSH ORGSCALE NEWSCALE) (* rrb "29-Apr-85 11:53") (* returns a brush scaled from size ORGSCALE to NEWSCALE. It will returns a size of 0 only if given a size of 0 This is so that brushes that scale down always show up.) (PROG ((BRUSHSIZE (FQUOTIENT (FTIMES (fetch (BRUSH BRUSHSIZE) of BRUSH) ORGSCALE) NEWSCALE))) (RETURN (create BRUSH using BRUSH BRUSHSIZE ←(COND ((ZEROP BRUSHSIZE) 0) (T (IMAX 1 (FIXR BRUSHSIZE]) ) (DEFINEQ (TWO.PT.TRANSFORMATION.INPUTFN [LAMBDA (WINDOW) (* rrb "19-Jul-85 10:35") (* reads four points from the user and returns the two point transformation that maps the first two into the second two.) (PROG ((SCALE (WINDOW.SCALE WINDOW)) FIRSTPT SECONDPT THIRDPT FOURTHPT FIRSTLOCALPT SECONDLOCALPT THIRDLOCALPT FOURTHLOCALPT) (STATUSPRINT WINDOW " " "Indicate the first point to move.") (COND ((SETQ FIRSTPT (SK.GETGLOBALPOSITION WINDOW)) (SK.MARK.POSITION (SETQ FIRSTLOCALPT (SCALE.POSITION FIRSTPT SCALE)) WINDOW FIRSTPTMARK)) (T (CLOSEPROMPTWINDOW WINDOW) (RETURN NIL))) (STATUSPRINT WINDOW " " "Indicate the second point to move.") (COND ((SETQ SECONDPT (SK.GETGLOBALPOSITION WINDOW)) (SK.MARK.POSITION (SETQ SECONDLOCALPT (SCALE.POSITION SECONDPT SCALE)) WINDOW SECONDPTMARK)) (T (* erase first pt on way out) (SK.MARK.POSITION FIRSTLOCALPT WINDOW FIRSTPTMARK) (CLOSEPROMPTWINDOW WINDOW) (RETURN NIL))) (STATUSPRINT WINDOW " " "Indicate the new position of the first point.") (COND ((SETQ THIRDPT (SK.GETGLOBALPOSITION WINDOW)) (SK.MARK.POSITION (SETQ THIRDLOCALPT (SCALE.POSITION THIRDPT SCALE)) WINDOW NEWFIRSTPTMARK)) (T (* erase first and second pts on way out) (SK.MARK.POSITION FIRSTLOCALPT WINDOW FIRSTPTMARK) (SK.MARK.POSITION SECONDLOCALPT WINDOW SECONDPTMARK) (CLOSEPROMPTWINDOW WINDOW) (RETURN NIL))) (STATUSPRINT WINDOW " " "Indicate the new position of the second point.") (SETQ FOURTHPT (SK.GETGLOBALPOSITION WINDOW)) (CLOSEPROMPTWINDOW WINDOW) (* erase the point marks.) (SK.MARK.POSITION FIRSTLOCALPT WINDOW FIRSTPTMARK) (SK.MARK.POSITION SECONDLOCALPT WINDOW SECONDPTMARK) (SK.MARK.POSITION THIRDLOCALPT WINDOW NEWFIRSTPTMARK) (OR FOURTHPT (RETURN NIL)) (* keep the coefficients of the two necessary equations.) (RETURN (SK.COMPUTE.TWO.PT.TRANSFORMATION FIRSTPT SECONDPT THIRDPT FOURTHPT]) (SK.TWO.PT.TRANSFORM.ELTS [LAMBDA (W) (* rrb "21-Apr-85 16:00") (* lets the user select some elements and specify a two point transformation and applies the transformation to all of the points.) (EVAL.AS.PROCESS (LIST (FUNCTION SK.SEL.AND.TWO.PT.TRANSFORM) (KWOTE W]) (SK.SEL.AND.TWO.PT.TRANSFORM [LAMBDA (W) (* rrb "10-Dec-85 17:26") (* lets the user select some elements and specify a two point transformation and applies the transformation to all of the points.) (PROG NIL (SK.TRANSFORM.ELEMENTS (OR (SK.SELECT.MULTIPLE.ITEMS W T NIL (QUOTE MOVE)) (RETURN)) (FUNCTION SK.APPLY.AFFINE.TRANSFORM) (OR (TWO.PT.TRANSFORMATION.INPUTFN W) (RETURN)) W]) (SK.APPLY.AFFINE.TRANSFORM [LAMBDA (GPOSITION AFFINETRANS) (* rrb "28-Apr-85 16:05") (* * applies a tranformation to the point. AFFINETRANS is an instance of AFFINETRANSFORMATION) (create POSITION XCOORD ←(PLUS (TIMES (fetch Ax of AFFINETRANS) (fetch (POSITION XCOORD) of GPOSITION)) (TIMES (fetch By of AFFINETRANS) (fetch (POSITION YCOORD) of GPOSITION)) (fetch C of AFFINETRANS)) YCOORD ←(PLUS (TIMES (fetch Dx of AFFINETRANS) (fetch (POSITION XCOORD) of GPOSITION)) (TIMES (fetch Ey of AFFINETRANS) (fetch (POSITION YCOORD) of GPOSITION)) (fetch F of AFFINETRANS]) (SK.COMPUTE.TWO.PT.TRANSFORMATION [LAMBDA (P1 P2 Q1 Q2) (* rrb "14-Oct-85 18:09") (* computes the AFFINETRANSFORMATION necessary to take P1 into Q1 and P2 into Q2.) (PROG ((PX1 (fetch (POSITION XCOORD) of P1)) (PY1 (fetch (POSITION YCOORD) of P1)) (PX2 (fetch (POSITION XCOORD) of P2)) (PY2 (fetch (POSITION YCOORD) of P2)) (QX1 (fetch (POSITION XCOORD) of Q1)) (QY1 (fetch (POSITION YCOORD) of Q1)) (QX2 (fetch (POSITION XCOORD) of Q2)) (QY2 (fetch (POSITION YCOORD) of Q2)) (MATRIX2 (CREATE3BY3)) (SCRATCHMATRIX) MATRIX1 PDELTAX PDELTAY QDELTAX QDELTAY PLEN QLEN LENRATIO) (* compute the transformation that translates P1 to the origin, rotates it until P has the same angle as Q, scales it until P has the same length as Q then translates the new P1 to Q1.) (SETQ PDELTAX (DIFFERENCE PX2 PX1)) (SETQ PDELTAY (DIFFERENCE PY2 PY1)) (SETQ QDELTAX (DIFFERENCE QX2 QX1)) (SETQ QDELTAY (DIFFERENCE QY2 QY1)) (* compute the length of segments P and Q.) [SETQ PLEN (SQRT (PLUS (TIMES PDELTAX PDELTAX) (TIMES PDELTAY PDELTAY] (COND ((ZEROP PLEN) (STATUSPRINT WINDOW " " "The two source points can not be the same.") (RETURN))) [SETQ QLEN (SQRT (PLUS (TIMES QDELTAX QDELTAX) (TIMES QDELTAY QDELTAY] (COND ((ZEROP QLEN) (STATUSPRINT WINDOW "The two destination points can not be the same.") (RETURN))) (* ratio is done to map P onto Q because the scaling is done after the rotation. It could be done first if the mapping were done from Q onto P.) (SETQ LENRATIO (QUOTIENT QLEN PLEN)) (* translate P1 to origin.) (* use MATRIX1 and MATRIX2 to swap the running result back and forth since matrix multiplication routines don't allow the result to be stored in one of the arguments.) (SETQ MATRIX1 (TRANSLATE3BY3 (MINUS PX1) (MINUS PY1))) (* Scale to make P the same length as Q.) (MATMULT333 MATRIX1 (SCALE3BY3 LENRATIO LENRATIO SCRATCHMATRIX) MATRIX2) (* rotate it so that the slope of P is the same as Q.) (MATMULT333 MATRIX2 (ROTATE3BY3 (DIFFERENCE (SK.COMPUTE.SLOPE PDELTAX PDELTAY) (SK.COMPUTE.SLOPE QDELTAX QDELTAY)) SCRATCHMATRIX NIL) MATRIX1) (* translate the origin pt to Q1. This is complicated because Q1 needs to be translated, rotated and scaled into new coordinates.) (MATMULT333 MATRIX1 (TRANSLATE3BY3 QX1 QY1 SCRATCHMATRIX) MATRIX2) (* return only the coefficients that make a difference.) (RETURN (create AFFINETRANSFORMATION Ax ←(AREF MATRIX2 0 0) By ←(AREF MATRIX2 1 0) C ←(AREF MATRIX2 2 0) Dx ←(AREF MATRIX2 0 1) Ey ←(AREF MATRIX2 1 1) F ←(AREF MATRIX2 2 1]) (SK.COMPUTE.SLOPE [LAMBDA (DELTAX DELTAY) (* rrb "31-May-85 10:09") (* computes the angle of a line from the delta X and Y.) (COND ((ZEROP DELTAX) (COND ((GREATERP DELTAY 0) 90.0) (T -90.0))) (T (PLUS (COND ((GREATERP DELTAX 0) 0.0) (T (* if the line is sloping to the left, add 180 to it. This is done because we need to make sure that P1 gets mapped into Q1.) 180.0)) (ARCTAN (FQUOTIENT DELTAY DELTAX]) (SK.THREE.PT.TRANSFORM.ELTS [LAMBDA (W) (* rrb "28-Apr-85 16:55") (* lets the user select some elements and specify a three point transformation and applies the transformation to all of the points.) (EVAL.AS.PROCESS (LIST (FUNCTION SK.SEL.AND.THREE.PT.TRANSFORM) (KWOTE W]) (SK.COMPUTE.THREE.PT.TRANSFORMATION [LAMBDA (P1 P2 P3 Q1 Q2 Q3 ERRORFLG) (* rrb " 8-May-85 18:10") (* computes the AFFINETRANSFORMATION necessary to take P1 into Q1, P2 into Q2 and P3 into Q3.) (PROG ((PX1 (fetch (POSITION XCOORD) of P1)) (PY1 (fetch (POSITION YCOORD) of P1)) (PX2 (fetch (POSITION XCOORD) of P2)) (PY2 (fetch (POSITION YCOORD) of P2)) (PX3 (fetch (POSITION XCOORD) of P3)) (PY3 (fetch (POSITION YCOORD) of P3)) (QX1 (fetch (POSITION XCOORD) of Q1)) (QY1 (fetch (POSITION YCOORD) of Q1)) (QX2 (fetch (POSITION XCOORD) of Q2)) (QY2 (fetch (POSITION YCOORD) of Q2)) (QX3 (fetch (POSITION XCOORD) of Q3)) (QY3 (fetch (POSITION YCOORD) of Q3)) DELTAPY12 DELTAPX12 DELTAPY23 A&DBOTTOM AX BY C DX EY F) (* this is the computation dictated by solving the six equations of the form QX1 = aPX1 + bPY1 + c for a, b, c, d, e, and f.) (* save some subexpressions that are reused.) (SETQ DELTAPX12 (FDIFFERENCE PX1 PX2)) (SETQ DELTAPY23 (FDIFFERENCE PY2 PY3)) [COND ((ZEROP (SETQ DELTAPY12 (FDIFFERENCE PY1 PY2))) (* need to divide by this number and it is zero) (COND (ERRORFLG (* this is the second attempt, all points must be horizontal) (STATUSPRINT WINDOW " " "All three source points cannot be in the same line. If you meant this, you should use the TWO PT TRANSFORM.") (RETURN)) (T (* try switching two points) (RETURN (SK.COMPUTE.THREE.PT.TRANSFORMATION P2 P3 P1 Q2 Q3 Q1 T] [COND ([ZEROP (SETQ A&DBOTTOM (FDIFFERENCE (FDIFFERENCE PX2 PX3) (FTIMES (FQUOTIENT DELTAPX12 DELTAPY12) DELTAPY23] (* need to divide by this number and it is zero) (COND (ERRORFLG (* this is the second attempt, maybe all points are collinear, in any case, can't continue.) (STATUSPRINT WINDOW " " "All three source points cannot be in the same line. If you meant this, you should use the TWO PT TRANSFORM.") (RETURN)) (T (* try switching two points) (RETURN (SK.COMPUTE.THREE.PT.TRANSFORMATION P2 P3 P1 Q2 Q3 Q1 T] (SETQ AX (FQUOTIENT (FDIFFERENCE (FDIFFERENCE QX2 QX3) (FQUOTIENT (FTIMES (FDIFFERENCE QX1 QX2) DELTAPY23) DELTAPY12)) A&DBOTTOM)) (SETQ DX (FQUOTIENT (FDIFFERENCE (FDIFFERENCE QY2 QY3) (FQUOTIENT (FTIMES (FDIFFERENCE QY1 QY2) DELTAPY23) DELTAPY12)) A&DBOTTOM)) (SETQ BY (FQUOTIENT (FDIFFERENCE (FDIFFERENCE QX1 QX2) (FTIMES AX DELTAPX12)) DELTAPY12)) (SETQ EY (FQUOTIENT (FDIFFERENCE (FDIFFERENCE QY1 QY2) (FTIMES DX DELTAPX12)) DELTAPY12)) [SETQ C (FDIFFERENCE QX1 (FPLUS (FTIMES AX PX1) (FTIMES BY PY1] [SETQ F (FDIFFERENCE QY1 (FPLUS (FTIMES DX PX1) (FTIMES EY PY1] (RETURN (create AFFINETRANSFORMATION Ax ← AX By ← BY C ← C Dx ← DX Ey ← EY F ← F]) (SK.SEL.AND.THREE.PT.TRANSFORM [LAMBDA (W) (* rrb "10-Dec-85 17:26") (* lets the user select some elements and specify a three point transformation and applies the transformation to all of the points.) (PROG NIL (SK.TRANSFORM.ELEMENTS (OR (SK.SELECT.MULTIPLE.ITEMS W T NIL (QUOTE MOVE)) (RETURN)) (FUNCTION SK.APPLY.AFFINE.TRANSFORM) (OR (THREE.PT.TRANSFORMATION.INPUTFN W) (RETURN)) W]) (THREE.PT.TRANSFORMATION.INPUTFN [LAMBDA (WINDOW) (* rrb "28-Apr-85 16:53") (* reads six points from the user and returns the affine transformation that maps the first three into the second three) (PROG ((SCALE (WINDOW.SCALE WINDOW)) FIRSTPT SECONDPT THIRDPT FOURTHPT FIFTHPT SIXTHPT FIRSTLOCALPT SECONDLOCALPT THIRDLOCALPT FOURTHLOCALPT FIFTHLOCALPT) (STATUSPRINT WINDOW " " "Indicate the first point to move.") (COND ((SETQ FIRSTPT (SK.GETGLOBALPOSITION WINDOW)) (SK.MARK.POSITION (SETQ FIRSTLOCALPT (SCALE.POSITION FIRSTPT SCALE)) WINDOW FIRSTPTMARK)) (T (CLOSEPROMPTWINDOW WINDOW) (RETURN NIL))) (STATUSPRINT WINDOW " " "Indicate the second point to move.") (COND ((SETQ SECONDPT (SK.GETGLOBALPOSITION WINDOW)) (SK.MARK.POSITION (SETQ SECONDLOCALPT (SCALE.POSITION SECONDPT SCALE)) WINDOW SECONDPTMARK)) (T (* erase first pt on way out) (SK.MARK.POSITION FIRSTLOCALPT WINDOW FIRSTPTMARK) (CLOSEPROMPTWINDOW WINDOW) (RETURN NIL))) (STATUSPRINT WINDOW " " "Indicate the third point to move.") (COND ((SETQ THIRDPT (SK.GETGLOBALPOSITION WINDOW)) (SK.MARK.POSITION (SETQ THIRDLOCALPT (SCALE.POSITION THIRDPT SCALE)) WINDOW THIRDPTMARK)) (T (* erase first and second pts on way out) (SK.MARK.POSITION FIRSTLOCALPT WINDOW FIRSTPTMARK) (SK.MARK.POSITION SECONDLOCALPT WINDOW SECONDPTMARK) (CLOSEPROMPTWINDOW WINDOW) (RETURN NIL))) (STATUSPRINT WINDOW " " "Indicate the new position of the first point.") (COND ((SETQ FOURTHPT (SK.GETGLOBALPOSITION WINDOW)) (SK.MARK.POSITION (SETQ FOURTHLOCALPT (SCALE.POSITION FOURTHPT SCALE)) WINDOW NEWFIRSTPTMARK)) (T (* erase first second and third pts on way out) (SK.MARK.POSITION FIRSTLOCALPT WINDOW FIRSTPTMARK) (SK.MARK.POSITION SECONDLOCALPT WINDOW SECONDPTMARK) (SK.MARK.POSITION THIRDLOCALPT WINDOW THIRDPTMARK) (CLOSEPROMPTWINDOW WINDOW) (RETURN NIL))) (STATUSPRINT WINDOW " " "Indicate the new position of the second point.") (COND ((SETQ FIFTHPT (SK.GETGLOBALPOSITION WINDOW)) (SK.MARK.POSITION (SETQ FIFTHLOCALPT (SCALE.POSITION FIFTHPT SCALE)) WINDOW NEWSECONDPTMARK)) (T (* erase first second and third pts on way out) (SK.MARK.POSITION FIRSTLOCALPT WINDOW FIRSTPTMARK) (SK.MARK.POSITION SECONDLOCALPT WINDOW SECONDPTMARK) (SK.MARK.POSITION THIRDLOCALPT WINDOW THIRDPTMARK) (SK.MARK.POSITION FOURTHLOCALPT WINDOW NEWFIRSTPTMARK) (CLOSEPROMPTWINDOW WINDOW) (RETURN NIL))) (STATUSPRINT WINDOW " " "Indicate the new position of the third point.") (SETQ SIXTHPT (SK.GETGLOBALPOSITION WINDOW)) (CLOSEPROMPTWINDOW WINDOW) (* erase the point marks.) (SK.MARK.POSITION FIRSTLOCALPT WINDOW FIRSTPTMARK) (SK.MARK.POSITION SECONDLOCALPT WINDOW SECONDPTMARK) (SK.MARK.POSITION THIRDLOCALPT WINDOW THIRDPTMARK) (SK.MARK.POSITION FOURTHLOCALPT WINDOW NEWFIRSTPTMARK) (SK.MARK.POSITION FIFTHLOCALPT WINDOW NEWSECONDPTMARK) (OR SIXTHPT (RETURN NIL)) (* keep the coefficients of the two necessary equations.) (RETURN (SK.COMPUTE.THREE.PT.TRANSFORMATION FIRSTPT SECONDPT THIRDPT FOURTHPT FIFTHPT SIXTHPT]) ) (DEFINEQ (SK.COPY.AND.TWO.PT.TRANSFORM.ELTS [LAMBDA (W) (* rrb " 8-May-85 17:24") (* lets the user select some elements and specify a two point transformation and applies the transformation to all of the points.) (EVAL.AS.PROCESS (LIST (FUNCTION SK.SEL.COPY.AND.TWO.PT.TRANSFORM) (KWOTE W]) (SK.SEL.COPY.AND.TWO.PT.TRANSFORM [LAMBDA (W) (* rrb "10-Dec-85 17:26") (* lets the user select some elements and specify a two point transformation and applies the transformation to all copies of the points.) (PROG NIL (SK.COPY.AND.TRANSFORM.ELEMENTS (OR (SK.SELECT.MULTIPLE.ITEMS W T NIL (QUOTE COPY)) (RETURN)) (FUNCTION SK.APPLY.AFFINE.TRANSFORM) (OR (TWO.PT.TRANSFORMATION.INPUTFN W) (RETURN)) W]) (SK.COPY.AND.THREE.PT.TRANSFORM.ELTS [LAMBDA (W) (* rrb " 8-May-85 17:34") (* lets the user select some elements and specify a three point transformation and applies the transformation to copies of the elements) (EVAL.AS.PROCESS (LIST (FUNCTION SK.SEL.COPY.AND.THREE.PT.TRANSFORM) (KWOTE W]) (SK.SEL.COPY.AND.THREE.PT.TRANSFORM [LAMBDA (W) (* rrb "10-Dec-85 17:26") (* lets the user select some elements and specify a three point transformation and applies the transformation to copies of the elements) (PROG NIL (SK.COPY.AND.TRANSFORM.ELEMENTS (OR (SK.SELECT.MULTIPLE.ITEMS W T NIL (QUOTE COPY)) (RETURN)) (FUNCTION SK.APPLY.AFFINE.TRANSFORM) (OR (THREE.PT.TRANSFORMATION.INPUTFN W) (RETURN)) W]) (SK.COPY.AND.TRANSFORM.ELEMENTS [LAMBDA (SCRELTS TRANSFORMFN TRANSFORMDATA SKW) (* rrb " 8-May-85 17:08") (* changes copies of SCRELTS to the elements that have had each of their control points transformed by transformfn. TRANSFORMDATA is arbitrary data that is passed to tranformfn.) (PROG (NEWGLOBALS) (* computes the scale factor inherent in the transformation so that it doesn't have to be done on every element that might need it. It major use is in scaling brush sizes.) (SETQ NEWGLOBALS (MAPCOLLECTSKETCHSPECS SCRELTS (FUNCTION SK.COPY.AND.TRANSFORM.ITEM) TRANSFORMFN TRANSFORMDATA ( SK.TRANSFORM.SCALE.FACTOR TRANSFORMFN TRANSFORMDATA) SKW)) (* make a history entry.) (SK.ADD.HISTEVENT (QUOTE COPY) NEWGLOBALS SKW) (RETURN NEWGLOBALS]) (SK.COPY.AND.TRANSFORM.ITEM [LAMBDA (SELELT TRANSFORMFN TRANSFORMDATA SCALEFACTOR W) (* rrb " 8-May-85 17:02") (* SELELT is a sketch element that was selected for a copy and transformation operation.) (PROG (NEWGLOBAL) (COND ((SETQ NEWGLOBAL (SK.TRANSFORM.ELEMENT (fetch (SCREENELT GLOBALPART) of SELELT) TRANSFORMFN TRANSFORMDATA SCALEFACTOR)) (SK.ADD.ELEMENT NEWGLOBAL W) (RETURN NEWGLOBAL]) ) (DECLARE: DONTCOPY [DECLARE: EVAL@COMPILE (RECORD AFFINETRANSFORMATION (Ax By C Dx Ey F)) ] ) (READVARS FIRSTPTMARK SECONDPTMARK THIRDPTMARK NEWFIRSTPTMARK NEWSECONDPTMARK) ({(READBITMAP)(25 25 "AOCNB@@@" "AA@HF@@@" "AA@HB@@@" "AN@HB@@@" "A@@HB@@@" "A@@HB@@@" "A@@HOH@@" "@@@@@@@@" "@@@@@@@@" "@@@H@@@@" "@@@H@@@@" "@@@H@@@@" "@@GO@@@@" "@@@H@@@@" "@@@H@@@@" "@@@H@@@@" "@@@@@@@@" "@@@@@@@@" "@@@@@@@@" "@@@@@@@@" "@@@@@@@@" "@@@@@@@@" "@@@@@@@@" "@@@@@@@@" "@@@@@@@@")} {(READBITMAP)(25 25 "AOCNG@@@" "AA@HHH@@" "AA@HAH@@" "AN@HG@@@" "A@@HL@@@" "A@@HH@@@" "A@@HOH@@" "@@@@@@@@" "@@@@@@@@" "@@@H@@@@" "@@@H@@@@" "@@@H@@@@" "@@GO@@@@" "@@@H@@@@" "@@@H@@@@" "@@@H@@@@" "@@@@@@@@" "@@@@@@@@" "@@@@@@@@" "@@@@@@@@" "@@@@@@@@" "@@@@@@@@" "@@@@@@@@" "@@@@@@@@" "@@@@@@@@")} {(READBITMAP)(25 25 "AOCNG@@@" "AA@HHH@@" "AA@HAH@@" "AN@HF@@@" "A@@HAH@@" "A@@HHH@@" "A@@HG@@@" "@@@@@@@@" "@@@@@@@@" "@@@H@@@@" "@@@H@@@@" "@@@H@@@@" "@@GO@@@@" "@@@H@@@@" "@@@H@@@@" "@@@H@@@@" "@@@@@@@@" "@@@@@@@@" "@@@@@@@@" "@@@@@@@@" "@@@@@@@@" "@@@@@@@@" "@@@@@@@@" "@@@@@@@@" "@@@@@@@@")} {(READBITMAP)(25 25 "AAGJB@@@" "AIDBJ@@@" "AEDBJ@@@" "AEGBJ@@@" "ACDBJ@@@" "ACDBJ@@@" "AAGID@@@" "@@@@@@@@" "@@@@@@@@" "@@@H@@@@" "@@@H@@@@" "@@@H@@@@" "@@GO@@@@" "@@@H@@@@" "@@@H@@@@" "@@@H@@@@" "@@@@@@@@" "@@@@@@@@" "AOCNB@@@" "AA@HF@@@" "AA@HB@@@" "AN@HB@@@" "A@@HB@@@" "A@@HB@@@" "A@@HOH@@")} {(READBITMAP)(25 25 "AAGJB@@@" "AIDBJ@@@" "AEDBJ@@@" "AEGBJ@@@" "ACDBJ@@@" "ACDBJ@@@" "AAGID@@@" "@@@@@@@@" "@@@@@@@@" "@@@H@@@@" "@@@H@@@@" "@@@H@@@@" "@@GO@@@@" "@@@H@@@@" "@@@H@@@@" "@@@H@@@@" "@@@@@@@@" "@@@@@@@@" "AOCNCH@@" "AA@HDD@@" "AA@H@D@@" "AN@HAH@@" "A@@HF@@@" "A@@HD@@@" "A@@HGL@@")}) (DECLARE: DOEVAL@COMPILE DONTCOPY (GLOBALVARS FIRSTPTMARK SECONDPTMARK THIRDPTMARK NEWFIRSTPTMARK NEWSECONDPTMARK) ) (COND ((EQ MAKESYSNAME (QUOTE INTERMEZZO)) (FILESLOAD MATRIXUSE)) (T (FILESLOAD MATMULT))) (* programmer interface entries) (DEFINEQ (SKETCH.ELEMENTS.OF.SKETCH [LAMBDA (SKETCH) (* rrb " 2-Aug-85 16:21") (* Returns the list of elements that are in SKETCH. SKETCH can be either a SKETCH structure, a sketch window (sometimes called a viewer) or a SKETCH stream (obtained via (OPENIMAGESTREAM (QUOTE name) (QUOTE SKETCH)). If SKETCH is not a sketch, a sketch window or a sketch stream, it returns NIL. This can be used with sketch streams to determine the elements created by a call to a display function or series of functions by looking at the list differences; new elements are always added at the end.)) (fetch (SKETCH SKETCHELTS) of (INSURE.SKETCH SKETCH T]) (SKETCH.LIST.OF.ELEMENTS [LAMBDA (SKETCH PREDICATE INSIDEGROUPSFLG) (* rrb "14-Aug-85 16:26") (* Returns a list of the sketch elements in SKETCH that satisfy PREDICATE. If INSIDEGROUPSFLG is T, elements that are members of a group will be considered too. Otherwise only top level objects are considered. Note: PREDICATE will be applied to GROUP elements even when INSIDEGROUPSFLG is T.) (* FOR NOW, IGNORE INSIDEGROUPSFLG) (for ELT in (SKETCH.ELEMENTS.OF.SKETCH SKETCH) when (APPLY* PREDICATE ELT) collect ELT]) (SKETCH.ADD.ELEMENT [LAMBDA (ELEMENT SKETCH NODISPLAYFLG) (* rrb " 9-Dec-85 14:36") (* Adds an element to a sketch. If NODISPLAYFLG is NIL, any windows currently displaying SKETCH will be updated to reflect ELEMENT's addition. If NODISPLAYFLG is T, the displays won't be updated.) (PROG [(SKSTRUC (COND ((NULL SKETCH) (SKETCH.CREATE NIL)) (T (INSURE.SKETCH SKETCH] (COND ((NULL ELEMENT) (RETURN SKSTRUC)) ((NOT (GLOBALELEMENTP ELEMENT)) (ERROR ELEMENT "is not a sketch element."))) (* add the element to the sketch.) (ADD.ELEMENT.TO.SKETCH ELEMENT SKSTRUC) (* propagate to the viewers.) (for SKW in (ALL.SKETCH.VIEWERS SKSTRUC) when (ELT.INSIDE.SKETCHWP ELEMENT SKW) do (SKETCH.ADD.AND.DISPLAY1 ELEMENT SKW NODISPLAYFLG)) (RETURN SKSTRUC]) (SKETCH.DELETE.ELEMENT [LAMBDA (ELEMENT SKETCH INSIDEGROUPSFLG NODISPLAYFLG) (* rrb "19-Oct-85 17:09") (* Deletes an element from a sketch. If INSIDEGROUPSFLG is T, the element will be deleted even if it is inside a group. Otherwise it will be deleted only if it is on the top level. If NODISPLAYFLG is NIL, any windows currently displaying SKETCH will be updated to reflect ELEMENT's deletion. If NODISPLAYFLG is T, the displays won't be updated. It returns ELEMENT if ELEMENT was deleted.) (PROG ((SKSTRUC (INSURE.SKETCH SKETCH)) LOCALELT OLDGELT) (* delete the element to the sketch.) (COND ((EQ T (SETQ OLDGELT (REMOVE.ELEMENT.FROM.SKETCH ELEMENT SKSTRUC INSIDEGROUPSFLG)) ) (* element deleted was top level.) ) (OLDGELT (* element deleted was part of a group.) (printout PROMPTWINDOW T "member of group deleted but group not redrawn.")) (T (RETURN NIL))) (* propagate to the viewers.) (for SKW in (ALL.SKETCH.VIEWERS SKSTRUC) when (SETQ LOCALELT ( SK.LOCAL.ELT.FROM.GLOBALPART ELEMENT SKW)) do (SK.ERASE.AND.DELETE.ITEM LOCALELT SKW NODISPLAYFLG)) (SK.CHECK.IMAGEOBJ.WHENDELETEDFN ELEMENT SKETCH) (RETURN OLDGELT]) (DELFROMGROUPELT [LAMBDA (ELTTODEL GROUPELT) (* rrb " 2-Aug-85 17:03") (* if ELTTODEL is a member of GROUPELT, this deletes it.) (AND (EQ (fetch (GLOBALPART GTYPE) of GROUPELT) (QUOTE GROUP)) (PROG ((INDVGROUPELT (fetch (GLOBALPART INDIVIDUALGLOBALPART) of GROUPELT)) SUBELTS) (SETQ SUBELTS (fetch (GROUP LISTOFGLOBALELTS) of INDVGROUPELT)) (COND ((MEMBER ELTTODEL SUBELTS) (replace (GROUP LISTOFGLOBALELTS) of INDVGROUPELT with (REMOVE ELTTODEL SUBELTS)) (RETURN T)) (T (RETURN (for ELT in SUBELTS thereis (DELFROMGROUPELT ELTTODEL ELT]) (SKETCH.ELEMENT.TYPE [LAMBDA (ELEMENT) (* rrb "14-Aug-85 16:35") (* returns the type of a global sketch element) (fetch (GLOBALPART GTYPE) of ELEMENT]) (SKETCH.ELEMENT.CHANGED [LAMBDA (SKETCH ELEMENT SKETCHWINDOW) (* rrb " 5-Sep-85 10:56") (* If ELEMENT is an element of SKETCH, its local part is recalculated. This is normally used to notify sketch that an image object element has changed. Note: this replaces the element with another one.) (PROG ((SKETCH (INSURE.SKETCH SKETCH)) OLDREG) (OR (GLOBALELEMENTP ELEMENT) (ERROR ELEMENT " is not a sketch element.")) (* note that the sketch has changed.) (SK.MARK.DIRTY SKETCH) (SETQ OLDREG (fetch (SKIMAGEOBJ SKIMOBJ.GLOBALREGION) of (fetch (GLOBALPART INDIVIDUALGLOBALPART) of ELEMENT))) (SK.UPDATE.GLOBAL.IMAGE.OBJECT.ELEMENT ELEMENT) (* do the window that the interaction occurred in first.) (AND SKETCHWINDOW (SK.ELEMENT.CHANGED1 ELEMENT OLDREG SKETCHWINDOW)) (* propagate to other windows.) (for SKW in (ALL.SKETCH.VIEWERS SKETCH) when (NEQ SKW SKETCHWINDOW) do (SK.ELEMENT.CHANGED1 ELEMENT OLDREG SKW)) (RETURN ELEMENT]) (SK.ELEMENT.CHANGED1 [LAMBDA (SKIMAGEOBJELT OLDREGION SKETCHW) (* rrb "21-Aug-85 15:54") (* updates the display of an image object element in a window.) (PROG (LOCALELT) (COND ((SETQ LOCALELT (SK.LOCAL.ELT.FROM.GLOBALPART SKIMAGEOBJELT SKETCHW)) (COND ((EQ (SKETCH.ELEMENT.TYPE SKIMAGEOBJELT) (QUOTE SKIMAGEOBJ)) (SK.DELETE.ITEM LOCALELT SKETCHW) (DSPFILL OLDREGION WHITESHADE (QUOTE REPLACE) SKETCHW) (RETURN (SKETCH.ADD.AND.DISPLAY1 SKIMAGEOBJELT SKETCHW]) (SK.UPDATE.GLOBAL.IMAGE.OBJECT.ELEMENT [LAMBDA (SKIMOBJELT) (* rrb "21-Aug-85 16:05") (* updates the fields to reflect changes in the size of the image object.) (PROG ((INDVSKIMOBJELT (fetch (GLOBALPART INDIVIDUALGLOBALPART) of SKIMOBJELT)) IMOBJSIZE REGION SCALE) (SETQ IMOBJSIZE (IMAGEBOXSIZE (fetch (SKIMAGEOBJ SKIMAGEOBJ) of INDVSKIMOBJELT))) (SETQ REGION (fetch (SKIMAGEOBJ SKIMOBJ.GLOBALREGION) of INDVSKIMOBJELT)) (SETQ SCALE (fetch (SKIMAGEOBJ SKIMOBJ.ORIGSCALE) of INDVSKIMOBJELT)) (replace (SKIMAGEOBJ SKIMOBJ.GLOBALREGION) of INDVSKIMOBJELT with (CREATEREGION (fetch (REGION LEFT) of REGION) (fetch (REGION BOTTOM) of REGION) (TIMES (fetch (IMAGEBOX XSIZE) of IMOBJSIZE) SCALE) (TIMES (fetch (IMAGEBOX YSIZE) of IMOBJSIZE) SCALE))) (replace (SKIMAGEOBJ SKIMOBJ.OFFSETPOS) of INDVSKIMOBJELT with (create POSITION XCOORD ←(fetch (IMAGEBOX XKERN) of IMOBJSIZE) YCOORD ←(fetch (IMAGEBOX YDESC) of IMOBJSIZE))) (RETURN SKIMOBJELT]) ) (* utility routines for sketch windows.) (DEFINEQ (INSURE.SKETCH [LAMBDA (SK NOERRORFLG) (* rrb "23-Oct-85 11:24") (* returns the SKETCH structure from a window, sketch stream, or a structure.) (SK.CHECK.SKETCH.VERSION (COND ((type? SKETCH SK) SK) [(WINDOWP SK) (COND ((WINDOWPROP SK (QUOTE SKETCH))) (T (AND (NULL NOERRORFLG) (ERROR SK "doesn't have a SKETCH property."] [(IMAGESTREAMTYPEP SK (QUOTE SKETCH)) (* this is a sketch stream) (COND ((WINDOWPROP (\SKSTRM.WINDOW.FROM.STREAM SK) (QUOTE SKETCH))) (T (AND (NULL NOERRORFLG) (ERROR "sketch stream window doesn't have SKETCH property" SK] [(type? IMAGEOBJ SK) (PROG [(SK? (fetch (SKETCHIMAGEOBJ SKIO.SKETCH) of (LISTP (IMAGEOBJPROP SK (QUOTE OBJECTDATUM] (RETURN (COND ((type? SKETCH SK?) SK?) (NOERRORFLG NIL) (T (ERROR "not a sketch image object" SK] ((AND (LITATOM (CAR SK)) (for ELT in (CDR SK) always (GLOBALELEMENTP ELT))) (* old form, probably written out by notecards, update to new form.) (PROG (X) (SETQ X (SKIO.UPDATE.FROM.OLD.FORM SK)) (* smash sketch so this won't have to happen every time.) (RPLACA SK (CAR X)) (RPLACD SK (CDR X)) (RETURN X))) ((NULL NOERRORFLG) (ERROR SK "not a SKETCH"]) (LOCALSPECS.FROM.VIEWER [LAMBDA (SKW) (* rrb "12-May-85 16:46") (* returns the sketch specification displayed in the window SKW.) (CDAR (WINDOWPROP SKW (QUOTE SKETCHSPECS]) (SK.LOCAL.ELT.FROM.GLOBALPART [LAMBDA (GLOBALPART SKW) (* rrb "18-MAR-83 13:09") (* returns the local element from SKW that has global part GLOBALPART - NIL if there isn't one.) (for ELT in (LOCALSPECS.FROM.VIEWER SKW) when (EQ (fetch (SCREENELT GLOBALPART) of ELT) GLOBALPART) do (RETURN ELT]) (SKETCH.FROM.VIEWER [LAMBDA (SKETCHW) (* returns the sketch that the window views.) (WINDOWPROP SKETCHW (QUOTE SKETCH]) (INSPECT.SKETCH [LAMBDA (SKW) (* rrb "18-Apr-84 14:44") (* calls the inspector on the sketch specs of a sketch window.) (PROG ((SPECS (LOCALSPECS.FROM.VIEWER SKW))) (COND (SPECS (INSPECT/TOP/LEVEL/LIST SPECS]) ) (DEFINEQ (MAPSKETCHSPECS [LAMBDA (SKSPECS SPECFN DATUM DATUM2 DATUM3) (* rrb "10-Sep-84 14:58") (* walks through a sketch specification list and applies SPECFN to each of the individual elements.) (AND SKSPECS (COND ((SCREENELEMENTP SKSPECS) (APPLY* SPECFN SKSPECS DATUM DATUM2 DATUM3)) ((LISTP SKSPECS) (for FIGSPEC in SKSPECS do (MAPSKETCHSPECS FIGSPEC SPECFN DATUM DATUM2 DATUM3))) (T (ERROR "unknown figure specification" SKSPECS]) (MAPCOLLECTSKETCHSPECS [LAMBDA (SKSPECS SPECFN DATUM DATUM2 DATUM3 DATUM4) (* rrb "26-Apr-85 09:29") (* walks through a sketch specification list and applies SPECFN to each of the individual (elements returning a list of the results.)) (AND SKSPECS (COND ((SCREENELEMENTP SKSPECS) (APPLY* SPECFN SKSPECS DATUM DATUM2 DATUM3 DATUM4)) ((LISTP SKSPECS) (for FIGSPEC in SKSPECS collect (MAPCOLLECTSKETCHSPECS FIGSPEC SPECFN DATUM DATUM2 DATUM3 DATUM4))) (T (ERROR "unknown figure specification" SKSPECS]) (MAPSKETCHSPECSUNTIL [LAMBDA (SKETCHSPECS SPECFN DATUM DATUM2) (* rrb " 4-AUG-83 15:22") (* walks through a sketch specification list and applies SPECFN to each of the individual elements.) (AND SKETCHSPECS (COND ((SKETCH.ELEMENT.NAMEP (fetch (SCREENELT GTYPE) of SKETCHSPECS)) (APPLY* SPECFN SKETCHSPECS DATUM DATUM2)) ((LISTP SKETCHSPECS) (for FIGSPEC in SKETCHSPECS bind VALUE when (SETQ VALUE (MAPSKETCHSPECSUNTIL FIGSPEC SPECFN DATUM DATUM2)) do (RETURN VALUE))) (T (ERROR "unknown figure specification" SKETCHSPECS]) (MAPGLOBALSKETCHSPECS [LAMBDA (SKSPECS SPECFN DATUM DATUM2 DATUM3) (* rrb "19-Feb-85 17:52") (* walks through a list of global sketch elements and applies SPECFN to each of the individual elements.) (AND SKSPECS (COND ((GLOBALELEMENTP SKSPECS) (APPLY* SPECFN SKSPECS DATUM DATUM2 DATUM3)) ((LISTP SKSPECS) (for FIGSPEC in SKSPECS collect (MAPGLOBALSKETCHSPECS FIGSPEC SPECFN DATUM DATUM2 DATUM3) )) (T (ERROR "unknown global sketch element" SKSPECS]) (MAPGLOBALSKETCHELEMENTS [LAMBDA (SKSPECS SPECFN DATUM DATUM2 DATUM3) (* rrb "24-Apr-85 15:02") (* walks through a list of global sketch elements and applies SPECFN to each of the individual elements. Differes from MAPGLOBALSKETCHSPECS in that it know about and gets inside of GROUP elements.) (AND SKSPECS (COND [(GLOBALELEMENTP SKSPECS) (COND ((EQ (fetch (GLOBALPART GTYPE) of SKSPECS) (QUOTE GROUP)) (* map function down the individual elements.) (MAPGLOBALSKETCHELEMENTS (fetch (GROUP LISTOFGLOBALELTS) of (fetch (GLOBALPART INDIVIDUALGLOBALPART) of SKSPECS)) SPECFN DATUM DATUM2 DATUM3)) (T (APPLY* SPECFN SKSPECS DATUM DATUM2 DATUM3] ((LISTP SKSPECS) (for FIGSPEC in SKSPECS collect (MAPGLOBALSKETCHELEMENTS FIGSPEC SPECFN DATUM DATUM2 DATUM3))) (T (ERROR "unknown global sketch element" SKSPECS]) ) (* functions for marking) (DEFINEQ (SK.SHOWMARKS [LAMBDA (W HOTSPOTCACHE) (* rrb "29-Jan-85 18:04") (* marks all of the hot spots of sketch elements in a figure window.) (bind Y for BUCKET in HOTSPOTCACHE do (SETQ Y (CAR BUCKET)) (for XBUCKET in (CDR BUCKET) do (* there may be old buckets that don't contain any elements.) (AND (CDR XBUCKET) (SK.MARK.HOTSPOT (CAR XBUCKET) Y W SK.LOCATEMARK]) (MARKPOINT [LAMBDA (PT WINDOW MARK) (* rrb "12-May-85 18:50") (* marks a point in a window with a mark. The mark should be a bitmap.) (OR MARK (SETQ MARK SK.SELECTEDMARK)) (PROG ((MARKWIDTH (BITMAPWIDTH MARK))) (RETURN (BITBLT MARK 0 0 WINDOW (IDIFFERENCE (fetch (POSITION XCOORD) of PT) (LRSH MARKWIDTH 1)) (IDIFFERENCE (fetch (POSITION YCOORD) of PT) (LRSH (fetch (BITMAP BITMAPHEIGHT) of MARK) 1)) MARKWIDTH MARKWIDTH (QUOTE INPUT) (QUOTE INVERT]) (SK.MARKHOTSPOTS [LAMBDA (SKETCHELT W MARK) (* rrb "12-May-85 18:59") (* marks the hotspots of a sketch element that are not already selected) (PROG [(HOTSPOTCACHE (SK.HOTSPOT.CACHE W)) (SELECTEDELTS (WINDOWPROP W (QUOTE SKETCH.SELECTIONS] (for PTTAIL on (fetch (LOCALPART HOTSPOTS) of (fetch (SCREENELT LOCALPART) of SKETCHELT)) unless (OR (MEMBER (CAR PTTAIL) (CDR PTTAIL)) (for ELTSOFPT in (SK.ELTS.FROM.HOTSPOT (CAR PTTAIL) HOTSPOTCACHE) thereis (MEMB ELTSOFPT SELECTEDELTS))) do (* mark points that aren't also hotspots of an already selected element or duplicate hot spots of this element.) (MARKPOINT (CAR PTTAIL) W MARK]) (SK.MARK.SELECTION [LAMBDA (ELT SKW MARKBM) (* rrb " 9-May-85 10:42") (* marks or unmarks a selection.) (COND ((POSITIONP ELT) (* handle positions {points} specially.) (MARKPOINT ELT SKW MARKBM)) (T (SK.MARKHOTSPOTS ELT SKW MARKBM]) ) (READVARS POINTMARK SPOTMARKER) ({(READBITMAP)(7 7 "HB@@" "DD@@" "BH@@" "A@@@" "BH@@" "DD@@" "HB@@")} {(READBITMAP)(17 18 "@@@@@@@@" "@@@@@@@@" "@@L@@@@@" "@@L@@@@@" "@@L@@@@@" "@@L@@@@@" "@@@@@@@@" "ANMN@@@@" "ANMN@@@@" "@@@@@@@@" "@@L@@@@@" "@@L@@@@@" "@@L@@@@@" "@@L@@@@@" "@@@@@@@@" "@@@@@@@@" "@@@@@@@@" "@@@@@@@@")}) (DECLARE: DOEVAL@COMPILE DONTCOPY (GLOBALVARS POINTMARK SPOTMARKER) ) (RPAQ POINTREADINGCURSOR (CURSORCREATE (READBITMAP) 7 7)) (16 16 "@@@@" "@GL@" "ALG@" "C@AH" "F@@L" "D@@D" "L@@F" "H@@B" "HA@B" "H@@B" "L@@F" "D@@D" "F@@L" "C@AH" "ALG@" "@GL@") (* hit detection functions.) (DEFINEQ (SK.SELECT.ITEM [LAMBDA (WINDOW ITEMFLG SELITEMS OPERATION) (* rrb "10-Dec-85 17:01") (* selects allows the user to select one of the sketch elements from the sketch WINDOW. If ITEMFLG is non-NIL, it returns the item selected, otherwise it returns the position. If SELITEMS is given it is used as the items to be marked and selected from. Keeps control and probably shouldn't) (PROG (HOTSPOTCACHE NOW PREVIOUS OLDPOS) (COND (SELITEMS (* create a cache for the items to select from) (SETQ HOTSPOTCACHE (SK.ADD.HOTSPOTS.TO.CACHE SELITEMS NIL))) [(SK.HAS.SOME.HOTSPOTS (SETQ HOTSPOTCACHE (SK.HOTSPOT.CACHE.FOR.OPERATION WINDOW OPERATION] (T (* no items, don't do anything.) (RETURN))) (TOTOPW WINDOW) (SK.SHOWMARKS WINDOW HOTSPOTCACHE) (until (MOUSESTATE (NOT UP))) (COND ((NOT (LASTMOUSESTATE (OR LEFT MIDDLE))) (* for now not interested in anything besides left and middle.) (SK.SHOWMARKS WINDOW HOTSPOTCACHE) (RETURN))) (* note current item selection.) (SETQ NOW (IN.SKETCH.ELT? HOTSPOTCACHE (SETQ OLDPOS (CURSORPOSITION NIL WINDOW)) (NULL ITEMFLG))) FLIP (* turn off old selection.) (SK.DESELECT.ELT PREVIOUS WINDOW) (SK.SELECT.ELT (SETQ PREVIOUS NOW) WINDOW) LP (* wait for a button up or move out of region) (COND ((NOT (MOUSESTATE (OR LEFT MIDDLE))) (* button up, selected item if one) (SK.DESELECT.ELT PREVIOUS WINDOW) (SK.SHOWMARKS WINDOW HOTSPOTCACHE) (RETURN PREVIOUS)) ([EQUAL PREVIOUS (SETQ NOW (IN.SKETCH.ELT? HOTSPOTCACHE (CURSORPOSITION NIL WINDOW OLDPOS) (NULL ITEMFLG] (GO LP)) (T (GO FLIP]) (IN.SKETCH.ELT? [LAMBDA (CACHE POS PTFLG) (* rrb "21-Feb-85 13:47") (* returns the first element that POS is on.) (PROG ((Y (fetch (POSITION YCOORD) of POS)) (X (fetch (POSITION XCOORD) of POS)) (BESTMEASURE 1000) PTLEFT PTRIGHT PTTOP PTBOTTOM BESTELT BESTX BESTY YDIF THISDIF) (SETQ PTLEFT (DIFFERENCE X SK.POINT.WIDTH)) (SETQ PTRIGHT (PLUS X SK.POINT.WIDTH)) (SETQ PTBOTTOM (DIFFERENCE Y SK.POINT.WIDTH)) (SETQ PTTOP (PLUS Y SK.POINT.WIDTH)) [for YBUCKET in CACHE when (ILEQ (CAR YBUCKET) PTTOP) do (COND ((ILESSP (CAR YBUCKET) PTBOTTOM) (* stop when Y gets too small.) (RETURN))) (SETQ YDIF (ABS (DIFFERENCE (CAR YBUCKET) Y))) (for XBUCKET in (CDR YBUCKET) when (ILEQ (CAR XBUCKET) PTRIGHT) do (COND ((ILESSP (CAR XBUCKET) PTLEFT) (* stop when X gets too small.) (RETURN))) (COND ((CDR XBUCKET) (* this bucket has entries) [SETQ THISDIF (PLUS YDIF (ABS (DIFFERENCE (CAR XBUCKET) X] (COND ((ILESSP THISDIF BESTMEASURE) (SETQ BESTMEASURE THISDIF) (COND (PTFLG (SETQ BESTX (CAR XBUCKET)) (SETQ BESTY (CAR YBUCKET))) (T (SETQ BESTELT (CADR XBUCKET] (RETURN (COND (PTFLG (AND BESTX (create POSITION XCOORD ← BESTX YCOORD ← BESTY))) (T BESTELT]) (SK.MARK.HOTSPOT [LAMBDA (X Y WINDOW MARK) (* rrb "29-Jan-85 15:45") (* marks a point in a window with a mark. The mark should be a bitmap.) (PROG ((MARKWIDTH (BITMAPWIDTH MARK)) HALFWIDTH) (RETURN (BITBLT MARK 0 0 WINDOW (IDIFFERENCE X (SETQ HALFWIDTH (LRSH MARKWIDTH 1))) (IDIFFERENCE Y HALFWIDTH) MARKWIDTH MARKWIDTH (QUOTE INPUT) (QUOTE INVERT]) (SK.MARK.POSITION [LAMBDA (PT WINDOW MARKBITMAP) (* rrb "20-Apr-85 18:47") (* marks a place on the sketch window WINDOW.) (SK.MARK.HOTSPOT (fetch (POSITION XCOORD) of PT) (fetch (POSITION YCOORD) of PT) WINDOW MARKBITMAP]) (SK.SELECT.ELT [LAMBDA (ELT FIGW MARKBM) (* rrb " 3-Oct-84 11:18") (* selects an item from a figure window.) (* for now just mark it.) (AND ELT (SK.MARK.SELECTION ELT FIGW MARKBM]) (SK.DESELECT.ELT [LAMBDA (ELT SKW MARKBM) (* rrb " 9-May-85 10:32") (* turns off the selection marking of an item from a figure window.) (AND ELT (SK.MARK.SELECTION ELT SKW MARKBM]) ) (DECLARE: EVAL@COMPILE (RPAQQ SK.POINT.WIDTH 4) (CONSTANTS (SK.POINT.WIDTH 4)) ) (* fns to support caching of hotspots.) (DEFINEQ (SK.HOTSPOT.CACHE [LAMBDA (SKW) (* rrb "29-Jan-85 14:23") (* retrieve the hotspot cache associated with a sketch window.) (WINDOWPROP SKW (QUOTE HOTSPOT.CACHE]) (SK.HOTSPOT.CACHE.FOR.OPERATION [LAMBDA (VIEWER OPERATION) (* rrb "10-Dec-85 16:59") (* returns the hotspot cache for the elements in a viewer that are not protected against OPERATION.) (PROG (SCRELTS) (RETURN (COND ((AND OPERATION (bind PROTECTION for SCRELT in (SETQ SCRELTS ( LOCALSPECS.FROM.VIEWER VIEWER)) thereis (* look for any element that disallows the current operation) (SK.ELEMENT.PROTECTED? (fetch (SCREENELT GLOBALPART) of SCRELT) OPERATION))) (* compute special cache) (SK.BUILD.CACHE SCRELTS OPERATION)) (T (* use the cache of all elements.) (SK.HOTSPOT.CACHE VIEWER]) (SK.BUILD.CACHE [LAMBDA (SCRELTS SKETCHOP) (* rrb "11-Dec-85 11:10") (* Builds a cache of the elements in SCRELTS that aren't protected against SKETCHOP.) (PROG (CACHE) (for ELT in SCRELTS when (NOT (SK.ELEMENT.PROTECTED? (fetch (SCREENELT GLOBALPART) of ELT) SKETCHOP)) do (SETQ CACHE (SK.ADD.HOTSPOTS.TO.CACHE1 ELT CACHE))) (RETURN CACHE]) (SK.ELEMENT.PROTECTED? [LAMBDA (GELT HOW) (* rrb " 5-Dec-85 11:16") (* determines if GELT is protected against the operation HOW) (PROG [(PROTECTIONLST (GETSKETCHELEMENTPROP GELT (QUOTE PROTECTION] (RETURN (OR (EQMEMB HOW PROTECTIONLST) (AND (NEQ HOW (QUOTE COPYSELECT)) (OR (EQMEMB T PROTECTIONLST) (EQMEMB (QUOTE FROZEN) PROTECTIONLST]) (SK.HAS.SOME.HOTSPOTS [LAMBDA (HOTSPOTCACHE) (* rrb "17-Oct-85 11:18") (* return T if there is a selectable point in HOTSPOTCACHE.) (for BUCKET in HOTSPOTCACHE when (SOME (CDR BUCKET) (FUNCTION CDR)) do (RETURN T]) (SK.SET.HOTSPOT.CACHE [LAMBDA (SKW NEWCACHE) (* rrb "29-Jan-85 14:23") (* stores the hotspot cache associated with a sketch window.) (WINDOWPROP SKW (QUOTE HOTSPOT.CACHE) NEWCACHE]) (SK.CREATE.HOTSPOT.CACHE [LAMBDA (SKW) (* rrb " 4-Feb-85 14:18") (* creates the cache of hotspot locations for a sketch window.) (SK.SET.HOTSPOT.CACHE SKW (SK.ADD.HOTSPOTS.TO.CACHE (LOCALSPECS.FROM.VIEWER SKW) NIL]) (SK.ELTS.FROM.HOTSPOT [LAMBDA (POSITION CACHE) (* rrb "29-Jan-85 13:47") (* returns a list of local elements that have POSITION as one of their hotspots.) (* a cache is an alist of alist with the top descriminator being the Y value and the second one being the X value.) (PROG (TMP) (RETURN (AND (SETQ TMP (SK.FIND.CACHE.BUCKET (fetch (POSITION YCOORD) of POSITION) CACHE)) (SK.FIND.CACHE.BUCKET (fetch (POSITION XCOORD) of POSITION) TMP]) (SK.ADD.HOTSPOTS.TO.CACHE [LAMBDA (ELTS CACHE) (* rrb " 3-Feb-85 14:36") (* adds a collection of hotspots to a cache.) (for ELT in ELTS do (SETQ CACHE (SK.ADD.HOTSPOTS.TO.CACHE1 ELT CACHE))) CACHE]) (SK.ADD.HOTSPOTS.TO.CACHE1 [LAMBDA (LOCALELT CACHE) (* rrb "29-Jan-85 14:55") (* adds an elements hotspots to the cache.) (for HOTSPOT in (fetch (SCREENELT HOTSPOTS) of LOCALELT) do (SETQ CACHE (SK.ADD.HOTSPOT.TO.CACHE HOTSPOT LOCALELT CACHE)) ) CACHE]) (SK.ADD.HOTSPOT.TO.CACHE [LAMBDA (POSITION ELT CACHE) (* rrb "29-Jan-85 18:36") (* adds a hotspot to a cache.) (* a cache is an alist of alist with the top descriminator being the Y value and the second one being the X value.) (PROG ((Y (fetch (POSITION YCOORD) of POSITION)) (X (fetch (POSITION XCOORD) of POSITION))) (RETURN (COND [(NULL CACHE) (LIST (LIST Y (LIST X ELT] ((IGREATERP Y (CAAR CACHE)) (* this element goes first Splice it onto the front.) (RPLACD CACHE (CONS (CAR CACHE) (CDR CACHE))) (RPLACA CACHE (LIST Y (LIST X ELT))) CACHE) ((EQ (CAAR CACHE) Y) (SK.ADD.VALUE.TO.CACHE.BUCKET X ELT (CDAR CACHE)) CACHE) (T [for TAIL on CACHE do [AND (CDR TAIL) (COND ((EQ (CAADR TAIL) Y) (SK.ADD.VALUE.TO.CACHE.BUCKET X ELT (CDADR TAIL)) (RETURN)) ((IGREATERP Y (CAADR TAIL)) (RPLACD TAIL (CONS (LIST Y (LIST X ELT)) (CDR TAIL))) (RETURN] finally (NCONC1 CACHE (LIST Y (LIST X ELT] CACHE]) (SK.REMOVE.HOTSPOTS.FROM.CACHE [LAMBDA (ELTS CACHE) (* rrb "29-Jan-85 14:04") (* removes a collection of hotspots from a cache.) (for ELT in ELTS do (SETQ CACHE (SK.REMOVE.HOTSPOTS.FROM.CACHE1 ELT CACHE]) (SK.REMOVE.HOTSPOTS.FROM.CACHE1 [LAMBDA (LOCALELT CACHE) (* rrb "29-Jan-85 13:45") (* removes an elements hotspots to the cache.) (for HOTSPOT in (fetch (SCREENELT HOTSPOTS) of LOCALELT) do ( SK.REMOVE.HOTSPOT.FROM.CACHE HOTSPOT LOCALELT CACHE]) (SK.REMOVE.HOTSPOT.FROM.CACHE [LAMBDA (POSITION ELT CACHE) (* rrb "29-Jan-85 14:01") (* removes a hotspot to a cache.) (* a cache is an alist of alist with the top descriminator being the Y value and the second one being the X value.) (SK.REMOVE.VALUE.FROM.CACHE.BUCKET (fetch (POSITION XCOORD) of POSITION) ELT (FASSOC (fetch (POSITION YCOORD) of POSITION) CACHE]) (SK.REMOVE.VALUE.FROM.CACHE.BUCKET [LAMBDA (VAL ELT BUCKET) (* rrb "29-Jan-85 14:45") (* removes ELT from the list of elements stored on BUCKET under the key VAL.) (* leaves the x and y of the bucket because it seems easier than removing it and it may be used again in the case of changing an element by deleting it then adding it again.) (for TAIL on (FASSOC VAL (CDR BUCKET)) do (AND (CDR TAIL) (COND ((EQ (CADR TAIL) ELT) (RPLACD TAIL (CDDR TAIL]) (SK.FIND.CACHE.BUCKET [LAMBDA (VALUE CACHE) (* rrb "29-Jan-85 13:18") (* internal function for searching the caching Alists. Returns the bucket if there is one; quits when a value is larger than the one asked for.) (for TAIL on CACHE do (COND ((EQ (CAAR TAIL) VALUE) (RETURN (CDAR TAIL))) ((IGREATERP VALUE (CAAR TAIL)) (RETURN NIL]) (SK.ADD.VALUE.TO.CACHE.BUCKET [LAMBDA (VAL ELT ALIST) (* rrb "31-Jan-85 11:52") (* adds ELT to the list of elements stored on ALIST under the key VAL.) (COND ((NULL ALIST) (* shouldn't ever happen.) NIL) ((IGREATERP VAL (CAAR ALIST)) (* this element goes first Splice it onto the front.) (RPLACD ALIST (CONS (CAR ALIST) (CDR ALIST))) (RPLACA ALIST (LIST VAL ELT))) ((EQ (CAAR ALIST) VAL) (* add it to the end of the first list.) (NCONC1 (CAR ALIST) ELT)) (T (for TAIL on ALIST do [AND (CDR TAIL) (COND ((EQ (CAADR TAIL) VAL) (NCONC1 (CADR TAIL) ELT) (RETURN ALIST)) ((IGREATERP VAL (CAADR TAIL)) (RPLACD TAIL (CONS (LIST VAL ELT) (CDR TAIL))) (RETURN ALIST] finally (NCONC1 ALIST (LIST VAL ELT]) ) (* multiple selection and copy select functions) (DEFINEQ (SK.ADD.SELECTION [LAMBDA (ITEM/POS WINDOW MARKBM FIRSTFLG) (* rrb " 9-May-85 10:42") (* adds an item to the selection list of WINDOW.) (COND ([NOT (MEMBER ITEM/POS (WINDOWPROP WINDOW (QUOTE SKETCH.SELECTIONS] (* must turning off the element's selection before adding it to the window selections because the display of the selection check to see if the points are already selected in another element.) (SK.SELECT.ELT ITEM/POS WINDOW MARKBM) (WINDOWADDPROP WINDOW (QUOTE SKETCH.SELECTIONS) ITEM/POS FIRSTFLG]) (SK.COPY.INSERTFN [LAMBDA (IMAGEOBJ SKW) (* rrb " 4-Dec-85 21:27") (* * the function that gets called to insert a copy-selection into a sketch window. Knows how to insert sketches, everything else is text.) (bind DATUM for IMOBJ inside IMAGEOBJ do (COND ((STRINGP IMOBJ) (BKSYSBUF IMOBJ)) ((EQ (fetch (IMAGEOBJ IMAGEOBJFNS) of IMOBJ) SKETCHIMAGEFNS) (* this is a sketch imageobj) (SETQ DATUM (IMAGEOBJPROP IMOBJ (QUOTE OBJECTDATUM))) (SK.INSERT.SKETCH SKW (fetch (SKETCHIMAGEOBJ SKIO.SKETCH) of DATUM) (fetch (SKETCHIMAGEOBJ SKIO.REGION) of DATUM) (fetch (SKETCHIMAGEOBJ SKIO.SCALE) of DATUM))) (T (* insert the image object whatever it is) (SK.INSERT.SKETCH SKW [SKETCH.CREATE (QUOTE DUMMYNAME) (QUOTE ELEMENTS) (LIST (SETQ DATUM ( SK.ELEMENT.FROM.IMAGEOBJ IMAGEOBJ SKW] (fetch (SKIMAGEOBJ SKIMOBJ.GLOBALREGION) of (fetch (GLOBALPART INDIVIDUALGLOBALPART) of DATUM)) (WINDOW.SCALE SKW)) (COND ((AND (SETQ DATUM (IMAGEOBJPROP IMOBJ (QUOTE WHENINSERTEDFN))) (NEQ DATUM (QUOTE NILL))) (* call the image objects insertfn.) (APPLY* DATUM IMOBJ SKW]) (SK.FIGUREIMAGE [LAMBDA (SCRITEMS LIMITREGION REGIONOFINTEREST) (* rrb "31-Jul-85 10:20") (* returns a bitmap which contains the image of the elements on SCRITEMS. And a lower left corner.) (RESETFORM (CURSOR WAITINGCURSOR) (PROG (REGION DSPSTREAM BITMAP LEFT BOTTOM LIMITDIM) (COND ((NULL SCRITEMS) (RETURN))) [COND ((SCREENELEMENTP SCRITEMS) (* single item case.) (SETQ REGION (SK.ITEM.REGION SCRITEMS))) (T (SETQ REGION (SK.ITEM.REGION (CAR SCRITEMS))) (for SCITEM in (CDR SCRITEMS) do (SETQ REGION (UNIONREGIONS REGION (SK.ITEM.REGION SCITEM] (* only some of the points are being moved, reduce the region to those.) (AND REGIONOFINTEREST (SETQ REGION (OR (INTERSECTREGIONS REGION REGIONOFINTEREST) REGION))) [COND (LIMITREGION (* limit the size of the bitmap. This is used by copy insert functions that do not know how big the thing coming in is.) (COND ((GREATERP (fetch (REGION WIDTH) of REGION) (SETQ LIMITDIM (fetch (REGION WIDTH) of LIMITREGION)) ) (* reduce the width picking out the middle of the region) (replace (REGION LEFT) of REGION with (PLUS (fetch (REGION LEFT) of REGION) (QUOTIENT (DIFFERENCE LIMITDIM (fetch (REGION WIDTH) of REGION)) 2))) (replace (REGION WIDTH) of REGION with LIMITDIM))) (COND ((GREATERP (fetch (REGION HEIGHT) of REGION) (SETQ LIMITDIM (fetch (REGION HEIGHT) of LIMITREGION) )) (* reduce the height picking out the middle of the region) (replace (REGION BOTTOM) of REGION with (PLUS (fetch (REGION BOTTOM) of REGION) (QUOTIENT (DIFFERENCE LIMITDIM (fetch (REGION HEIGHT) of REGION)) 2))) (replace (REGION HEIGHT) of REGION with LIMITDIM] (* ADD1 is used to convert the possibly floating region coordinates into fixed.) [SETQ DSPSTREAM (DSPCREATE (SETQ BITMAP (BITMAPCREATE (ADD1 (fetch (REGION WIDTH) of REGION)) (ADD1 (fetch (REGION HEIGHT) of REGION] (DSPXOFFSET [IMINUS (SETQ LEFT (FIXR (fetch (REGION LEFT) of REGION] DSPSTREAM) (DSPYOFFSET [IMINUS (SETQ BOTTOM (FIXR (fetch (REGION BOTTOM) of REGION] DSPSTREAM) (* this is because the default clipping region is smaller than the clipping region of the figure in extreme cases.) (DSPCLIPPINGREGION REGION DSPSTREAM) (DSPOPERATION (QUOTE PAINT) DSPSTREAM) (* to avoid carriage returns.) (DSPRIGHTMARGIN (PLUS 100 (fetch (REGION RIGHT) of REGION)) DSPSTREAM) (DRAW.LOCAL.SKETCH SCRITEMS DSPSTREAM REGION) (RETURN (create SKFIGUREIMAGE SKFIGURE.LOWERLEFT ←(create POSITION XCOORD ← LEFT YCOORD ← BOTTOM) SKFIGURE.BITMAP ← BITMAP]) (SCREENELEMENTP [LAMBDA (ELT?) (* rrb "10-Sep-84 14:56") (* * returns ELT? if it is a screen element.) (PROG (X) (RETURN (AND (SETQ X (fetch (SCREENELT GLOBALPART) of ELT?)) (SKETCH.ELEMENT.NAMEP (fetch (GLOBALPART GTYPE) of X)) ELT?]) (SK.ITEM.REGION [LAMBDA (SCRELT) (* rrb "24-Jan-85 17:46") (* SCRELT is a sketch element This function returns the region it occupies.) (PROG [(REGIONFN (SK.REGIONFN (fetch (SCREENELT GTYPE) of SCRELT] (RETURN (COND ((OR (NULL REGIONFN) (EQ REGIONFN (QUOTE NILL))) NIL) ((APPLY* REGIONFN SCRELT]) (SK.ELEMENT.GLOBAL.REGION [LAMBDA (GELT) (* rrb "18-Oct-85 10:30") (* GELT is a global sketch element This function returns the global region it occupies.) (PROG [(REGIONFN (SK.GLOBAL.REGIONFN (fetch (GLOBALPART GTYPE) of GELT] (RETURN (COND ((OR (NULL REGIONFN) (EQ REGIONFN (QUOTE NILL))) NIL) ((APPLY* REGIONFN GELT]) (SK.LOCAL.ITEMS.IN.REGION [LAMBDA (HOTSPOTCACHE LEFT BOTTOM RIGHT TOP) (* rrb "31-Jan-85 11:38") (* * returns a list of the LOCALITEMS that are within LOCALREGION) (* changed to take a hotspot cache instead of a list of local items. OLD ARGS were (HOTSPOTCACHE LOCALREGION SCALE) OLD CODE (PROG ((SKREGION (UNSCALE.REGION LOCALREGION SCALE))) (RETURN (for SCRELT in LOCALITEMS when (SK.INSIDE.REGION (fetch (SCREENELT GLOBALPART) of SCRELT) SKREGION) collect SCRELT)))) (PROG ((RLEFT (DIFFERENCE LEFT SK.POINT.WIDTH)) (RBOTTOM (DIFFERENCE BOTTOM SK.POINT.WIDTH)) (RRIGHT (PLUS RIGHT SK.POINT.WIDTH)) (RTOP (PLUS TOP SK.POINT.WIDTH)) ELTS) [for YBUCKET in HOTSPOTCACHE when (ILEQ (CAR YBUCKET) RTOP) do (COND ((ILESSP (CAR YBUCKET) RBOTTOM) (* stop when Y gets too small.) (RETURN))) (for XBUCKET in (CDR YBUCKET) when (ILEQ (CAR XBUCKET) RRIGHT) do (COND ((ILESSP (CAR XBUCKET) RLEFT) (* stop when X gets too small.) (RETURN))) (* collect the elements.) (SETQ ELTS (UNION (CDR XBUCKET) ELTS] (RETURN ELTS]) (SK.REGIONFN [LAMBDA (ELEMENTTYPE) (* rrb " 5-Sep-84 16:06") (* * access fn for getting the function that returns the region of an item from its type.) (fetch (SKETCHTYPE REGIONFN) of (GETPROP ELEMENTTYPE (QUOTE SKETCHTYPE]) (SK.GLOBAL.REGIONFN [LAMBDA (ELEMENTTYPE) (* rrb "18-Oct-85 10:30") (* * access fn for getting the function that returns the global region of a global sketch element from its type.) (fetch (SKETCHTYPE GLOBALREGIONFN) of (GETPROP ELEMENTTYPE (QUOTE SKETCHTYPE]) (SK.REMOVE.SELECTION [LAMBDA (ITEM/POS WINDOW MARKBM) (* rrb " 9-May-85 10:31") (* removes an item from the selection list of WINDOW.) (COND ((MEMBER ITEM/POS (WINDOWPROP WINDOW (QUOTE SKETCH.SELECTIONS))) (* must remove element from window selections before turning off its selection because the display of the selection check to see if the points are still selected in another element.) (WINDOWDELPROP WINDOW (QUOTE SKETCH.SELECTIONS) ITEM/POS) (SK.DESELECT.ELT ITEM/POS WINDOW MARKBM]) (SK.SELECT.MULTIPLE.ITEMS [LAMBDA (WINDOW ITEMFLG SELITEMS OPERATION) (* rrb "10-Dec-85 17:34") (* * selects allows the user to select a group of the sketch elements from the sketch WINDOW. If ITEMFLG is NIL, the user is allows to select control points as well as complete items and the returned value may be the position of a control point. If SELITEMS is given it is used as the items to be marked and selected from. Keeps control and probably shouldn't) (* the selection protocol is left to add, right to delete. Multiple clicking in the same place upscales for both select and deselect. Sweeping will select or deselect all of the items in the swept out area. Also it keeps control as long as a shift key is down.) (PROG ((INTERIOR (DSPCLIPPINGREGION NIL WINDOW)) SELECTABLEITEMS HOTSPOTCACHE TIMER NOW OLDX ORIGX NEWX NEWY OLDY ORIGY OUTOFFIRSTPICK PREVMOUSEBUTTONS MOUSEINSIDE?) (COND (SELITEMS (SETQ SELECTABLEITEMS SELITEMS) (* create a cache for the items to select from) (SETQ HOTSPOTCACHE (SK.ADD.HOTSPOTS.TO.CACHE SELITEMS NIL))) [(AND (SETQ SELECTABLEITEMS (LOCALSPECS.FROM.VIEWER WINDOW)) (SK.HAS.SOME.HOTSPOTS (SETQ HOTSPOTCACHE (SK.HOTSPOT.CACHE.FOR.OPERATION WINDOW OPERATION] (T (* no items, don't do anything.) (RETURN))) (TOTOPW WINDOW) (SK.PUT.MARKS.UP WINDOW HOTSPOTCACHE) (until (MOUSESTATE (NOT UP))) (COND ((INSIDEP INTERIOR (LASTMOUSEX WINDOW) (LASTMOUSEY WINDOW)) (SETQ MOUSEINSIDE? T)) (T (* first press was outside of the window, don't select anything.) (SK.TAKE.MARKS.DOWN WINDOW HOTSPOTCACHE) (RETURN))) SELECTLP (COND ((MOUSESTATE UP) (GO SELECTEXIT))) (* this label provides an entry for the code that tests if the shift key is down.) SELAFTERTEST (SETQ NEWY (LASTMOUSEY WINDOW)) (SETQ NEWX (LASTMOUSEX WINDOW)) [COND [(NOT MOUSEINSIDE?) (* mouse is outside, don't do anything other than wait for it to come back in. If the user has let up all buttons, the branch to SELECTEXIT will have been taken.) (COND ((INSIDEP INTERIOR NEWX NEWY) (SETQ MOUSEINSIDE? T) (* restore the saved selected items.) (for ELT in SELITEMS do (SK.ADD.SELECTION ELT WINDOW] ((NOT (INSIDEP INTERIOR NEWX NEWY)) (* mouse just went outside, remove selections but save them in case mouse comes back in.) (SETQ MOUSEINSIDE? NIL) (SETQ SELITEMS (WINDOWPROP WINDOW (QUOTE SKETCH.SELECTIONS))) (for ELT in SELITEMS do (SK.REMOVE.SELECTION ELT WINDOW))) [(NEQ PREVMOUSEBUTTONS LASTMOUSEBUTTONS) (* another button has gone down, mark this as the origin of a new box to sweep.) (SETQ PREVMOUSEBUTTONS LASTMOUSEBUTTONS) (SETQ ORIGX (LASTMOUSEX WINDOW)) (SETQ ORIGY (LASTMOUSEY WINDOW)) [COND ((NULL ITEMFLG) (* clear any selections that are of single points.) (for SEL in (WINDOWPROP WINDOW (QUOTE SKETCH.SELECTIONS)) when (POSITIONP SEL) do (SK.REMOVE.SELECTION SEL WINDOW] (* add or delete the element that the button press occurred on if any.) (AND [SETQ NOW (IN.SKETCH.ELT? HOTSPOTCACHE (create POSITION XCOORD ← NEWX YCOORD ← NEWY) (AND (NULL ITEMFLG) (LASTMOUSESTATE (ONLY LEFT)) (NULL (WINDOWPROP WINDOW (QUOTE SKETCH.SELECTIONS] (COND ((LASTMOUSESTATE (ONLY LEFT)) (* add selection.) (SK.ADD.SELECTION NOW WINDOW)) ((LASTMOUSESTATE RIGHT) (* remove selection.) (SK.REMOVE.SELECTION NOW WINDOW] ((COND (OUTOFFIRSTPICK (OR (NEQ OLDX NEWX) (NEQ OLDY NEWY))) ((OR (IGREATERP (IABS (IDIFFERENCE ORIGX NEWX)) SK.NO.MOVE.DISTANCE) (IGREATERP (IABS (IDIFFERENCE ORIGY NEWY)) SK.NO.MOVE.DISTANCE)) (* make the first pick move further so that it is easier to multiple click.) (SETQ OUTOFFIRSTPICK T))) (* cursor has moved more than the minimum amount since last noticed.) (* add or delete any with in the swept out area.) (COND ([AND (LASTMOUSESTATE (NOT UP)) (SETQ SELITEMS (SK.LOCAL.ITEMS.IN.REGION HOTSPOTCACHE (MIN ORIGX NEWX) (MIN ORIGY NEWY) (MAX ORIGX NEWX) (MAX ORIGY NEWY] (* if selecting multiple things, it must be whole items. Update NOW to be an item if it isn't already.) [COND ((POSITIONP NOW) (SK.REMOVE.SELECTION NOW WINDOW) (* if selecting, add the whole element in.) (AND (LASTMOUSESTATE (ONLY LEFT)) (SETQ NOW (IN.SKETCH.ELT? HOTSPOTCACHE NOW)) (SK.ADD.SELECTION NOW WINDOW] (COND ((LASTMOUSESTATE (ONLY LEFT)) (* left only selects.) (for SELITEM in SELITEMS do (SK.ADD.SELECTION SELITEM WINDOW))) ((LASTMOUSESTATE RIGHT) (* right cause deselect.) (for SELITEM in SELITEMS do (SK.REMOVE.SELECTION SELITEM WINDOW] (SETQ OLDX NEWX) (SETQ OLDY NEWY) (GO SELECTLP) SELECTEXIT (COND (OUTOFFIRSTPICK (GO SHIFTDOWNLP))) (* wait for multiple clicks) (SETQ TIMER (SETUPTIMER CLICKWAITTIME TIMER)) CLICKLP (COND [(AND (MOUSESTATE (NOT UP)) (ILESSP (IABS (IDIFFERENCE ORIGX (LASTMOUSEX WINDOW))) SK.NO.MOVE.DISTANCE) (ILESSP (IABS (IDIFFERENCE ORIGY (LASTMOUSEY WINDOW))) SK.NO.MOVE.DISTANCE)) (AND (LASTMOUSESTATE (ONLY LEFT)) (COND ((POSITIONP NOW) (* thing selected is a point, select the whole item.) (SK.REMOVE.SELECTION NOW WINDOW) (SK.ADD.SELECTION (SETQ NOW (IN.SKETCH.ELT? HOTSPOTCACHE NOW)) WINDOW)) ((SCREENELEMENTP NOW) (* thing now selected is an item, select all selectable items keeping the first one selected on the front.) (for SELITEM in (SETQ NOW (CONS NOW (REMOVE NOW SELECTABLEITEMS)) ) do (SK.ADD.SELECTION SELITEM WINDOW] ((NOT (TIMEREXPIRED? TIMER)) (GO CLICKLP))) SHIFTDOWNLP (COND ((MOUSESTATE (NOT UP)) (* button went down again, initialize the button state and click position.) (SETQ PREVMOUSEBUTTONS NIL) (SETQ OUTOFFIRSTPICK NIL) (GO SELAFTERTEST)) ((.SHIFTKEYDOWNP.) (* flip selection marks because if cursor is outside when shift key is let up, nothing is selected.) [COND [(NOT MOUSEINSIDE?) (* mouse is outside: if it comes back in, mark the selections.) (COND ((INSIDEP INTERIOR (LASTMOUSEX WINDOW) (LASTMOUSEY WINDOW)) (SETQ MOUSEINSIDE? T) (* restore the saved selected items.) (for ELT in SELITEMS do (SK.ADD.SELECTION ELT WINDOW] ((NOT (INSIDEP INTERIOR (LASTMOUSEX WINDOW) (LASTMOUSEY WINDOW))) (* mouse just went outside, remove marks but keep selections) (SETQ MOUSEINSIDE? NIL) (SETQ SELITEMS (WINDOWPROP WINDOW (QUOTE SKETCH.SELECTIONS))) (for ELT in SELITEMS do (SK.REMOVE.SELECTION ELT WINDOW] (GO SHIFTDOWNLP))) (SETQ SELITEMS (WINDOWPROP WINDOW (QUOTE SKETCH.SELECTIONS))) (COND (MOUSEINSIDE? (* unmark and remove the selected items from the window property list.) (for SEL in SELITEMS do (SK.REMOVE.SELECTION SEL WINDOW))) (T (* they have already been unmarked, just remove them from the window.) (WINDOWPROP WINDOW (QUOTE SKETCH.SELECTIONS) NIL))) (SK.TAKE.MARKS.DOWN WINDOW HOTSPOTCACHE) (RETURN SELITEMS]) (SK.PUT.MARKS.UP [LAMBDA (SKETCHW HOTSPOTCACHE) (* rrb "29-Jan-85 17:40") (* makes sure the selection points are up in a window.) (COND ((NULL (WINDOWPROP SKETCHW (QUOTE MARKS.UP))) (SK.SHOWMARKS SKETCHW HOTSPOTCACHE) (WINDOWPROP SKETCHW (QUOTE MARKS.UP) T]) (SK.TAKE.MARKS.DOWN [LAMBDA (SKETCHW HOTSPOTCACHE) (* rrb "29-Jan-85 17:41") (* makes sure the selection points are down in a window.) (COND ((WINDOWPROP SKETCHW (QUOTE MARKS.UP)) (SK.SHOWMARKS SKETCHW HOTSPOTCACHE) (WINDOWPROP SKETCHW (QUOTE MARKS.UP) NIL]) (SK.TRANSLATE.GLOBALPART [LAMBDA (GLOBALELT DELTAPOS RETURNELTIFCANTFLG) (* rrb "26-Nov-85 15:51") (* GLOBALELT is a sketch element that was selected for a translate operation. DELTAPOS is the amount the item is to be translated.) (PROG ((TRANSLATEFN (SK.TRANSLATEFN (fetch (GLOBALPART GTYPE) of GLOBALELT))) NEWGLOBAL OLDGLOBAL ACTIVEREGION) (RETURN (COND ((OR (NULL TRANSLATEFN) (EQ TRANSLATEFN (QUOTE NILL))) (* if can't translate, return the same thing. This is probably an error condition.) GLOBALELT) ((SETQ NEWGLOBAL (APPLY* TRANSLATEFN GLOBALELT DELTAPOS)) [COND ([AND (SETQ ACTIVEREGION (GETSKETCHELEMENTPROP NEWGLOBAL (QUOTE ACTIVEREGION))) (EQUAL ACTIVEREGION (GETSKETCHELEMENTPROP GLOBALELT (QUOTE ACTIVEREGION] (* update the ACTIVEREGION if the element has one and it is the same in the new element.) (* copy the property list so that undoing works) (SK.COPY.ELEMENT.PROPERTY.LIST NEWGLOBAL) (PUTSKETCHELEMENTPROP NEWGLOBAL (QUOTE ACTIVEREGION) (REL.MOVE.REGION ACTIVEREGION (fetch (POSITION XCOORD) of DELTAPOS) (fetch (POSITION YCOORD) of DELTAPOS] NEWGLOBAL) (RETURNELTIFCANTFLG (* in the case of translating a whole sketch, need to return something.) GLOBALELT]) (SK.TRANSLATE.ITEM [LAMBDA (SELELT GLOBALDELTAPOS W) (* rrb "21-Jan-85 18:35") (* SELELT is a sketch element that was selected for a translate operation. GLOBALDELTAPOS is the amount the item is to be translated.) (PROG (NEWGLOBAL OLDGLOBAL) (COND ((SETQ NEWGLOBAL (SK.TRANSLATE.GLOBALPART (SETQ OLDGLOBAL (fetch (SCREENELT GLOBALPART) of SELELT)) GLOBALDELTAPOS)) (SK.UPDATE.ELEMENT OLDGLOBAL NEWGLOBAL W T) (* don't include history for now. (SK.ADD.HISTEVENT (QUOTE TRANSLATE) (LIST OLDGLOBAL NEWGLOBAL) W)) (RETURN NEWGLOBAL]) (SK.TRANSLATEFN [LAMBDA (ELEMENTTYPE) (* rrb " 4-Sep-84 17:01") (fetch (SKETCHTYPE TRANSLATEFN) of (GETPROP ELEMENTTYPE (QUOTE SKETCHTYPE]) (TRANSLATE.SKETCH [LAMBDA (SKETCH NEWXORG NEWYORG) (* rrb " 9-Jul-85 12:36") (* * translates all the elements in a sketch to make the new {0, 0} be NEWXORG NEWYORG) (PROG [(DELTAPOS (create POSITION XCOORD ←(MINUS NEWXORG) YCOORD ←(MINUS NEWYORG] (RETURN (create SKETCH using SKETCH SKETCHELTS ←(for GELT in (fetch (SKETCH SKETCHELTS) of SKETCH) collect ( SK.TRANSLATE.GLOBALPART GELT DELTAPOS T]) ) (DECLARE: EVAL@COMPILE (RPAQQ SK.NO.MOVE.DISTANCE 4) (CONSTANTS (SK.NO.MOVE.DISTANCE 4)) ) (DECLARE: DONTCOPY [DECLARE: EVAL@COMPILE (RECORD SKFIGUREIMAGE (SKFIGURE.BITMAP SKFIGURE.LOWERLEFT)) ] ) (RPAQ? ALLOW.MULTIPLE.SELECTION.FLG T) (* functions for determining what is inside of a window.) (DEFINEQ (ELT.INSIDE.SKETCHWP [LAMBDA (GELT SKW) (* rrb " 8-APR-83 13:18") (* determines if a global element is in the region of a viewer) (SK.INSIDE.REGION GELT (WINDOWPROP SKW (QUOTE REGION.VIEWED]) (SK.INSIDE.REGION [LAMBDA (GELT REGION) (* rrb "31-Aug-84 10:15") (* determines if the element GELT is inside of the global region REGION) (APPLY* (SK.INSIDEFN (fetch (GLOBALPART GTYPE) of GELT)) GELT REGION]) ) (* stuff for changing the input scale) (DEFINEQ (SK.INPUT.SCALE [LAMBDA (SKW) (* rrb " 4-Sep-85 15:35") (* returns the scale that input should be) (PROG [(SK (WINDOWPROP SKW (QUOTE SKETCHCONTEXT] (COND ((NULL SK) (ERROR SKW "arg not sketch window") (RETURN NIL))) (RETURN (COND ((fetch (SKETCHCONTEXT SKETCHINPUTSCALE) of SK)) (T (* early form of sketch that doesn't have an input scale.) (SK.UPDATE.SKETCHCONTEXT SK) (replace (SKETCHCONTEXT SKETCHINPUTSCALE) of SK with 1.0) 1.0]) (SK.UPDATE.SKETCHCONTEXT [LAMBDA (SKETCHCONTEXT) (* rrb " 4-Sep-85 14:55") (* updates an instance of a sketch context to have enough fields.) (PROG ((NEWSK (CREATE.DEFAULT.SKETCH.CONTEXT))) [COND ((GREATERP (DIFFERENCE (LENGTH NEWSK) (LENGTH SKETCHCONTEXT)) 0) (* add fields to the sketch) (NCONC SKETCHCONTEXT (NTH NEWSK (ADD1 (LENGTH SKETCHCONTEXT] (RETURN SKETCHCONTEXT]) (SK.SET.INPUT.SCALE [LAMBDA (W) (* rrb " 4-Sep-85 15:47") (* sets the size of the (input scale)) (SK.SET.INPUT.SCALE.VALUE (RNUMBER (CONCAT "Input scale is now " (SK.INPUT.SCALE W) ". Enter new input scale. A larger scale will make new lines and text larger.") NIL NIL NIL T T) W]) (SK.SET.INPUT.SCALE.CURRENT [LAMBDA (W) (* rrb " 4-Sep-85 15:41") (* sets the size of the input scale to the scale of the current window.) (SK.SET.INPUT.SCALE.VALUE (WINDOW.SCALE W) W]) (SK.SET.INPUT.SCALE.VALUE [LAMBDA (NEWINPUTSCALE SKW) (* rrb " 4-Sep-85 15:39") (* sets the input scale to NEWINPUTSCALE) (AND (NUMBERP NEWINPUTSCALE) (NOT (ZEROP NEWINPUTSCALE)) (replace (SKETCHCONTEXT SKETCHINPUTSCALE) of (WINDOWPROP SKW (QUOTE SKETCHCONTEXT)) with NEWINPUTSCALE]) ) (* stuff for setting feedback amount) (DEFINEQ (SK.SET.FEEDBACK.MODE [LAMBDA (VALUE) (* rrb "19-Nov-85 13:25") (* sets the control on how much feedback to give the user as they are entering new figure elements.) [OR (MEMB VALUE (QUOTE (POINTS T ALWAYS))) (SETQ VALUE (\CURSOR.IN.MIDDLE.MENU (create MENU ITEMS ←(QUOTE (("Points only" (QUOTE POINTS) "Only the control points will be shown when entering elements.") ("Fast figures" T "Wires, circles and ellipses are shown while they are being entered.") ("All figures" (QUOTE ALWAYS) "Most elements are shown while they are being entered. This will be slow for arcs and curves."))) CENTERFLG ← T] (AND VALUE (SETQ SKETCH.VERBOSE.FEEDBACK (SELECTQ VALUE (POINTS NIL) VALUE]) (SK.SET.FEEDBACK.POINT [LAMBDA NIL (* sets the feedback to points only) (SK.SET.FEEDBACK.MODE (QUOTE POINTS]) (SK.SET.FEEDBACK.VERBOSE [LAMBDA NIL (* sets the feedback to provide images on elements that are fast.) (SK.SET.FEEDBACK.MODE T]) (SK.SET.FEEDBACK.ALWAYS [LAMBDA NIL (* sets the feedback to give images on all figures.) (SK.SET.FEEDBACK.MODE (QUOTE ALWAYS]) ) (RPAQQ SKETCH.VERBOSE.FEEDBACK T) (DECLARE: DOEVAL@COMPILE DONTCOPY (GLOBALVARS SKETCH.VERBOSE.FEEDBACK) ) (* functions for zooming) (DEFINEQ (SKETCHW.SCALE [LAMBDA (WIN) (WINDOWPROP WIN (QUOTE SCALE]) (SKETCH.ZOOM [LAMBDA (SKW) (* rrb " 8-May-85 18:11") (* changes the scale of the figure being looked at in a window.) (PROG (NEWREG) (PROMPTPRINT "Specify the part of this figure that will be seen after the zoom. It can be either larger or smaller than the present window size.") (SETQ NEWREG (GETWREGION SKW (FUNCTION SAME.ASPECT.RATIO) SKW 4 4)) (CLRPROMPT) (COND ((NULL (REGIONSINTERSECTP NEWREG (DSPCLIPPINGREGION NIL SKW))) (* if it doesn't overlap this window, don't move.) (STATUSPRINT SKW "Specified region was entirely outside the window. Not changed.")) (T (SKETCH.DO.ZOOM SKW NEWREG]) (SAME.ASPECT.RATIO [LAMBDA (FIXPT MOVEPT WIN) (* rrb "29-MAR-83 11:13") (* new region function that keeps the same aspect ratio as a window.) (COND ((NULL MOVEPT) FIXPT) (T (PROG ((REG (DSPCLIPPINGREGION NIL WIN)) (YMOVE (fetch (POSITION YCOORD) of MOVEPT)) (XFIX (fetch (POSITION XCOORD) of FIXPT)) (XMOVE (fetch (POSITION XCOORD) of MOVEPT)) (YFIX (fetch (POSITION YCOORD) of FIXPT)) WID) (* use height as the deciding point.) [SETQ WID (ABS (QUOTIENT (ITIMES (fetch (REGION WIDTH) of REG) (IDIFFERENCE YMOVE YFIX)) (fetch (REGION HEIGHT) of REG] (RETURN (create POSITION XCOORD ←(COND ((IGREATERP XFIX XMOVE) (IDIFFERENCE XFIX WID)) (T (IPLUS XFIX WID))) YCOORD ← YMOVE]) (SKETCH.DO.ZOOM [LAMBDA (SKETCHW NEWREGION) (* rrb " 7-May-85 15:49") (* moves the viewing region of a window to be over NEWREGION which is in window coordinates.) (PROG (NEWSCALE (OLDSCALE (WINDOW.SCALE SKETCHW)) (OLDREG (DSPCLIPPINGREGION NIL SKETCHW))) (* scale on the basis of heights.) [SETQ NEWSCALE (FTIMES OLDSCALE (FQUOTIENT (fetch (REGION HEIGHT) of NEWREGION) (fetch (REGION HEIGHT) of OLDREG] (WINDOWPROP SKETCHW (QUOTE SCALE) NEWSCALE) (ABSWXOFFSET (FIXR (FQUOTIENT (FTIMES (fetch (REGION LEFT) of NEWREGION) OLDSCALE) NEWSCALE)) SKETCHW) (ABSWYOFFSET (FIXR (FQUOTIENT (FTIMES (fetch (REGION BOTTOM) of NEWREGION) OLDSCALE) NEWSCALE)) SKETCHW) (SK.UPDATE.GRIDFACTOR SKETCHW OLDSCALE) (SK.UPDATE.AFTER.SCALE.CHANGE SKETCHW]) (SKETCH.NEW.VIEW [LAMBDA (SKW) (* rrb "23-Jan-85 13:56") (* opens a new view onto the sketch viewed by SKW.) (WINDOWPROP (SKETCHW.CREATE (SKETCH.FROM.VIEWER SKW) NIL NIL NIL (WINDOW.SCALE SKW) T (SK.GRIDFACTOR SKW)) (QUOTE DONTQUERYCHANGES) T]) (ZOOM.UPDATE.ELT [LAMBDA (ELT SKW) (* rrb "29-Jan-85 14:40") (* destructively updates the local part of an element in response to a zoom or hardcopy command.) (PROG ((CACHE (SK.HOTSPOT.CACHE SKW))) (SK.REMOVE.HOTSPOTS.FROM.CACHE1 ELT CACHE) (replace (SCREENELT LOCALPART) of ELT with (fetch (SCREENELT LOCALPART) of (SK.LOCAL.FROM.GLOBAL (fetch (SCREENELT GLOBALPART) of ELT) SKW))) (SK.ADD.HOTSPOTS.TO.CACHE1 ELT CACHE) (RETURN ELT]) (SK.UPDATE.AFTER.SCALE.CHANGE [LAMBDA (SKETCHW STOPIFMOUSEDOWN) (* rrb "25-Nov-85 17:46") (* called to update the display and local elements after a window has had a scale change.) (* if STOPIFMOUSEDOWN is T, it displays some but stops if the button left or middle button is still down and returns STOPPED) (PROG ([SKETCH (fetch (SKETCH SKETCHELTS) of (INSURE.SKETCH (SKETCH.FROM.VIEWER SKETCHW] NEWREGION INNEW? LOCALELT) (* take down the caret.) (SKED.CLEAR.SELECTION SKETCHW T) (SK.UPDATE.REGION.VIEWED SKETCHW) (SETQ NEWREGION (SKETCH.REGION.VIEWED SKETCHW)) [for GELT in SKETCH do (SETQ INNEW? (SK.INSIDE.REGION GELT NEWREGION)) (COND [(SETQ LOCALELT (SK.LOCAL.ELT.FROM.GLOBALPART GELT SKETCHW)) (COND (INNEW? (* is still in but must have its local adjusted to the new scale.) (ZOOM.UPDATE.ELT LOCALELT SKETCHW)) (T (* if it is not supposed to be in the new region, remove it.) (SK.DELETE.ITEM LOCALELT SKETCHW] (INNEW? (* just came in) (SK.ADD.ITEM GELT SKETCHW] (DSPFILL NIL NIL (QUOTE REPLACE) SKETCHW) (SKETCHW.REPAINTFN SKETCHW NIL STOPIFMOUSEDOWN T]) (SKETCH.AUTOZOOM [LAMBDA (SKW) (* rrb "25-Nov-85 17:46") (* allows the user to pick a point and zooms to or from that point according to the cursor.) (RESETFORM (CURSOR AUTOZOOMCURSOR) (PROG [SKETCHREG NEWSKETCHREG PTX PTY SCALE LFT BTM WID HGHT DISPLAYSTOPPED (WINDOWREG (WINDOWPROP SKW (QUOTE REGION] (STATUSPRINT SKW "left button zooms in; middle zooms out.") (* zoom by a constant factor that keeps the point that the cursor is on at the same location.) [until (AND (MOUSESTATE (NOT UP)) (NOT (INSIDE? WINDOWREG LASTMOUSEX LASTMOUSEY)) (OR (NOT (EQ DISPLAYSTOPPED (QUOTE STOPPED))) (PROGN (* last display didn't finish) (SKETCH.GLOBAL.REGION.ZOOM SKW NEWSKETCHREG T) T))) do (COND ((LASTMOUSESTATE (OR LEFT MIDDLE)) [SETQ PTX (TIMES (LASTMOUSEX SKW) (SETQ SCALE (WINDOW.SCALE SKW] (SETQ PTY (TIMES (LASTMOUSEY SKW) SCALE)) (SETQ SKETCHREG (SKETCH.REGION.VIEWED SKW)) (SETQ LFT (fetch (REGION LEFT) of SKETCHREG)) (SETQ BTM (fetch (REGION BOTTOM) of SKETCHREG)) (SETQ WID (fetch (REGION WIDTH) of SKETCHREG)) (SETQ HGHT (fetch (REGION HEIGHT) of SKETCHREG)) (COND ([SETQ NEWSKETCHREG (COND ((LASTMOUSESTATE LEFT) (* zoom in) (CREATEREGION (FDIFFERENCE PTX (TIMES (DIFFERENCE PTX LFT) AUTOZOOM.FACTOR)) (FDIFFERENCE PTY (TIMES AUTOZOOM.FACTOR (DIFFERENCE PTY BTM))) (TIMES WID AUTOZOOM.FACTOR) (TIMES HGHT AUTOZOOM.FACTOR))) ((LASTMOUSESTATE MIDDLE) (* zoom out) (CREATEREGION (FDIFFERENCE PTX (QUOTIENT (DIFFERENCE PTX LFT) AUTOZOOM.FACTOR)) (FDIFFERENCE PTY (QUOTIENT (DIFFERENCE PTY BTM) AUTOZOOM.FACTOR)) (QUOTIENT WID AUTOZOOM.FACTOR) (QUOTIENT HGHT AUTOZOOM.FACTOR] (CURSOR (COND ((LASTMOUSESTATE LEFT) ZOOMINCURSOR) (T ZOOMOUTCURSOR))) (SETQ DISPLAYSTOPPED (SKETCH.GLOBAL.REGION.ZOOM SKW NEWSKETCHREG T)) (CURSOR AUTOZOOMCURSOR] (CLOSEPROMPTWINDOW SKW]) (SKETCH.GLOBAL.REGION.ZOOM [LAMBDA (SKETCHW NEWREGION STOPIFMOUSEDOWN) (* rrb "12-Nov-85 16:00") (* moves the viewing region of a window to be over NEWREGION which is in sketch coordinates.) (PROG (WIDTHSCALE HEIGHTSCALE NEWSCALE NEWLEFT NEWSCALE (OLDSCALE (WINDOW.SCALE SKETCHW)) (WINDOWREG (DSPCLIPPINGREGION NIL SKETCHW))) (* scale on the basis of which ever dimension make the region fit.) (SKED.CLEAR.SELECTION SKETCHW) (COND ([GREATERP (SETQ HEIGHTSCALE (FQUOTIENT (fetch (REGION HEIGHT) of NEWREGION) (fetch (REGION HEIGHT) of WINDOWREG))) (SETQ WIDTHSCALE (FQUOTIENT (fetch (REGION WIDTH) of NEWREGION) (fetch (REGION WIDTH) of WINDOWREG] (* height is largest scale) (SETQ NEWSCALE HEIGHTSCALE)) (T (SETQ NEWSCALE WIDTHSCALE))) (* center the extra width) (SETQ NEWLEFT (FIXR (FQUOTIENT (DIFFERENCE (fetch (REGION LEFT) of NEWREGION) (QUOTIENT (DIFFERENCE (TIMES (fetch (REGION WIDTH) of WINDOWREG) NEWSCALE) (fetch (REGION WIDTH) of NEWREGION)) 2)) NEWSCALE))) (* center the extra height) (SETQ NEWBOTTOM (FIXR (FQUOTIENT (DIFFERENCE (fetch (REGION BOTTOM) of NEWREGION) (QUOTIENT (DIFFERENCE (TIMES (fetch (REGION HEIGHT) of WINDOWREG) NEWSCALE) (fetch (REGION HEIGHT) of NEWREGION)) 2)) NEWSCALE))) (COND [(EQUAL OLDSCALE NEWSCALE) (* scale hasn't changed, just scroll) (RETURN (SKETCHW.SCROLLFN SKETCHW (DIFFERENCE NEWLEFT (fetch (REGION LEFT) of WINDOWREG)) (DIFFERENCE NEWBOTTOM (fetch (REGION BOTTOM) of WINDOWREG] (T (WINDOWPROP SKETCHW (QUOTE SCALE) NEWSCALE) (ABSWXOFFSET NEWLEFT SKETCHW) (ABSWYOFFSET NEWBOTTOM SKETCHW) (SK.UPDATE.GRIDFACTOR SKETCHW OLDSCALE) (RETURN (SK.UPDATE.AFTER.SCALE.CHANGE SKETCHW STOPIFMOUSEDOWN]) ) (RPAQ? AUTOZOOM.FACTOR .8) (RPAQ? AUTOZOOM.REPAINT.TIME 3000) (READVARS AUTOZOOMCURSOR ZOOMINCURSOR ZOOMOUTCURSOR) (({(READBITMAP)(16 16 "O@@O" "N@@G" "O@@O" "KJEM" "ANGH" "@NG@" "AOOH" "@BD@" "@BD@" "COOH" "@NG@" "ANGH" "KJEM" "OB@O" "N@@G" "O@@O")} 7 . 8) ({(READBITMAP)(16 16 "OLCO" "N@@G" "N@@G" "I@@I" "HHAA" "HDBA" "@BD@" "@@@@" "@@@@" "@BD@" "HDBA" "HHAA" "I@@I" "N@@G" "N@@G" "OLCO")} 7 . 8) ({(READBITMAP)(16 16 "H@@A" "DBDB" "BBDD" "ABDH" "@NG@" "@NG@" "GNGN" "@@@@" "@@@@" "GNGN" "@NG@" "@NG@" "ABDH" "BBDD" "DBDB" "H@@A")} 7 . 8)) (DECLARE: DOEVAL@COMPILE DONTCOPY (GLOBALVARS AUTOZOOM.FACTOR AUTOZOOM.REPAINT.TIME ZOOMINCURSOR ZOOMOUTCURSOR) ) (* fns for changing the view) (DEFINEQ (SKETCH.HOME [LAMBDA (SKW) (* rrb " 7-May-85 12:43") (* changes the scale of the figure being looked at in a window.) (PROG NIL (WINDOWPROP SKW (QUOTE SCALE) 1.0) (WXOFFSET (WXOFFSET NIL SKW) SKW) (WYOFFSET (WYOFFSET NIL SKW) SKW) (SK.UPDATE.AFTER.SCALE.CHANGE SKW]) (SK.FRAME.IT [LAMBDA (SKW) (* rrb "23-Oct-85 10:44") (* changes the region being viewed so that the entire sketch just fits.) (PROG ((SKETCH (INSURE.SKETCH SKW))) (COND ((NULL (fetch (SKETCH SKETCHELTS) of SKETCH)) (STATUSPRINT SKW "There is nothing in this sketch.")) (T (SKETCH.GLOBAL.REGION.ZOOM SKW (SKETCH.REGION.OF.SKETCH SKETCH]) (SK.MOVE.TO.VIEW [LAMBDA (SKW VIEW) (* rrb "28-Jun-85 18:16") (* restores a view by changing the position and scale of the figure being looked at in a window.) (PROG ((NEWSCALE (fetch (SKETCHVIEW VIEWSCALE) of VIEW)) (OLDSCALE (WINDOWPROP SKW (QUOTE SCALE))) SKREGWIDTH SKREGHEIGHT) (WINDOWPROP SKW (QUOTE SCALE) NEWSCALE) (WXOFFSET (WXOFFSET NIL SKW) SKW) (WXOFFSET (IMINUS (QUOTIENT (DIFFERENCE (fetch (SKETCHVIEW VIEWXPOSITION) of VIEW) (TIMES (QUOTIENT (WINDOWPROP SKW (QUOTE WIDTH)) 2) NEWSCALE)) NEWSCALE)) SKW) (WYOFFSET (WYOFFSET NIL SKW) SKW) (WYOFFSET (IMINUS (QUOTIENT (DIFFERENCE (fetch (SKETCHVIEW VIEWYPOSITION) of VIEW) (TIMES (QUOTIENT (WINDOWPROP SKW (QUOTE HEIGHT)) 2) NEWSCALE)) NEWSCALE)) SKW) (SK.UPDATE.GRIDFACTOR SKW OLDSCALE) (SK.UPDATE.AFTER.SCALE.CHANGE SKW]) (SK.NAME.CURRENT.VIEW [LAMBDA (SKW) (* rrb "25-Nov-85 17:46") (* reads a name from the user and adds the current view to the list of views) (PROG [(SKETCH (INSURE.SKETCH SKW)) (NAME (MKATOM (PROMPT.GETINPUT SKW "Name for this view: "] (COND (NAME [PUTSKETCHPROP SKETCH (QUOTE VIEWS) (APPEND (GETSKETCHPROP SKETCH (QUOTE VIEWS)) (CONS (create SKETCHVIEW VIEWNAME ← NAME VIEWSCALE ←(WINDOW.SCALE SKW) VIEWPOSITION ←(REGION.CENTER (SKETCH.REGION.VIEWED SKW] (STATUSPRINT SKW " ... done."]) (SKETCH.ADD.VIEW [LAMBDA (SKETCH NAME SCALE CENTERPOSITION) (* rrb "25-Nov-85 18:27") (* Adds a view to SKETCH.) (PROG ((SKETCH (INSURE.SKETCH SKETCH))) (COND (NAME (PUTSKETCHPROP SKETCH (QUOTE VIEWS) (APPEND (GETSKETCHPROP SKETCH (QUOTE VIEWS)) (CONS (create SKETCHVIEW VIEWNAME ← NAME VIEWSCALE ←(OR (NUMBERP SCALE) (\ILLEGAL.ARG SCALE)) VIEWPOSITION ←(OR (POSITIONP CENTERPOSITION) (\ILLEGAL.ARG CENTERPOSITION] ) (SK.RESTORE.VIEW [LAMBDA (SKW) (* rrb " 6-Nov-85 09:56") (* puts up a menu of the previously saved places in the sketch and moves to the one selected.) (PROG [(VIEW (\CURSOR.IN.MIDDLE.MENU (create MENU ITEMS ←(CONS (QUOTE (Home (QUOTE HOME) "returns to the origin at the original scale")) (for SAVEDVIEW in (GETSKETCHPROP (INSURE.SKETCH SKW) (QUOTE VIEWS)) collect (LIST (fetch (SKETCHVIEW VIEWNAME) of SAVEDVIEW) (KWOTE SAVEDVIEW) "returns the view to this location."))) TITLE ← "Which view?" CENTERFLG ← T] (* treat home specially so the user will always have one way back.) (COND ((EQ VIEW (QUOTE HOME)) (SKETCH.HOME SKW)) (VIEW (SK.MOVE.TO.VIEW SKW VIEW]) (SK.FORGET.VIEW [LAMBDA (SKW) (* rrb " 6-Nov-85 09:57") (* puts up a menu of the previously saved places in the sketch and lets the user select one to forget.) (PROG ((SKETCH (INSURE.SKETCH SKW)) VIEWS ONETOFORGET) (SETQ VIEWS (GETSKETCHPROP SKETCH (QUOTE VIEWS))) (COND ((NULL VIEWS) (STATUSPRINT SKW "There are no saved views. They are created with the 'Save view' command.") (RETURN))) (SETQ ONETOFORGET (MENU (create MENU ITEMS ←(for SAVEDVIEW in VIEWS collect (LIST (fetch (SKETCHVIEW VIEWNAME) of SAVEDVIEW) (KWOTE SAVEDVIEW) "removes this view.")) TITLE ← "Which view?" CENTERFLG ← T))) (COND (ONETOFORGET (PUTSKETCHPROP SKETCH (QUOTE VIEWS) (REMOVE ONETOFORGET VIEWS)) (STATUSPRINT SKW "View " (fetch (SKETCHVIEW VIEWNAME) of ONETOFORGET) " forgotten."]) ) (DECLARE: DONTCOPY [DECLARE: EVAL@COMPILE (RECORD SKETCHVIEW (VIEWNAME VIEWSCALE VIEWPOSITION) (RECORD VIEWPOSITION (VIEWXPOSITION . VIEWYPOSITION))) ] ) (* grid stuff) (DEFINEQ (SK.SET.GRID [LAMBDA (SKETCHW) (* rrb "25-Oct-84 12:40") (* switches from grided to non-grided or vice versa.) (COND ((WINDOWPROP SKETCHW (QUOTE USEGRID)) (SK.TURN.GRID.OFF SKETCHW)) (T (SK.TURN.GRID.ON SKETCHW]) (SK.DISPLAY.GRID [LAMBDA (SKETCHW) (* rrb " 1-Feb-85 15:35") (* displays the current grid.) (COND ((WINDOWPROP SKETCHW (QUOTE USEGRID))) (T (* grid was not being used, turn it on.) (SK.TURN.GRID.ON SKETCHW T))) (WINDOWPROP SKETCHW (QUOTE GRIDUP) T) (SK.DISPLAY.GRID.POINTS SKETCHW]) (SK.DISPLAY.GRID.POINTS [LAMBDA (SKETCHW NEWFLG) (* rrb "16-Jan-85 10:09") (SK.SHOW.GRID (SK.GRIDFACTOR SKETCHW) SKETCHW NEWFLG]) (SK.REMOVE.GRID.POINTS [LAMBDA (SKETCHW) (* rrb " 3-Feb-85 15:12") (* removes the grid by calling redisplay with the gridup property removed.) (WINDOWPROP SKETCHW (QUOTE GRIDUP) (PROG1 (WINDOWPROP SKETCHW (QUOTE GRIDUP) NIL) (REDISPLAYW SKETCHW]) (SK.TAKE.DOWN.GRID [LAMBDA (SKETCHW) (* rrb "25-Oct-84 12:07") (* takes down the grid if it is up.) (COND ((WINDOWPROP SKETCHW (QUOTE GRIDUP) NIL) (SK.REMOVE.GRID.POINTS SKETCHW]) (SK.SHOW.GRID [LAMBDA (GRID SKW NEWFLG) (* DECLARATIONS: FLOATING) (* rrb "25-Nov-85 17:46") (* puts a grid of size GRID onto SKW.) (PROG ((SCALE (WINDOW.SCALE SKW)) (REGION (SKETCH.REGION.VIEWED SKW))) (COND ((GREATERP 3.0 (FQUOTIENT GRID SCALE)) (* would be every point or so) (AND NEWFLG (STATUSPRINT SKW (CONCAT "New" " grid has a position every " (FQUOTIENT GRID SCALE) " screen points."))) NIL) (T (* make a horizontal bitmap that has the X pattern then blt it at the proper Y places.) [PROG ((WREG (DSPCLIPPINGREGION NIL SKW)) HORIZPATTERN WWIDTH WLEFT GRIDLEFT SKREGLEFT SKREGLIMIT) (SETQ WWIDTH (fetch (REGION WIDTH) of WREG)) (SETQ WLEFT (fetch (REGION LEFT) of WREG)) (SETQ HORIZPATTERN (BITMAPCREATE WWIDTH 1)) (SETQ GRIDLEFT (NEAREST.ON.GRID (SETQ SKREGLEFT (fetch (REGION LEFT) of REGION)) GRID)) (* put limit calculation outside of the loop.) (SETQ SKREGLIMIT (PLUS SKREGLEFT (fetch (REGION WIDTH) of REGION))) (for X from GRIDLEFT to SKREGLIMIT by GRID do (BITMAPBIT HORIZPATTERN (FIXR (FQUOTIENT (DIFFERENCE X SKREGLEFT) SCALE)) 0 1)) (SETQ SKREGLIMIT (PLUS (fetch (REGION BOTTOM) of REGION) (fetch (REGION HEIGHT) of REGION))) (for Y from (NEAREST.ON.GRID (fetch (REGION BOTTOM) of REGION) GRID) to SKREGLIMIT by GRID do (BITBLT HORIZPATTERN 0 0 SKW WLEFT (FIXR (FQUOTIENT Y SCALE)) WWIDTH 1 (QUOTE INPUT) (QUOTE PAINT] (COND ((GREATERP (FQUOTIENT GRID SCALE) (QUOTIENT (MIN (WINDOWPROP SKW (QUOTE HEIGHT)) (WINDOWPROP SKW (QUOTE WIDTH))) 3)) (* there aren't enough visible points so tell the user how far apart they are.) (STATUSPRINT SKW (CONCAT (COND (NEWFLG "New") (T "Current")) " grid has a position every " (FIXR (FQUOTIENT GRID SCALE)) " screen points."]) (SK.GRIDFACTOR [LAMBDA (SKETCHW GRIDSIZE) (* rrb "25-Oct-84 12:34") (* sets the grid factor of a window to GRIDSIZE. Returns the previous setting. The actual use of the grid is determined by (QUOTE USEGRID) property.) (COND ((NUMBERP GRIDSIZE) (WINDOWPROP SKETCHW (QUOTE GRIDFACTOR) GRIDSIZE)) (GRIDSIZE (\ILLEGAL.ARG GRIDSIZE) (WINDOWPROP SKETCHW (QUOTE GRIDFACTOR))) (T (WINDOWPROP SKETCHW (QUOTE GRIDFACTOR]) (SK.TURN.GRID.ON [LAMBDA (SKETCHW QUIETFLG) (* rrb "25-Oct-84 12:04") (* turns the grid on.) (COND ((WINDOWPROP SKETCHW (QUOTE USEGRID) T) (OR QUIETFLG (STATUSPRINT SKETCHW "The grid was already in use."]) (SK.TURN.GRID.OFF [LAMBDA (SKETCHW) (* rrb "25-Oct-84 12:03") (* turns the grid off.) (COND ((WINDOWPROP SKETCHW (QUOTE USEGRID) NIL) (SK.TAKE.DOWN.GRID SKETCHW)) (T (STATUSPRINT SKETCHW "The grid was not is use."]) (SK.MAKE.GRID.LARGER [LAMBDA (SKETCHW) (* rrb "25-Oct-84 12:15") (* makes the grid larger. If the grid is off, it turns it on.) (SK.CHANGE.GRID (FTIMES (SK.GRIDFACTOR SKETCHW) 2.0) SKETCHW]) (SK.MAKE.GRID.SMALLER [LAMBDA (SKETCHW) (* rrb "25-Oct-84 12:15") (* makes the grid smaller. If the grid is off, it turns it on.) (SK.CHANGE.GRID (FTIMES (SK.GRIDFACTOR SKETCHW) .5) SKETCHW]) (SK.CHANGE.GRID [LAMBDA (NEWGRID SKETCHW) (* rrb " 1-Feb-85 15:52") (* changes the grid of a window. Turns the grid on if it isn't already on.) (SK.TURN.GRID.ON SKETCHW T) (AND (WINDOWPROP SKETCHW (QUOTE GRIDUP)) (SK.REMOVE.GRID.POINTS SKETCHW)) (SK.GRIDFACTOR SKETCHW NEWGRID) (AND (WINDOWPROP SKETCHW (QUOTE GRIDUP)) (SK.DISPLAY.GRID.POINTS SKETCHW T]) (GRID.FACTOR1 [LAMBDA (REALHEIGHT HEIGHTONSCREEN NPTS) (* rrb "19-Jun-84 17:26") (* returns the greatest power of two such that REALHEIGHT maps onto SCREENHEIGHT leaving at least NPTS per grid.) (LEASTPOWEROF2GT (FQUOTIENT (FTIMES NPTS REALHEIGHT) HEIGHTONSCREEN]) (LEASTPOWEROF2GT [LAMBDA (FLOATP) (* rrb "20-Jun-84 18:57") (* returns the number which is the least power of two that is greater than FLOATP.) (PROG [(LOG2 (FQUOTIENT (LOG FLOATP) (CONSTANT (LOG 2] (RETURN (COND [(FGREATERP LOG2 0.0) (COND ((EQUAL LOG2 (FLOAT (FIX LOG2))) (* special case of exact hit.) (EXPT 2.0 (FIX LOG2))) (T (EXPT 2.0 (ADD1 (FIX LOG2] (T (EXPT 2.0 (FIX LOG2]) (GREATESTPOWEROF2LT [LAMBDA (FLOATP) (* rrb " 9-Jul-85 17:43") (* returns the number which is the greatest power of two that is less than FLOATP.) (PROG [(LOG2 (FQUOTIENT (LOG FLOATP) (CONSTANT (LOG 2] (RETURN (COND ((FGREATERP LOG2 0.0) (EXPT 2.0 (FIX LOG2))) ((EQUAL LOG2 (FLOAT (FIX LOG2))) (* special case of exact hit.) (EXPT 2.0 (FIX LOG2))) (T (EXPT 2.0 (SUB1 (FIX LOG2]) (SK.DEFAULT.GRIDFACTOR [LAMBDA (SKETCHW) (* rrb "25-Nov-85 17:46") (* returns the default grid factor for a window. Starts at about a quarter inch.) (GRID.FACTOR1 (fetch (REGION HEIGHT) of (SKETCH.REGION.VIEWED SKETCHW)) (WINDOWPROP SKETCHW (QUOTE HEIGHT)) DEFAULTGRIDSIZE]) (SK.PUT.ON.GRID [LAMBDA (GPOSITION GRID) (* rrb " 7-Feb-85 11:32") (* returns the grid point that is closest to GPOSITION.) (create POSITION XCOORD ←(NEAREST.ON.GRID (fetch (POSITION XCOORD) of GPOSITION) GRID) YCOORD ←(NEAREST.ON.GRID (fetch (POSITION YCOORD) of GPOSITION) GRID]) (MAP.WINDOW.ONTO.GRID [LAMBDA (X SCALE GRID) (* rrb "20-Jun-84 16:53") (* maps from a window point onto the window point that is closest to GRID.) (FIXR (QUOTIENT (NEAREST.ON.GRID (TIMES X SCALE) GRID) SCALE]) (MAP.SCREEN.ONTO.GRID [LAMBDA (X SCALE GRID WOFFSET) (* rrb "20-Jun-84 16:22") (* maps a screen coordinate into the screen coordinate that is closest to the grid of a window with offset WOFFSET.) (COND ((OR (NOT GRID) (EQ GRID 0) (EQP GRID 0.0)) X) (T (IPLUS (MAP.WINDOW.ONTO.GRID (IDIFFERENCE X WOFFSET) SCALE GRID) WOFFSET]) (MAP.GLOBAL.PT.ONTO.GRID [LAMBDA (PT SKW) (* rrb " 7-Feb-85 11:33") (* If the grid is in use, maps from a point in global coordinates into the closest grid point in global coordinates.) (COND ((WINDOWPROP SKW (QUOTE USEGRID)) (SK.PUT.ON.GRID PT (SK.GRIDFACTOR SKW))) (T PT]) (MAP.GLOBAL.REGION.ONTO.GRID [LAMBDA (GREGION SKW) (* rrb "25-Jan-85 10:50") (* If the grid is in use, maps from a region in global coordinates into the closest larger region in global coordinates.) (COND [(WINDOWPROP SKW (QUOTE USEGRID)) (PROG ((GRID (SK.GRIDFACTOR SKW)) HALFGRID NEWLEFT NEWBOTTOM) (SETQ HALFGRID (QUOTIENT GRID 2.0)) (RETURN (CREATEREGION (SETQ NEWLEFT (NEAREST.ON.GRID (DIFFERENCE (fetch (REGION LEFT) of GREGION) HALFGRID) GRID)) (SETQ NEWBOTTOM (NEAREST.ON.GRID (DIFFERENCE (fetch (REGION BOTTOM) of GREGION) HALFGRID) GRID)) (DIFFERENCE (NEAREST.ON.GRID (PLUS (fetch (REGION RIGHT) of GREGION) HALFGRID) GRID) NEWLEFT) (DIFFERENCE (NEAREST.ON.GRID (PLUS (fetch (REGION TOP) of GREGION) HALFGRID) GRID) NEWBOTTOM] (T GREGION]) (MAP.WINDOW.POINT.ONTO.GLOBAL.GRID [LAMBDA (PT SCALE GRID) (* rrb " 1-Feb-85 14:08") (* maps from a point in window coordinates into the closest grid point in global coordinates.) (create POSITION XCOORD ←(MAP.WINDOW.ONTO.GLOBAL.GRID (fetch (POSITION XCOORD) of PT) SCALE GRID) YCOORD ←(MAP.WINDOW.ONTO.GLOBAL.GRID (fetch (POSITION YCOORD) of PT) SCALE GRID]) (MAP.WINDOW.ONTO.GLOBAL.GRID [LAMBDA (X SCALE GRID) (* rrb " 1-Feb-85 14:08") (* maps from a window point onto the window point that is closest to GRID.) (NEAREST.ON.GRID (TIMES X SCALE) GRID]) (SK.UPDATE.GRIDFACTOR [LAMBDA (SKW OLDSCALE) (* rrb "25-Nov-85 17:46") (* determines the size of the grid for the newly scaled window.) (PROG ((OLDGRID (SK.GRIDFACTOR SKW)) X) (SK.GRIDFACTOR SKW (GRID.FACTOR1 (fetch (REGION HEIGHT) of (SKETCH.REGION.VIEWED SKW)) (WINDOWPROP SKW (QUOTE HEIGHT)) (IMIN DEFAULTMAXGRIDSIZE (FQUOTIENT OLDGRID OLDSCALE]) (SK.MAP.FROM.WINDOW.TO.GLOBAL.GRID [LAMBDA (POSITION SKETCHW) (* rrb " 1-Feb-85 14:41") (* maps from a position in a window to the corresponding global position taking into account the grid if it is in use.) (COND ((WINDOWPROP SKETCHW (QUOTE USEGRID)) (MAP.WINDOW.POINT.ONTO.GLOBAL.GRID POSITION (WINDOW.SCALE SKETCHW) (SK.GRIDFACTOR SKETCHW))) (T (UNSCALE.POSITION POSITION (WINDOW.SCALE SKETCHW]) (SK.MAP.INPUT.PT.TO.GLOBAL [LAMBDA (POSSPEC SKETCHW) (* rrb " 3-Oct-85 17:57") (* maps from a position ala GETSKWPOSITION in a window to the corresponding global position (POSITION is a list of (GRIDON? position))) (AND POSSPEC (COND ((fetch (INPUTPT INPUT.ONGRID?) of POSSPEC) (MAP.WINDOW.POINT.ONTO.GLOBAL.GRID (fetch (INPUTPT INPUT.POSITION) of POSSPEC) (WINDOW.SCALE SKETCHW) (SK.GRIDFACTOR SKETCHW))) (T (* map the point onto a grid location that would have the same screen position as the given point.) (SK.MAP.FROM.WINDOW.TO.NEAREST.GRID (fetch (INPUTPT INPUT.POSITION) of POSSPEC) (WINDOW.SCALE SKETCHW) T]) (SK.MAP.FROM.WINDOW.TO.NEAREST.GRID [LAMBDA (POSITION SCALE NOMOVEFLG) (* rrb " 3-Oct-85 14:16") (* maps from a point in a window to the closest grid position in the global space that has a distance between the points of less than 1.0) (PROG [(GRID (COND (NOMOVEFLG (* if NOMOVEFLG is on, use a grid small enough that the mapping into and out of coordinate space will leave POSITION unchanged. For most uses, this is too fine.) (GREATESTPOWEROF2LT SCALE)) (T (LEASTPOWEROF2GT (TIMES SCALE 2] (RETURN (create POSITION XCOORD ←(NEAREST.ON.GRID (TIMES (fetch (POSITION XCOORD) of POSITION) SCALE) GRID) YCOORD ←(NEAREST.ON.GRID (TIMES (fetch (POSITION YCOORD) of POSITION) SCALE) GRID]) ) (RPAQ? DEFAULTGRIDSIZE 8) (RPAQ? DEFAULTMINGRIDSIZE 4) (RPAQ? DEFAULTMAXGRIDSIZE 32) (* sketch icon support) (DEFINEQ (SKETCH.TITLE [LAMBDA (SKW) (* rrb " 3-Jan-85 12:17") (* gets the title of the sketch being edited in SKW.) (fetch (SKETCH SKETCHNAME) of (INSURE.SKETCH (SKETCH.FROM.VIEWER SKW]) (SK.SHRINK.ICONCREATE [LAMBDA (W) (* rrb " 3-Jan-85 12:16") (* Create the icon that represents this window.) (PROG [(ICON (WINDOWPROP W (QUOTE ICON))) (ICONTITLE (WINDOWPROP W (QUOTE SKETCH.ICON.TITLE] (COND ((OR (AND ICONTITLE (EQUAL ICONTITLE (SKETCH.TITLE W))) (AND (NOT ICONTITLE) ICON)) (* we built this and the title is the same, or he has already put an icon on this. Do nothing) NIL) (ICON (* There's an existing icon window; change the title in it) (WINDOWPROP W (QUOTE SKETCH.ICON.TITLE) (SETQ ICONTITLE (SKETCH.TITLE W))) (ICONTITLE ICONTITLE NIL NIL ICON)) (T (* install a new icon) (WINDOWPROP W (QUOTE SKETCH.ICON.TITLE) (SETQ ICONTITLE (SKETCH.TITLE W))) (WINDOWPROP W (QUOTE ICON) (TITLEDICONW SKETCH.TITLED.ICON.TEMPLATE ICONTITLE TEDIT.ICON.FONT NIL T]) ) (READVARS SKETCH.TITLED.ICON.TEMPLATE) (({(READBITMAP)(87 95 "AOOOOOOOOOOOOOOOOOOOOL@@" "GOOOOOOOOOOOOOOOOOOOOL@@" "OKMHOHNCHNCHNCHNCHNCHN@@" "OOOOOOOOOOOOOOOOOOOOON@@" "ONJJCLGALGALGALGALGALF@@" "LOOOOOOOOOOOOOOOOOOOON@@" "NKOJCLGALGALGALGALGALF@@" "ONOOOOOOOOOOOOOOOOOOON@@" "NJJOOOOOOOOOOOOOOOOOON@@" "NNKNGALGALGALGALGALGAL@@" "OJJNOCLOCLOCLOCLOCLOCN@@" "NJJNFAHFAHFAHFAHFAHFAN@@" "NNJN@@@@@@@@@@@@@@@@@N@@" "OJJN@@@@@@@@@@@@@@@@@N@@" "OJKN@@@@@@@@@@@@@@@@@N@@" "NJKN@@@@@@@@@@@@@@@@@N@@" "OKNN@@@@@@@@@@@@@@@@@N@@" "OKJN@@@@@@@@@@@@@@@@@N@@" "NJJN@@@@@@@@@@@@@@@@@N@@" "NJNN@@@@@@@@@@@@@@@@@N@@" "NKJN@@@@@@@@@@@@@@@@@N@@" "NJJN@@@@@@@@@@@@@@@@@N@@" "NNKN@@@@@@@@@@@@@@@@@N@@" "NNKN@@@@@@@@@@@@@@@@@N@@" "OJNN@@@@@@@@@@@@@@@@@N@@" "NJNN@@@@@@@@@@@@@@@@@N@@" "OJNN@@@@@@@@@@@@@@@@@N@@" "OJJN@@@@@@@@@@@@@@@@@N@@" "NNNN@@@@@@@@@@@@@@@@@N@@" "NNNN@@@@@@@@@@@@@@@@@N@@" "NJNN@@@@@@@@@@@@@@@@@N@@" "NJKN@@@@@@@@@@@@@@@@@N@@" "NJJN@@@@@@@@@@@@@@@@@N@@" "L@@N@@@@@@@@@@@@@@@@@N@@" "L@@N@@@@@@@@@@@@@@@@@N@@" "L@BN@@@@@@@@@@@@@@@@@N@@" "L@NN@@@@@@@@@@@@@@@@@N@@" "LA@N@@@@@@@@@@@@@@@@@N@@" "MM@N@@@@@@@@@@@@@@@@@N@@" "LCBN@@@@@@@@@@@@@@@@@N@@" "L@NN@@@@@@@@@@@@@@@@@N@@" "L@BN@@@@@@@@@@@@@@@@@N@@" "L@@N@@@@@@@@@@@@@@@@@N@@" "L@@N@@@@@@@@@@@@@@@@@N@@" "LB@N@@@@@@@@@@@@@@@@@N@@" "LDDN@@@@@@@@@@@@@@@@@N@@" "LDBN@@@@@@@@@@@@@@@@@N@@" "LBBN@@@@@@@@@@@@@@@@@N@@" "LALN@@@@@@@@@@@@@@@@@N@@" "L@@N@@@@@@@@@@@@@@@@@N@@" "L@@N@@@@@@@@@@@@@@@@@N@@" "L@@N@@@@@@@@@@@@@@@@@N@@" "LDDN@@@@@@@@@@@@@@@@@N@@" "MLBN@@@@@@@@@@@@@@@@@N@@" "LGBN@@@@@@@@@@@@@@@@@N@@" "LDNN@@@@@@@@@@@@@@@@@N@@" "L@@N@@@@@@@@@@@@@@@@@N@@" "L@@N@@@@@@@@@@@@@@@@@N@@" "L@@N@@@@@@@@@@@@@@@@@N@@" "LC@N@@@@@@@@@@@@@@@@@N@@" "LDHN@@@@@@@@@@@@@@@@@N@@" "LDJN@@@@@@@@@@@@@@@@@N@@" "LCJN@@@@@@@@@@@@@@@@@N@@" "LABN@@@@@@@@@@@@@@@@@N@@" "L@NN@@@@@@@@@@@@@@@@@N@@" "L@@N@@@@@@@@@@@@@@@@@N@@" "LD@N@@@@@@@@@@@@@@@@@N@@" "LB@N@@@@@@@@@@@@@@@@@N@@" "MBNN@@@@@@@@@@@@@@@@@N@@" "MM@N@@@@@@@@@@@@@@@@@N@@" "LCHN@@@@@@@@@@@@@@@@@N@@" "L@FN@@@@@@@@@@@@@@@@@N@@" "L@BN@@@@@@@@@@@@@@@@@N@@" "L@@N@@@@@@@@@@@@@@@@@N@@" "LH@N@@@@@@@@@@@@@@@@@N@@" "M@@N@@@@@@@@@@@@@@@@@N@@" "MAHN@@@@@@@@@@@@@@@@@N@@" "MBDN@@@@@@@@@@@@@@@@@N@@" "MBDN@@@@@@@@@@@@@@@@@N@@" "LLDN@@@@@@@@@@@@@@@@@N@@" "L@DN@@@@@@@@@@@@@@@@@N@@" "L@DN@@@@@@@@@@@@@@@@@N@@" "L@LN@@@@@@@@@@@@@@@@@N@@" "L@@N@@@@@@@@@@@@@@@@@N@@" "L@@N@@@@@@@@@@@@@@@@@N@@" "NJJN@@@@@@@@@@@@@@@@@N@@" "OJJN@@@@@@@@@@@@@@@@@N@@" "NKKN@@@@@@@@@@@@@@@@@N@@" "OJNN@@@@@@@@@@@@@@@@@N@@" "CNNN@@@@@@@@@@@@@@@@@N@@" "@OJN@@@@@@@@@@@@@@@@@N@@" "@CNN@@@@@@@@@@@@@@@@@N@@" "@@OOOOOOOOOOOOOOOOOOON@@" "@@COOOOOOOOOOOOOOOOOON@@" "@@@OOOOOOOOOOOOOOOOOON@@")} {(READBITMAP)(87 95 "AOOOOOOOOOOOOOOOOOOOOH@@" "GOOOOOOOOOOOOOOOOOOOOL@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "OOOOOOOOOOOOOOOOOOOOON@@" "COOOOOOOOOOOOOOOOOOOON@@" "@OOOOOOOOOOOOOOOOOOOON@@" "@COOOOOOOOOOOOOOOOOOON@@" "@@OOOOOOOOOOOOOOOOOOON@@" "@@COOOOOOOOOOOOOOOOOON@@" "@@@OOOOOOOOOOOOOOOOOON@@")} (16 4 64 77))) (* history and undo stuff) (DEFINEQ (SK.ADD.HISTEVENT [LAMBDA (EVENTTYPE EVENTARGS SKETCHW) (* rrb "11-Jan-85 18:04") (* puts a history event on a sketch window.) (* trim to a given length) (PROG [(HISTLST (WINDOWPROP SKETCHW (QUOTE SKETCHHISTORY] (WINDOWPROP SKETCHW (QUOTE SKETCHHISTORY) (CONS (create SKHISTEVENT EVENTTYPE ← EVENTTYPE EVENTARGS ← EVENTARGS) (COND ((GREATERP SKETCH.#.UNDO.ITEMS (LENGTH HISTLST)) (* there is room for one more) HISTLST) (T (REMOVE.LAST HISTLST]) (SK.SEL.AND.UNDO [LAMBDA (SKW) (* rrb " 5-Dec-85 17:18") (* gives the user a choice of past events to undo.) (SKED.CLEAR.SELECTION SKW) (PROG [EVENT UNDOFN (HISTLST (WINDOWPROP SKW (QUOTE SKETCHHISTORY] (COND ((NULL HISTLST) (STATUSPRINT SKW "Nothing to undo.") (RETURN))) (COND ([SETQ EVENT (\CURSOR.IN.MIDDLE.MENU (create MENU ITEMS ←(for EVENT in HISTLST collect (LIST (SK.UNDO.NAME EVENT) EVENT)) WHENSELECTEDFN ←(FUNCTION CADR) TITLE ← "Select event to undo" WHENHELDFN ←(FUNCTION (LAMBDA ( ITEM MENU BUTTON) (PROMPTPRINT "Will undo this event."] (COND ((fetch (SKHISTEVENT UNDONE?) of EVENT) (* can't undo already undone event. They are included in the menu to provide session continuity.) (STATUSPRINT SKW "That event has already been undone.") (RETURN NIL)) ([NULL (SETQ UNDOFN (fetch (SKEVENTTYPE SKUNDOFN) of (SKEVENTTYPEFNS (fetch (SKHISTEVENT EVENTTYPE) of EVENT] (STATUSPRINT SKW "Can't undo that event.") (RETURN NIL))) (COND ((APPLY* UNDOFN (fetch (SKHISTEVENT EVENTARGS) of EVENT) SKW EVENT) (* only add to history list if something happened.) (replace (SKHISTEVENT UNDONE?) of EVENT with T) (SK.ADD.HISTEVENT (QUOTE UNDO) EVENT SKW)) ((NOT (EQ UNDOFN (QUOTE SK.UNDO.UNDO))) (STATUSPRINT SKW "Element subsequently modified, can't undo"]) (SK.UNDO.LAST [LAMBDA (SKW) (* rrb " 5-Dec-85 17:19") (* undoes the first not yet undone history event.) (SKED.CLEAR.SELECTION SKW) (PROG [EVENT UNDOFN (HISTLST (WINDOWPROP SKW (QUOTE SKETCHHISTORY] (COND ((NULL HISTLST) (STATUSPRINT SKW "Nothing to undo.") (RETURN))) (COND [(SETQ EVENT (for HISTEVENT in HISTLST when [AND (NOT (EQ (fetch (SKHISTEVENT EVENTTYPE) of HISTEVENT) (QUOTE UNDO))) (NOT (fetch (SKHISTEVENT UNDONE?) of HISTEVENT)) (SETQ UNDOFN (fetch (SKEVENTTYPE SKUNDOFN) of (SKEVENTTYPEFNS (fetch (SKHISTEVENT EVENTTYPE) of HISTEVENT] do (RETURN HISTEVENT))) (COND ((APPLY* UNDOFN (fetch (SKHISTEVENT EVENTARGS) of EVENT) SKW EVENT) (* only add to history list if something happened.) (STATUSPRINT SKW (SK.UNDO.NAME EVENT) " event undone.") (replace (SKHISTEVENT UNDONE?) of EVENT with T) (SK.ADD.HISTEVENT (QUOTE UNDO) EVENT SKW)) ((NOT (EQ UNDOFN (QUOTE SK.UNDO.UNDO))) (STATUSPRINT SKW "Element subsequently modified, can't undo"] (T (STATUSPRINT SKW " " "All events have been undone. Use the '?UNDO' subcommand to undo an UNDO command."]) (SK.UNDO.NAME [LAMBDA (HISTEVENT) (* rrb "17-Apr-84 11:27") (* returns the menu label for HISTEVENT.) (APPLY* (fetch (SKEVENTTYPE SKUNDONAMEFN) of (SKEVENTTYPEFNS (fetch (SKHISTEVENT EVENTTYPE) of HISTEVENT))) HISTEVENT]) (SKEVENTTYPEFNS [LAMBDA (EVENTTYPE) (* rrb "17-Apr-84 11:02") (* returns the list of type related functions associated with EVENTTYPE.) (GETPROP EVENTTYPE (QUOTE EVENTFNS]) (SK.TYPE.OF.FIRST.ARG [LAMBDA (HISTEVENT NOMARKUNDOFLG) (* rrb "10-Dec-85 17:55") (* returns a name suitable for a menu label for an history event by combining the event name with the type of its arg.) (PROG ((ARGS (fetch (SKHISTEVENT EVENTARGS) of HISTEVENT)) (TYPE (fetch (SKHISTEVENT EVENTTYPE) of HISTEVENT))) (RETURN (CONCAT (COND ((AND (NULL NOMARKUNDOFLG) (fetch (SKHISTEVENT UNDONE?) of HISTEVENT)) "*") (T " ")) TYPE " " (COND ((CDR ARGS) (QUOTE "a group")) (T (SELECTQ TYPE ((GROUP UNGROUP) "") [(MOVE CHANGE) (SK.LABEL.FROM.TYPE (fetch (GLOBALPART GTYPE) of (CAAR ARGS] (SK.LABEL.FROM.TYPE (fetch (GLOBALPART GTYPE) of (CAR ARGS]) ) (DEFINEQ (SK.DELETE.UNDO [LAMBDA (EVENTARGS SKW) (* rrb "11-Sep-84 14:57") (* undoes a delete event) (PROG (CHANGED?) [for GELT in EVENTARGS do (COND ((SK.ADD.ELEMENT GELT SKW) (SETQ CHANGED? T] (RETURN CHANGED?]) (SK.ADD.UNDO [LAMBDA (EVENTARGS SKW) (* rrb "11-Sep-84 15:58") (* undoes an add event) (PROG (CHANGED?) [for GELT in EVENTARGS do (COND ((SK.DELETE.ELEMENT1 GELT SKW) (SETQ CHANGED? T] (RETURN CHANGED?]) ) (DEFINEQ (SK.CHANGE.UNDO [LAMBDA (EVENTARGS SKW) (* rrb "11-Sep-84 15:57") (* undoes a change event) (* the args for a change event are the old {previous} global part of the element and the new global part of the element.) (PROG (CHANGED?) [for PAIR in EVENTARGS do (COND ((SK.UPDATE.ELEMENT (CADR PAIR) (CAR PAIR) SKW) (SETQ CHANGED? T] (RETURN CHANGED?]) (SK.CHANGE.REDO [LAMBDA (EVENTARGS SKW) (* rrb "10-Sep-84 17:01") (* redoes a change event) (PROG (CHANGE) (for PAIR in EVENTARGS do (AND (SK.UPDATE.ELEMENT (CAR PAIR) (CADR PAIR) SKW) (SETQ CHANGE T))) (OR CHANGE (STATUSPRINT SKW "That sketch element has been changed by something else, can't redo."]) ) (DEFINEQ (SK.UNDO.UNDO [LAMBDA (UNDONEEVENT SKW THISEVENT) (* rrb "18-Apr-84 15:32") (* undoes an UNDO event by calling the REDO fn of that event type.) (PROG (REDOFN) (COND ([SETQ REDOFN (fetch (SKEVENTTYPE SKREDOFN) of (SKEVENTTYPEFNS (fetch (SKHISTEVENT EVENTTYPE) of UNDONEEVENT] (APPLY* REDOFN (fetch (SKHISTEVENT EVENTARGS) of UNDONEEVENT) SKW) (replace (SKHISTEVENT UNDONE?) of UNDONEEVENT with NIL) (* remove the undo event from the history list.) (WINDOWDELPROP SKW (QUOTE SKETCHHISTORY) THISEVENT)) (T (STATUSPRINT SKW "Can't undo that event."))) (* always return NIL so the undoing of an undo event won't be added as an event.) (RETURN NIL]) (SK.UNDO.MENULABEL [LAMBDA (UNDOEVENT) (* rrb "18-Sep-84 11:53") (* returns a name suitable for a menu label for an UNDO history event by combining the event name with the type of its arg.) (CONCAT "undo" (SK.TYPE.OF.FIRST.ARG (fetch (SKHISTEVENT EVENTARGS) of UNDOEVENT) T]) (SK.LABEL.FROM.TYPE [LAMBDA (SKELEMENTTYPE) (* rrb " 4-Jun-85 13:40") (* takes a type name and returns the label for it. These two are different because the names changed since the first sketchs were made.) (SELECTQ SKELEMENTTYPE (WIRE (QUOTE LINE)) (OPENCURVE (QUOTE CURVE)) (CLOSEDWIRE (QUOTE POLYGON)) SKELEMENTTYPE]) ) (DECLARE: DONTCOPY [DECLARE: EVAL@COMPILE (RECORD SKHISTEVENT (EVENTTYPE EVENTARGS UNDONE?)) (RECORD SKEVENTTYPE (SKUNDOFN SKUNDONAMEFN SKREDOFN)) ] ) (RPAQ? SKETCH.#.UNDO.ITEMS 30) (DECLARE: DOEVAL@COMPILE DONTCOPY (GLOBALVARS SKETCH.#.UNDO.ITEMS) ) (PUTPROPS ADD EVENTFNS (SK.ADD.UNDO SK.TYPE.OF.FIRST.ARG SK.DELETE.UNDO)) (PUTPROPS DELETE EVENTFNS (SK.DELETE.UNDO SK.TYPE.OF.FIRST.ARG SK.ADD.UNDO)) (PUTPROPS CHANGE EVENTFNS (SK.CHANGE.UNDO SK.TYPE.OF.FIRST.ARG SK.CHANGE.REDO)) (PUTPROPS UNDO EVENTFNS (SK.UNDO.UNDO SK.UNDO.MENULABEL SHOULDNT)) (PUTPROPS MOVE EVENTFNS (SK.CHANGE.UNDO SK.TYPE.OF.FIRST.ARG SK.CHANGE.REDO)) (PUTPROPS COPY EVENTFNS (SK.ADD.UNDO SK.TYPE.OF.FIRST.ARG SK.DELETE.UNDO)) (* functions for hardcopying) (DEFINEQ (SKETCHW.HARDCOPYFN [LAMBDA (SKETCHW OPENIMAGESTREAM) (* rrb "25-Nov-85 17:46") (* dumps the sketch onto OPENIMAGESTREAM.) (* centers it within the DSPCLIPPINGREGION of OPENIMAGESTREAM) (PROG ((SKETCH (INSURE.SKETCH (SKETCH.FROM.VIEWER SKETCHW))) (VIEWREGION (DSPCLIPPINGREGION NIL SKETCHW)) (PAGEREGION (DSPCLIPPINGREGION NIL OPENIMAGESTREAM)) (SKETCHREGION (SKETCH.REGION.VIEWED SKETCHW)) (SCALE (WINDOW.SCALE SKETCHW)) SKETCHREGIONINPAGECOORDS PAGELEFTSPACE PAGEBOTTOMSPACE PAGETOSKETCHFACTOR SKETCHX) (OR SKETCH (RETURN)) (SPAWN.MOUSE) (* PAGETOSKETCHFACTOR is the factor to multiply the page coordinates by to get into sketch coordinates.) (STATUSPRINT SKETCHW "Hardcopying ...") (SETQ PAGETOSKETCHFACTOR (FQUOTIENT SCALE (DSPSCALE NIL OPENIMAGESTREAM))) (SETQ SKETCHREGIONINPAGECOORDS (SCALE.REGION SKETCHREGION PAGETOSKETCHFACTOR)) (COND ((AND (IMAGESTREAMTYPEP OPENIMAGESTREAM (QUOTE INTERPRESS)) (GREATERP (fetch WIDTH of SKETCHREGIONINPAGECOORDS) (fetch WIDTH of PAGEREGION)) (GREATERP (fetch WIDTH of SKETCHREGIONINPAGECOORDS) (fetch HEIGHT of SKETCHREGIONINPAGECOORDS))) (* Print in landscape mode) (* only know the hack for interpress streams.) (* Hack to coerce interpress stream into landscapemode) (ROTATE.IP OPENIMAGESTREAM 90) (CONCATT.IP OPENIMAGESTREAM) (TRANSLATE.IP OPENIMAGESTREAM 0 -21590) (CONCATT.IP OPENIMAGESTREAM) (DSPCLIPPINGREGION (SETQ PAGEREGION (SK.SWITCH.REGION.X.AND.Y PAGEREGION)) OPENIMAGESTREAM) (* End HACK) )) (SETQ PAGELEFTSPACE (QUOTIENT (DIFFERENCE (fetch (REGION WIDTH) of PAGEREGION) (fetch (REGION WIDTH) of SKETCHREGIONINPAGECOORDS)) 2)) (SETQ PAGEBOTTOMSPACE (QUOTIENT (DIFFERENCE (fetch (REGION HEIGHT) of PAGEREGION) (fetch (REGION HEIGHT) of SKETCHREGIONINPAGECOORDS)) 2)) (* translate the sketch so that the lower left corner of the sketch region is at the lower left corner of the image on the page.) [SETQ SKETCHX (TRANSLATE.SKETCH SKETCH (MINUS (TIMES (DIFFERENCE (SETQ PAGELEFTSPACE (PLUS (fetch (REGION LEFT) of PAGEREGION) PAGELEFTSPACE)) (fetch (REGION LEFT) of SKETCHREGIONINPAGECOORDS)) PAGETOSKETCHFACTOR)) (MINUS (TIMES (DIFFERENCE (SETQ PAGEBOTTOMSPACE (PLUS (fetch (REGION BOTTOM) of PAGEREGION) PAGEBOTTOMSPACE)) (fetch (REGION BOTTOM) of SKETCHREGIONINPAGECOORDS)) PAGETOSKETCHFACTOR] (* calculate the local parts for the interpress sketch.) (SETQ SKETCHX (MAKE.LOCAL.SKETCH SKETCHX (CREATEREGION (TIMES PAGELEFTSPACE PAGETOSKETCHFACTOR) (TIMES PAGEBOTTOMSPACE PAGETOSKETCHFACTOR) (fetch (REGION WIDTH) of SKETCHREGION) (fetch (REGION HEIGHT) of SKETCHREGION)) PAGETOSKETCHFACTOR OPENIMAGESTREAM T)) (DRAW.LOCAL.SKETCH SKETCHX OPENIMAGESTREAM (CREATEREGION PAGELEFTSPACE PAGEBOTTOMSPACE (fetch (REGION WIDTH) of SKETCHREGIONINPAGECOORDS) (fetch (REGION HEIGHT) of SKETCHREGIONINPAGECOORDS))) (STATUSPRINT SKETCHW " done.") (RETURN OPENIMAGESTREAM]) (\SK.LIST.PAGE.IMAGE [LAMBDA (OPENIMAGESTREAM REGIONINSKETCH LOCALSKELTS PAGETOSKETCHFACTOR REGIONONPAGE SKETCHTOWINDOWFACTOR) (* rrb " 9-Jul-85 12:37") (* draws the image of a set of sketch elements on an OPENIMAGESTREAM.) (PROG ((SCALEDSKETCHREGION (SCALE.REGION REGIONINSKETCH SKETCHTOWINDOWFACTOR)) ELTSINREGION SKETCHX) (COND ((SETQ ELTSINREGION (for LOCALSKELT in LOCALSKELTS when (REGIONSINTERSECTP SCALEDSKETCHREGION (SK.ITEM.REGION LOCALSKELT)) collect (fetch (SCREENELT GLOBALPART) of LOCALSKELT))) (* translate the sketch so that the right stuff appears in the region on the page.) [SETQ SKETCHX (TRANSLATE.SKETCH (create SKETCH SKETCHELTS ← ELTSINREGION) (DIFFERENCE (fetch (REGION LEFT) of REGIONINSKETCH) (TIMES (fetch (REGION LEFT) of REGIONONPAGE) PAGETOSKETCHFACTOR)) (DIFFERENCE (fetch (REGION BOTTOM) of REGIONINSKETCH) (TIMES (fetch (REGION BOTTOM) of REGIONONPAGE) PAGETOSKETCHFACTOR] (SETQ SKETCHX (MAKE.LOCAL.SKETCH SKETCHX (CREATEREGION 0 0 (fetch (REGION WIDTH) of REGIONINSKETCH) (fetch (REGION HEIGHT) of REGIONINSKETCH)) PAGETOSKETCHFACTOR OPENIMAGESTREAM T)) (DRAW.LOCAL.SKETCH SKETCHX OPENIMAGESTREAM REGIONONPAGE]) (SK.LIST.IMAGE [LAMBDA (SKETCHW FILE IMAGETYPE DONTLISTFLG) (* rrb "18-Oct-85 10:13") (* makes an image file from the sketch in a window even if it takes more than one page.) (PROG ((SKETCH (INSURE.SKETCH (SKETCH.FROM.VIEWER SKETCHW))) (VIEWREGION (DSPCLIPPINGREGION NIL SKETCHW)) (SCALE (WINDOW.SCALE SKETCHW)) PAGEREGION OPENIMAGESTREAM PAGEOVERLAPMARGIN SKETCHREGION SKETCHLOCALELTS SKETCHREGIONINPAGECOORDS LEFTSTART BOTTOMSTART RIGHTEND BOTTOMEND PAGETOSKETCHFACTOR PAGEHEIGHTINSKETCHCOORDS PAGEWIDTHINSKETCHCOORDS) (OR SKETCH (RETURN)) (SPAWN.MOUSE) (STATUSPRINT SKETCHW "Hardcopying ... ") (SETQ OPENIMAGESTREAM (OPENIMAGESTREAM FILE IMAGETYPE)) (SETQ PAGEREGION (DSPCLIPPINGREGION NIL OPENIMAGESTREAM)) (* calculate the local elements for all the sketch elements at this scale. This is done because the region testing routines all work on local elements. The local elements will be made again for each page; wasteful but should demonstrate the capability.) (SETQ SKETCHLOCALELTS (for SKELT in (fetch (SKETCH SKETCHELTS) of SKETCH) collect (SK.LOCAL.FROM.GLOBAL SKELT SKETCHW SCALE))) (SETQ SKETCHREGION (SK.GLOBAL.REGION.OF.LOCAL.ELEMENTS SKETCHLOCALELTS SCALE)) (* PAGETOSKETCHFACTOR is the factor to multiply the page coordinates by to get into sketch coordinates.) (SETQ PAGETOSKETCHFACTOR (FQUOTIENT SCALE (DSPSCALE NIL OPENIMAGESTREAM))) (SETQ SKETCHREGIONINPAGECOORDS (SCALE.REGION SKETCHREGION PAGETOSKETCHFACTOR)) (* should check here for wider than high and rotate it or use landscape imagestream.) [COND ((AND (ILESSP (fetch (REGION WIDTH) of SKETCHREGIONINPAGECOORDS) (fetch (REGION WIDTH) of PAGEREGION)) (ILESSP (fetch (REGION HEIGHT) of SKETCHREGIONINPAGECOORDS) (fetch (REGION HEIGHT) of PAGEREGION))) (* whole image fits on one page, center it) (SETQ LEFTSTART (QUOTIENT (DIFFERENCE (fetch (REGION WIDTH) of PAGEREGION) (fetch (REGION WIDTH) of SKETCHREGIONINPAGECOORDS)) 2)) (SETQ BOTTOMSTART (QUOTIENT (DIFFERENCE (fetch (REGION HEIGHT) of PAGEREGION) (fetch (REGION HEIGHT) of SKETCHREGIONINPAGECOORDS)) 2)) (\SK.LIST.PAGE.IMAGE OPENIMAGESTREAM SKETCHREGION SKETCHLOCALELTS PAGETOSKETCHFACTOR (CREATEREGION LEFTSTART BOTTOMSTART (fetch (REGION WIDTH) of SKETCHREGIONINPAGECOORDS) (fetch (REGION HEIGHT) of SKETCHREGIONINPAGECOORDS)) SCALE)) (T (* put sketch on multiple pages. Might also try scaling it to fit.) (* leave a half inch so that the pages can be taped together.) (SETQ PAGEOVERLAPMARGIN (TIMES 36 (DSPSCALE NIL OPENIMAGESTREAM))) (SETQ PAGEREGION (CREATEREGION (fetch (REGION LEFT) of PAGEREGION) (fetch (REGION BOTTOM) of PAGEREGION) (DIFFERENCE (fetch (REGION WIDTH) of PAGEREGION) PAGEOVERLAPMARGIN) (DIFFERENCE (fetch (REGION HEIGHT) of PAGEREGION) PAGEOVERLAPMARGIN))) (SETQ PAGEWIDTHINSKETCHCOORDS (TIMES (fetch (REGION WIDTH) of PAGEREGION) PAGETOSKETCHFACTOR)) (SETQ PAGEHEIGHTINSKETCHCOORDS (TIMES (fetch (REGION HEIGHT) of PAGEREGION) PAGETOSKETCHFACTOR)) (* adjust sketch region to center the image within the multiple pages. This is mostly to cover the case of a wide but not high image that extents across multiple pages.) [COND ([NOT (ZEROP (SETQ LEFTSTART (REMAINDER (fetch (REGION WIDTH) of SKETCHREGION) PAGEWIDTHINSKETCHCOORDS] (* unless the sketch is right on a page boundary, leave half the room in front.) (SETQ LEFTSTART (QUOTIENT (DIFFERENCE PAGEWIDTHINSKETCHCOORDS LEFTSTART) 2] (SETQ LEFTSTART (DIFFERENCE (fetch (REGION LEFT) of SKETCHREGION) LEFTSTART)) [COND ([NOT (ZEROP (SETQ BOTTOMSTART (REMAINDER (fetch (REGION HEIGHT) of SKETCHREGION) PAGEHEIGHTINSKETCHCOORDS] (* unless the sketch is right on a page boundary, leave half the room in front.) (SETQ BOTTOMSTART (QUOTIENT (DIFFERENCE PAGEHEIGHTINSKETCHCOORDS BOTTOMSTART) 2] (SETQ BOTTOMSTART (DIFFERENCE (PLUS (fetch (REGION TOP) of SKETCHREGION) BOTTOMSTART) PAGEHEIGHTINSKETCHCOORDS)) (SETQ BOTTOMEND (DIFFERENCE (fetch (REGION BOTTOM) of SKETCHREGION) PAGEHEIGHTINSKETCHCOORDS)) (SETQ RIGHTEND (fetch (REGION RIGHT) of SKETCHREGION)) (STATUSPRINT SKETCHW (TIMES (IQUOTIENT (DIFFERENCE (PLUS RIGHTEND (SUB1 PAGEWIDTHINSKETCHCOORDS)) LEFTSTART) PAGEWIDTHINSKETCHCOORDS) (IQUOTIENT (DIFFERENCE (PLUS BOTTOMSTART (SUB1 PAGEHEIGHTINSKETCHCOORDS)) BOTTOMEND) PAGEHEIGHTINSKETCHCOORDS)) " pgs...") (bind (PGN ← 0) for PGBOTTOM from BOTTOMSTART to BOTTOMEND by (MINUS PAGEHEIGHTINSKETCHCOORDS) as PGROW from 1 do (* unless this is the first line of pages, put out new page.) (OR (EQ PGROW 1) (DSPNEWPAGE OPENIMAGESTREAM)) (for PGLEFT from LEFTSTART to RIGHTEND by PAGEWIDTHINSKETCHCOORDS as PGCOL from 1 do (* unless this is the first page on a line of pages, put out new page.) (OR (EQ PGCOL 1) (DSPNEWPAGE OPENIMAGESTREAM)) (\SK.LIST.PAGE.IMAGE OPENIMAGESTREAM (CREATEREGION PGLEFT PGBOTTOM PAGEWIDTHINSKETCHCOORDS PAGEHEIGHTINSKETCHCOORDS) SKETCHLOCALELTS PAGETOSKETCHFACTOR PAGEREGION SCALE) (STATUSPRINT SKETCHW (SETQ PGN (ADD1 PGN)) ",") (* code to put out matrix numbers that I couldn't get to work. (COND ((IMAGESTREAMTYPEP OPENIMAGESTREAM (QUOTE PRESS)) (* Press does better at the left edge so put numbers on the right.) (COND ((LESSP (PLUS PGLEFT PAGEWIDTHINSKETCHCOORDS) (fetch (REGION RIGHT) of SKETCHREGION)) (* unless this is the last page, print a page number in the area that is overlapped.) (* this should change back to the default font of the stream but I don't know how to do that.) (MOVETO (fetch (REGION WIDTH) of PAGEREGION) (PLUS (fetch (REGION HEIGHT) of PAGEREGION) (FONTPROP OPENIMAGESTREAM (QUOTE DESCENT))) OPENIMAGESTREAM) (printout OPENIMAGESTREAM PGROW ", " PGCOL)))) ((NEQ PGCOL 1) (* Interpress and assumed all others look better at the right edge so put the number on the left.) (* unless this is the first page, print a page number in the area that is overlapped.) (* this should change back to the default font of the stream but I don't know how to do that.) (MOVETO 10 (FONTPROP OPENIMAGESTREAM (QUOTE DESCENT)) OPENIMAGESTREAM) (printout OPENIMAGESTREAM PGROW ", " PGCOL)) )) ] (SETQ LEFTSTART (CLOSEF OPENIMAGESTREAM)) (STATUSPRINT SKETCHW "...done.") (RETURN LEFTSTART]) (SK.LIST.IMAGE.ON.FILE [LAMBDA (SKETCHW) (* rrb "17-Jul-85 21:34") (* makes a file suitable for the default printing host of the current sketch. Pretty dumb about file names.) (SK.LIST.IMAGE SKETCHW [PACKFILENAME (CONS (QUOTE EXTENSION) (CONS (DEFAULTPRINTINGIMAGETYPE) (UNPACKFILENAME (OR (fetch (SKETCH SKETCHNAME) of (INSURE.SKETCH ( SKETCH.FROM.VIEWER SKETCHW))) (QUOTE Sketch] (DEFAULTPRINTINGIMAGETYPE]) (SK.SET.HARDCOPY.MODE [LAMBDA (SKETCHW IMAGETYPE) (* rrb "28-Oct-85 16:43") (* * changes a sketch window to show things in hardcopy mode.) (PROG [NOWTYPE (IMAGETYPEX (OR IMAGETYPE (PRINTERTYPE] (RETURN (COND ((OR (NOT (IMAGESTREAMTYPEP SKETCHW (QUOTE HARDCOPY))) (AND (SETQ NOWTYPE (HARDCOPYSTREAMTYPE SKETCHW)) (NEQ IMAGETYPEX NOWTYPE))) (* make the font of the stream be something that will not cause MAKEHARDCOPYSTREAM to barf on.) (* flip cursor because finding fonts can take a while.) (SKED.CLEAR.SELECTION SKETCHW) (RESETFORM (CURSOR WAITINGCURSOR) (DSPFONT (DEFAULTFONT IMAGETYPE) SKETCHW) (MAKEHARDCOPYSTREAM SKETCHW IMAGETYPE) (SK.UPDATE.AFTER.HARDCOPY SKETCHW))) (T (* already in hardcopy mode.) (STATUSPRINT SKETCHW "The display is already showing " IMAGETYPE " output spacing."]) (SK.UNSET.HARDCOPY.MODE [LAMBDA (SKETCHW) (* rrb "28-Oct-85 16:43") (* * changes a sketch window to show things in normal display mode.) (COND ((IMAGESTREAMTYPEP (GETSTREAM SKETCHW (QUOTE OUTPUT)) (QUOTE HARDCOPY)) (SKED.CLEAR.SELECTION SKETCHW) (UNMAKEHARDCOPYSTREAM SKETCHW) (SK.UPDATE.AFTER.HARDCOPY SKETCHW]) (SK.UPDATE.AFTER.HARDCOPY [LAMBDA (SKETCHW) (* rrb "29-Jan-85 14:40") (* * goes through a sketch window updating those elements that have changed as a result of a change in mode between normal and hardcopy and redraws the screen.) (MAPSKETCHSPECS (LOCALSPECS.FROM.VIEWER SKETCHW) [FUNCTION (LAMBDA (SKELT SKW SCALE) (COND ((MEMB (fetch (SCREENELT GTYPE) of SKELT) (QUOTE (TEXT TEXTBOX))) (ZOOM.UPDATE.ELT SKELT SKW] SKETCHW (SKETCHW.SCALE SKETCHW)) (REDISPLAYW SKETCHW]) (DEFAULTPRINTINGIMAGETYPE [LAMBDA NIL (* rrb "20-Mar-85 12:45") (* returns the image type of the default printer.) (* code copied from OPENIMAGESTREAM) (CAR (MKLIST (PRINTERPROP (PRINTERTYPE (OR (CAR (LISTP DEFAULTPRINTINGHOST)) DEFAULTPRINTINGHOST)) (QUOTE CANPRINT]) (SK.SWITCH.REGION.X.AND.Y [LAMBDA (REGION) (* rrb " 3-Sep-85 14:50") (* switchs the X and Y dimensions of a region.) (CREATEREGION (fetch (REGION BOTTOM) of REGION) (fetch (REGION LEFT) of REGION) (fetch (REGION HEIGHT) of REGION) (fetch (REGION WIDTH) of REGION]) ) (DECLARE: EVAL@COMPILE (RPAQQ MICASPERPT 35.27778) (RPAQQ IMICASPERPT 35) (RPAQQ PTSPERMICA .02834646) (CONSTANTS MICASPERPT IMICASPERPT PTSPERMICA) ) (* functions for displaying the global coordinate space values.) (DEFINEQ (SHOW.GLOBAL.COORDS [LAMBDA (XCOORD YCOORD W) (* rrb " 5-Jun-85 18:30") (* converts to global coordinates and displays it in W) (DSPRESET W) (COND ((AND (EQP XCOORD (FIX XCOORD)) (EQP YCOORD (FIX YCOORD))) (printout W .F6.0 XCOORD " x" " " T .F6.0 YCOORD " y" " ")) (T (printout W .F8.2 XCOORD " x" " " T .F8.2 YCOORD " y" " "]) (LOCATOR.CLOSEFN [LAMBDA (GCOORDW) (* rrb " 7-May-85 09:41") (* close function for a window that is keeping track of the global coordinate system. It breaks the link to itself.) (DETACHWINDOW GCOORDW]) (SKETCHW.FROM.LOCATOR [LAMBDA (GCOORDW) (* rrb " 7-May-85 09:40") (* returns the active window if any that points to GCOORDW) (for W in (ACTIVEWINDOWS) when (MEMB GCOORDW (ATTACHEDWINDOWS W)) do (RETURN W]) (SKETCHW.UPDATE.LOCATORS [LAMBDA (W) (* rrb " 7-May-85 10:06") (* a cursor moved function for a sketch that shows the coordinates cursor in global coordinates.) (AND (INSIDEP (DSPCLIPPINGREGION NIL W) (LASTMOUSEX W) (LASTMOUSEY W)) (for LOCATOR in (ATTACHEDWINDOWS W) when (MEMB (FUNCTION LOCATOR.CLOSEFN) (WINDOWPROP LOCATOR (QUOTE CLOSEFN))) do (LOCATOR.UPDATE LOCATOR W]) (LOCATOR.UPDATE [LAMBDA (LOCATORW SKW) (* rrb "22-May-85 11:09") (* updates the position of the locator coordinates.) (* there are three kinds of locators: real coordinate, gridded real coordinates and latitude longitude, although lat lon has been deimplemented.) (SELECTQ (WINDOWPROP LOCATORW (QUOTE LOCATORTYPE)) (GLOBALCOORD (UPDATE.GLOBALCOORD.LOCATOR LOCATORW SKW)) (GLOBALGRIDDEDCOORD (UPDATE.GLOBAL.GRIDDED.COORD.LOCATOR LOCATORW SKW)) (LATLON (UPDATE.LATLON.LOCATOR LOCATORW SKW)) (SHOULDNT]) (UPDATE.GLOBAL.LOCATOR [LAMBDA (SKETCHW) (* rrb "19-APR-83 14:19") (* checks to see if the latitude longitude display needs to be updated.) (COND ([OR (AND (NEQ SKETCHW.LASTCURSORPTX (SETQ SKETCHW.LASTCURSORPTX (LASTMOUSEX SKETCHW))) (SETQ SKETCHW.LASTCURSORPTY (LASTMOUSEY SKETCHW))) (NEQ SKETCHW.LASTCURSORPTY (SETQ SKETCHW.LASTCURSORPTY (LASTMOUSEY SKETCHW] (* call it if either point has changed.) (SKETCHW.UPDATE.LOCATORS SKETCHW]) (UPDATE.GLOBALCOORD.LOCATOR [LAMBDA (GCOORDW W) (* rrb " 6-NOV-83 11:46") (* a cursor moved function for a map that shows the coordinates cursor in global coordinates.) (PROG (SCALE) (OR GCOORDW (RETURN)) (OR (SETQ SCALE (WINDOW.SCALE W)) (RETURN)) (SHOW.GLOBAL.COORDS (UNSCALE (LASTMOUSEX W) SCALE) (UNSCALE (LASTMOUSEY W) SCALE) GCOORDW]) (ADD.GLOBAL.DISPLAY [LAMBDA (SKW TYPE) (* rrb "28-Aug-85 11:10") (* creates a locator which gives the coordinates of the cursor in SKW in global coordinates.) (PROG [(LOCATOR (CREATE.GLOBAL.DISPLAYER (FONTCREATE BOLDFONT) (COND ((EQ TYPE (QUOTE GRID)) "cursor grid location") (T "cursor location in sketch"] (ATTACHWINDOW LOCATOR SKW (QUOTE BOTTOM) (QUOTE RIGHT) (QUOTE LOCALCLOSE)) [WINDOWPROP LOCATOR (QUOTE LOCATORTYPE) (COND ((EQ TYPE (QUOTE GRID)) (QUOTE GLOBALGRIDDEDCOORD)) (T (QUOTE GLOBALCOORD] (WINDOWPROP SKW (QUOTE CURSORMOVEDFN) (FUNCTION SKETCHW.UPDATE.LOCATORS)) (RETURN LOCATOR]) (ADD.GLOBAL.GRIDDED.DISPLAY [LAMBDA (SKW) (* adds a locator that shows the nearest grid location.) (ADD.GLOBAL.DISPLAY SKW (QUOTE GRID]) (CREATE.GLOBAL.DISPLAYER [LAMBDA (FONT TITLE) (* rrb " 7-May-85 09:59") (* creates a window for displaying latitude longitude.) (PROG ((GCOORDW (CREATEW (CREATEREGION 0 0 (WIDTHIFWINDOW (STRINGWIDTH "11111111.1111 " FONT)) (HEIGHTIFWINDOW (ITIMES 2 (FONTPROP FONT (QUOTE HEIGHT))) T)) (OR TITLE "Real Coordinates") NIL T))) (* extra space on stringwidth is to allow for the fact that printout translates into PRIN1 rather than PRIN3.) (DSPFONT FONT GCOORDW) (DSPRESET GCOORDW) (* reset its coordinates to the upper left) (WINDOWPROP GCOORDW (QUOTE CLOSEFN) (FUNCTION LOCATOR.CLOSEFN)) (RETURN GCOORDW]) (UPDATE.GLOBAL.GRIDDED.COORD.LOCATOR [LAMBDA (GCOORDW W) (* rrb "22-May-85 11:32") (* a cursor moved function for a map that shows the coordinates cursor in global coordinates.) (PROG (SCALE) (OR GCOORDW (RETURN)) (OR (SETQ SCALE (WINDOW.SCALE W)) (RETURN)) (COND [(WINDOWPROP W (QUOTE USEGRID)) (PROG ((GRID (SK.GRIDFACTOR W)) XGRID YGRID) (SETQ YGRID (MAP.WINDOW.ONTO.GLOBAL.GRID (LASTMOUSEY W) SCALE GRID)) (COND ([OR [NOT (EQP (SETQ XGRID (MAP.WINDOW.ONTO.GLOBAL.GRID (LASTMOUSEX W) SCALE GRID)) (WINDOWPROP GCOORDW (QUOTE XCOORD] (NOT (EQP YGRID (WINDOWPROP GCOORDW (QUOTE YCOORD] (* only update if one of the values has changed. This is done here but not in the ungridded case because it is handled by the cursor moved fn.) (WINDOWPROP GCOORDW (QUOTE XCOORD) XGRID) (WINDOWPROP GCOORDW (QUOTE YCOORD) YGRID) (SHOW.GLOBAL.COORDS XGRID YGRID GCOORDW] (T (SHOW.GLOBAL.COORDS (UNSCALE (LASTMOUSEX W) SCALE) (UNSCALE (LASTMOUSEY W) SCALE) GCOORDW]) ) (RPAQQ SKETCHW.LASTCURSORPTX 0) (RPAQQ SKETCHW.LASTCURSORY 0) (DECLARE: DOEVAL@COMPILE DONTCOPY (GLOBALVARS SKETCHW.LASTCURSORPTX SKETCHW.LASTCURSORPTY) ) (* fns for reading in various values) (DEFINEQ (READBRUSHSHAPE [LAMBDA NIL (* rrb " 6-Nov-85 09:57") (* reads a brush shape from the user.) (\CURSOR.IN.MIDDLE.MENU (create MENU CENTERFLG ← T TITLE ← "pick a shape" ITEMS ←(QUOTE (ROUND SQUARE VERTICAL HORIZONTAL DIAGONAL]) ) (DEFINEQ (SK.CHANGE.DASHING [LAMBDA (ELTWITHLINE DASHING SKW) (* rrb "20-Aug-85 15:30") (* changes the line dashing of ELTWITHLINE if it has one) (* knows about the various types of sketch elements and shouldn't.) (PROG (SIZE GLINELT TYPE NEWDASHING NOWDASHING NEWELT) (COND ((MEMB (SETQ TYPE (fetch (GLOBALPART GTYPE) of ELTWITHLINE)) (QUOTE (WIRE BOX CLOSEDWIRE CLOSEDCURVE OPENCURVE CIRCLE ELLIPSE TEXTBOX ARC) )) (* only works for things of wire type.) (SETQ GLINELT (fetch (GLOBALPART INDIVIDUALGLOBALPART) of ELTWITHLINE)) (* the dashing may be stored in different places for the element types.) [SETQ NEWDASHING (COND ((EQ DASHING (QUOTE NONE)) (* no dashing is marked with NIL) NIL) ((DASHINGP DASHING)) (T (ERROR "illegal dashing" DASHING] (SETQ NOWDASHING (SELECTQ TYPE (WIRE (fetch (WIRE OPENWIREDASHING) of GLINELT)) (BOX (fetch (BOX BOXDASHING) of GLINELT)) (ARC (fetch (ARC ARCDASHING) of GLINELT)) (TEXTBOX (fetch (TEXTBOX TEXTBOXDASHING) of GLINELT)) (CLOSEDWIRE (fetch (CLOSEDWIRE CLOSEDWIREDASHING) of GLINELT)) (CLOSEDCURVE (fetch (CLOSEDCURVE DASHING) of GLINELT)) (OPENCURVE (fetch (OPENCURVE DASHING) of GLINELT)) (CIRCLE (fetch (CIRCLE DASHING) of GLINELT)) (ELLIPSE (fetch (ELLIPSE DASHING) of GLINELT)) (SHOULDNT))) (COND ((EQUAL NEWDASHING NOWDASHING) (* if dashing isn't changing, don't bother creating a new one and repainting.) (RETURN))) (SETQ NEWELT (SELECTQ TYPE (WIRE (create WIRE using GLINELT OPENWIREDASHING ← NEWDASHING)) (BOX (create BOX using GLINELT BOXDASHING ← NEWDASHING)) (ARC (create ARC using GLINELT ARCDASHING ← NEWDASHING)) (TEXTBOX (create TEXTBOX using GLINELT TEXTBOXDASHING ← NEWDASHING)) (CLOSEDWIRE (create CLOSEDWIRE using GLINELT CLOSEDWIREDASHING ← NEWDASHING)) (CLOSEDCURVE (create CLOSEDCURVE using GLINELT DASHING ← NEWDASHING)) (OPENCURVE (create OPENCURVE using GLINELT DASHING ← NEWDASHING)) (CIRCLE (create CIRCLE using GLINELT DASHING ← NEWDASHING)) (ELLIPSE (create ELLIPSE using GLINELT DASHING ← NEWDASHING)) (SHOULDNT))) (RETURN (create GLOBALPART COMMONGLOBALPART ←(fetch (GLOBALPART COMMONGLOBALPART) of ELTWITHLINE) INDIVIDUALGLOBALPART ← NEWELT]) (READ.AND.SAVE.NEW.DASHING [LAMBDA NIL (* rrb " 6-Nov-85 09:57") (* reads a new dashing, confirms it with the user and adds it to SK.DASHING.PATTERNS) (PROG (DASHING BM) LP (COND ((NULL (SETQ DASHING (READ.NEW.DASHING))) (* user aborted) (RETURN NIL))) (SETQ BM (SK.DASHING.LABEL DASHING)) CONFIRM (SELECTQ (\CURSOR.IN.MIDDLE.MENU (create MENU ITEMS ←(LIST (LIST BM T "Will use this as the dashing pattern.") (QUOTE (Yes T "Will accept this pattern.")) (QUOTE (No (QUOTE NO) "Will ask you for another dashing pattern."))) CENTERFLG ← T TITLE ← "Is this pattern OK?")) (NO (GO LP)) (T (* add dashing to global list and return it.) (SK.CACHE.DASHING DASHING BM) (RETURN DASHING)) (PROGN (PROMPTPRINT "Please select 'Yes' if this pattern is what you want; 'No' if it isn't.") (GO CONFIRM]) (READ.NEW.DASHING [LAMBDA NIL (* rrb "27-Aug-85 14:12") (* reads a value of dashing from the user.) (PROMPTPRINT "You will be prompted for a series of numbers which specify the number of points ON and OFF. Enter 0 to end the dashing pattern. Enter 'Abort' to leave the dashing unchanged.") (bind VAL DASHLST OFF? (ORIGPOS ←(create POSITION XCOORD ← LASTMOUSEX YCOORD ← LASTMOUSEY)) until (OR (EQ (SETQ VAL (RNUMBER (CONCAT "Enter the number of points " (COND (OFF? (QUOTE OFF)) (T (QUOTE ON))) ". Enter 0 to end the dashing.") ORIGPOS NIL NIL T)) 0) (NULL VAL)) do (SETQ DASHLST (CONS VAL DASHLST)) (SETQ OFF? (NOT OFF?)) finally (CLRPROMPT) (RETURN (COND ((NULL VAL) (* abort selection) NIL) (T (REVERSE DASHLST]) (READ.DASHING.CHANGE [LAMBDA NIL (DECLARE (GLOBALVARS SK.DASHING.PATTERNS)) (* rrb " 6-Nov-85 09:57") (* gets a description of how to change the arrow heads of a wire or curve.) (PROG (DASHING) (SELECTQ [SETQ DASHING (\CURSOR.IN.MIDDLE.MENU (create MENU CENTERFLG ← T TITLE ← "New dashing pattern?" ITEMS ←(APPEND (for DASHPAT in SK.DASHING.PATTERNS collect (LIST (CAR DASHPAT) (KWOTE (CADR DASHPAT)) "changes dashing to this pattern")) (QUOTE (("other" (QUOTE OTHER) "will prompt you for a new dashing pattern.") ("no dashing" (QUOTE NONE) "removes dashing."] (OTHER (RETURN (READ.AND.SAVE.NEW.DASHING))) (RETURN DASHING]) (DASHINGP [LAMBDA (DASHING) (* rrb "30-Oct-85 11:33") (* return DASHING if it is a legal DASHING Note that NIL is a legal dashing and this will return NIL.) (AND (LISTP DASHING) (for X in DASHING always (NUMBERP X)) DASHING]) (SK.CACHE.DASHING [LAMBDA (DASHING BITMAP) (* rrb " 3-May-85 14:33") (* adds a dashing and its bitmap label to the global cache.) (OR (for DASH in SK.DASHING.PATTERNS when (EQUAL (CADR DASH) DASHING) do (RETURN T)) (COND (SK.DASHING.PATTERNS (NCONC1 SK.DASHING.PATTERNS (LIST (COND ((BITMAPP BITMAP)) (T (SK.DASHING.LABEL DASHING))) DASHING))) (T (SETQ SK.DASHING.PATTERNS (LIST (LIST (COND ((BITMAPP BITMAP)) (T (SK.DASHING.LABEL DASHING))) DASHING]) (SK.DASHING.LABEL [LAMBDA (DASHING) (* rrb " 3-May-85 14:32") (* creates a bitmap label which shows a dashing pattern.) (PROG (DS BM) [SETQ DS (DSPCREATE (SETQ BM (BITMAPCREATE 50 1] (DRAWLINE 0 0 50 0 1 NIL DS NIL DASHING) (RETURN BM]) ) (DEFINEQ (READ.FILLING.CHANGE [LAMBDA NIL (* rrb " 6-Nov-85 09:58") (* reads a shade for the filling texture.) (PROG (FILLING) (SELECTQ (SETQ FILLING (\CURSOR.IN.MIDDLE.MENU (create MENU CENTERFLG ← T TITLE ← "New filling?" ITEMS ←[APPEND (for FILLPAT in SK.FILLING.PATTERNS collect (LIST (CAR FILLPAT) (KWOTE (CADR FILLPAT)) "changes filling to this pattern")) (QUOTE (("4x4 shade" (QUOTE 4X4) "Allows creation of a 4 bits by 4 bits shade") ("16x16 shade" (QUOTE 16X16) "Allows creation of a 16 bits by 16 bits shade") ("No filling" (QUOTE NONE) "no filling will be used."] MENUBORDERSIZE ← 1))) (4X4 (RETURN (READ.AND.SAVE.NEW.FILLING))) (16X16 (RETURN (READ.AND.SAVE.NEW.FILLING T))) (RETURN FILLING]) (SK.CACHE.FILLING [LAMBDA (FILLING) (* rrb " 8-Jun-85 14:58") (* adds a dashing and its bitmap label to the global cache.) (OR (for FILL in SK.FILLING.PATTERNS when (EQUAL (CADR FILL) FILLING) do (RETURN T)) (COND (SK.FILLING.PATTERNS (NCONC1 SK.FILLING.PATTERNS (LIST (SK.FILLING.LABEL FILLING) FILLING))) (T (SETQ SK.FILLING.PATTERNS (LIST (LIST (SK.FILLING.LABEL FILLING) FILLING))) (QUOTE ADDED]) (READ.AND.SAVE.NEW.FILLING [LAMBDA (16X16FLG) (* rrb " 8-Jun-85 14:58") (* reads a new filling, confirms it with the user and adds it to SK.FILLING.PATTERNS) (PROG (FILLING) (COND ([NULL (SETQ FILLING (EDITSHADE (COND (16X16FLG (BITMAPCREATE 16 16] (* user aborted) (RETURN NIL))) (SK.CACHE.FILLING FILLING) (RETURN FILLING]) (SK.FILLING.LABEL [LAMBDA (FILLING) (* rrb " 8-Jun-85 12:08") (* creates a bitmap label which fills it with the texture FILLING.) (PROG [(BM (BITMAPCREATE (PLUS 8 (STRINGWIDTH "16x16 shade" MENUFONT)) (FONTPROP MENUFONT (QUOTE HEIGHT] (BLTSHADE FILLING BM) (RETURN BM]) ) (RPAQ? SK.DASHING.PATTERNS ) (RPAQ? SK.FILLING.PATTERNS ) (DECLARE: DOEVAL@COMPILE DONTCOPY (GLOBALVARS SK.DASHING.PATTERNS SK.FILLING.PATTERNS) ) (SK.CACHE.DASHING (QUOTE (2 4))) (SK.CACHE.DASHING (QUOTE (6 3 1 3))) (SK.CACHE.FILLING BLACKSHADE) (SK.CACHE.FILLING GRAYSHADE) (SK.CACHE.FILLING HIGHLIGHTSHADE) (* fns for reading colors) (DEFINEQ (DISPLAYREADCOLORHLSLEVELS [LAMBDA (HLS WIN) (* rrb "17-Jul-85 15:10") (* displays a hue lightness saturation triple in the color reading window.) (PROG (LEVEL) (DISPLAYREADCOLORLEVEL (SETQ LEVEL (HLSLEVEL HLS (QUOTE HUE))) (LEVELFROMHLSVALUE (QUOTE HUE) LEVEL) HUEREGION WIN) (DISPLAYREADCOLORLEVEL (SETQ LEVEL (HLSLEVEL HLS (QUOTE LIGHTNESS))) (LEVELFROMHLSVALUE (QUOTE LIGHTNESS) LEVEL) LIGHTNESSREGION WIN) (DISPLAYREADCOLORLEVEL (SETQ LEVEL (HLSLEVEL HLS (QUOTE SATURATION))) (LEVELFROMHLSVALUE (QUOTE SATURATION) LEVEL) SATURATIONREGION WIN]) (DISPLAYREADCOLORLEVEL [LAMBDA (PRINTLEVEL BARLEVEL REGION WINDOW) (* rrb "17-Jul-85 15:38") (* displays the value of a primary color in a color bar region.) (COND ((FIXP PRINTLEVEL) (MOVETO (DIFFERENCE (fetch LEFT of REGION) 4) VALBTM WINDOW) (PRIN1 PRINTLEVEL WINDOW) (* overstrike extra digits in case the old value was larger.) (PRIN1 " " WINDOW)) (T (* floating point values) (MOVETO (DIFFERENCE (fetch LEFT of REGION) 10) VALBTM WINDOW) (printout WINDOW .F5.3 PRINTLEVEL))) (FILLINREGION REGION BARLEVEL GRAYSHADE WINDOW]) (DRAWREADCOLORBOX [LAMBDA (TITLELEFT TITLE WINDOW) (* rrb "17-Jul-85 14:20") (* draws the box and title for a display bar for an rgb or hls quantity. Returns a dotted pair of the region the box occuppied and the left most position printed in.) (PROG (XPOS REGION) (MOVETO TITLELEFT 4 WINDOW) (SETQ XPOS (DSPXPOSITION NIL WINDOW)) (PRIN1 TITLE WINDOW) (OUTLINEREGION (SETQ REGION (create REGION LEFT ←(CENTEREDLEFT 10 XPOS (SETQ XPOS (DSPXPOSITION NIL WINDOW))) BOTTOM ←(PLUS 4 (FONTPROP WIN (QUOTE HEIGHT))) WIDTH ← 10 HEIGHT ← 256)) 2 NIL WINDOW) (RETURN (CONS REGION XPOS]) (READ.CHANGE.COLOR [LAMBDA (MSG) (* reads a color from the user and returns it) BLACKCOLOR]) (READCOLOR1 [LAMBDA (MSG ALLOWNONEFLG NOWCOLOR) (* rrb "29-Oct-85 12:29") (* lets the user select a color.) (PROG [(WIN (CREATEW (MAKEWITHINREGION (CREATEREGION LASTMOUSEX LASTMOUSEY COLORMENUWIDTH COLORMENUHEIGHT) WHOLEDISPLAY) (OR MSG "Enter a color: Left in rectangle sets level."))) VAL REDREGION GREENREGION BLUEREGION HUEREGION LIGHTNESSREGION SATURATIONREGION (INITCOLOR (AND NOWCOLOR (INSURE.RGB.COLOR NOWCOLOR T] [SETQ REDREGION (CAR (SETQ VAL (DRAWREADCOLORBOX 10 " RED " WIN] [SETQ GREENREGION (CAR (SETQ VAL (DRAWREADCOLORBOX (IPLUS (CDR VAL) 5) "GREEN" WIN] [SETQ BLUEREGION (CAR (SETQ VAL (DRAWREADCOLORBOX (IPLUS (CDR VAL) 5) " BLUE" WIN] [SETQ HUEREGION (CAR (SETQ VAL (DRAWREADCOLORBOX (IPLUS (CDR VAL) 20) " hue " WIN] [SETQ LIGHTNESSREGION (CAR (SETQ VAL (DRAWREADCOLORBOX (CDR VAL) " light " WIN] [SETQ SATURATIONREGION (CAR (SETQ VAL (DRAWREADCOLORBOX (CDR VAL) " sat " WIN] (ADDMENU (create MENU ITEMS ←[APPEND [COND (ALLOWNONEFLG (QUOTE (("No color" (QUOTE NONE) "specifies that no color should be used."] (QUOTE ((OK (QUOTE OK) "Returns the displayed color.") (Abort (QUOTE ABORT) "Aborts this operation."] CENTERFLG ← T MENUBORDERSIZE ← 1 WHENSELECTEDFN ←(FUNCTION READCOLORCOMMANDMENUSELECTEDFN)) WIN (create POSITION XCOORD ←(PLUS (CDR VAL) 10) YCOORD ← 100)) [SETQ VAL (COND (NOWCOLOR (READCOLOR2 WIN (fetch (RGB RED) of NOWCOLOR) (fetch (RGB GREEN) of NOWCOLOR) (fetch (RGB BLUE) of NOWCOLOR))) (T (READCOLOR2 WIN 0 0 0] (CLOSEW WIN) (RETURN VAL]) (READCOLORCOMMANDMENUSELECTEDFN [LAMBDA (ITEM MENU BUTTON) (* rrb "18-Jul-85 11:01") (* when selected function for the menu that sits in the read color window. Puts the value OK or ABORT on the window if selected.) (WINDOWPROP (WFROMMENU MENU) (QUOTE MENUCOMMAND) (CADADR ITEM]) (READCOLOR2 [LAMBDA (WIN REDLEVEL GREENLEVEL BLUELEVEL) (* rrb "29-Oct-85 12:29") (* internal function to READCOLOR which polls mouse and updates fields.) (PROG ((VALBTM (IPLUS (fetch (REGION BOTTOM) of REDREGION) 264)) LEVEL LASTX LASTY HLS) (PROGN (DISPLAYREADCOLORLEVEL REDLEVEL REDLEVEL REDREGION WIN) (DISPLAYREADCOLORLEVEL GREENLEVEL GREENLEVEL GREENREGION WIN) (DISPLAYREADCOLORLEVEL BLUELEVEL BLUELEVEL BLUEREGION WIN)) (DISPLAYREADCOLORHLSLEVELS (SETQ HLS (RGBTOHLS REDLEVEL GREENLEVEL BLUELEVEL)) WIN) WAITLP (* check if menu command was pressed.) (SELECTQ (WINDOWPROP WIN (QUOTE MENUCOMMAND)) (OK (RETURN (create RGB RED ← REDLEVEL GREEN ← GREENLEVEL BLUE ← BLUELEVEL))) (NONE (RETURN (QUOTE NONE))) (ABORT (RETURN NIL)) NIL) [COND ((MOUSESTATE LEFT) (COND [[SETQ COLOR (COND ((INSIDEP REDREGION (SETQ LASTX (LASTMOUSEX WIN)) (SETQ LASTY (LASTMOUSEY WIN))) (QUOTE RED)) ((INSIDEP GREENREGION LASTX LASTY) (QUOTE GREEN)) ((INSIDEP BLUEREGION LASTX LASTY) (QUOTE BLUE] (until (MOUSESTATE (NOT LEFT)) do (* as long as left is down, adjust the color.) (COND ((NEQ [SETQ LEVEL (IMIN 255 (IMAX 0 (IDIFFERENCE (LASTMOUSEY WIN) (fetch (REGION BOTTOM) of REDREGION] (SELECTQ COLOR (RED REDLEVEL) (GREEN GREENLEVEL) BLUELEVEL)) (* see if color level has changed.) (SELECTQ COLOR (RED (DISPLAYREADCOLORLEVEL (SETQ REDLEVEL LEVEL) REDLEVEL REDREGION WIN)) (GREEN (DISPLAYREADCOLORLEVEL (SETQ GREENLEVEL LEVEL) GREENLEVEL GREENREGION WIN) ) (DISPLAYREADCOLORLEVEL (SETQ BLUELEVEL LEVEL) BLUELEVEL BLUEREGION WIN)) (DISPLAYREADCOLORHLSLEVELS (SETQ HLS (RGBTOHLS REDLEVEL GREENLEVEL BLUELEVEL)) WIN] ([SETQ COLOR (COND ((INSIDEP HUEREGION (SETQ LASTX (LASTMOUSEX WIN)) (SETQ LASTY (LASTMOUSEY WIN))) (QUOTE HUE)) ((INSIDEP LIGHTNESSREGION LASTX LASTY) (QUOTE LIGHTNESS)) ((INSIDEP SATURATIONREGION LASTX LASTY) (QUOTE SATURATION] (until (MOUSESTATE (NOT LEFT)) do (* as long as red is down, adjust the color.) (COND ((NOT (EQUAL [SETQ LEVEL (HLSVALUEFROMLEVEL COLOR (IMIN 255 (IMAX 0 (IDIFFERENCE (LASTMOUSEY WIN) (fetch (REGION BOTTOM) of REDREGION] (HLSLEVEL HLS COLOR))) (* see if color level has changed.) (HLSLEVEL HLS COLOR LEVEL) (SELECTQ COLOR (HUE (DISPLAYREADCOLORLEVEL LEVEL (LEVELFROMHLSVALUE (QUOTE HUE) LEVEL) HUEREGION WIN)) (LIGHTNESS (DISPLAYREADCOLORLEVEL LEVEL (LEVELFROMHLSVALUE (QUOTE LIGHTNESS) LEVEL) LIGHTNESSREGION WIN)) (DISPLAYREADCOLORLEVEL LEVEL (LEVELFROMHLSVALUE (QUOTE SATURATION) LEVEL) SATURATIONREGION WIN)) (* set the color levels of the current color and update that display also.) (SETQ LEVEL (HLSTORGB HLS)) (PROGN (DISPLAYREADCOLORLEVEL (SETQ REDLEVEL (CAR LEVEL)) REDLEVEL REDREGION WIN) (DISPLAYREADCOLORLEVEL (SETQ GREENLEVEL (CADR LEVEL)) GREENLEVEL GREENREGION WIN) (DISPLAYREADCOLORLEVEL (SETQ BLUELEVEL (CADDR LEVEL)) BLUELEVEL BLUEREGION WIN] (BLOCK) (GO WAITLP]) ) (DEFINEQ (CREATE.CNS.MENU [LAMBDA NIL (* rrb "17-Jul-85 21:14") (* creates the CNS menu.) (* Not fully implemented. Use STYLESHEET.WHENSELECTEDFN to set items from level bars.) (SETQ CNS.STYLE (CREATE.STYLE (QUOTE ITEM.TITLES) (QUOTE (Saturation Lightness Tint Hue)) (QUOTE ITEM.TITLE.FONT) (QUOTE (TIMESROMAN 14 BOLD)) (QUOTE ITEMS) [LIST (CREATE MENU ITEMS ←(QUOTE (Grayish Moderate Strong Vivid))) (CREATE MENU ITEMS ←(QUOTE (Black ("Very Dark" (QUOTE VeryDark)) Dark Medium Light ("Very Light" (QUOTE VeryLight)) White))) (CREATE MENU ITEMS ←(QUOTE (Orange Orangish Red Reddish Yellow Yellowish Green Greenish Blue Bluish Purple Purplish Brown Brownish))) (CREATE MENU ITEMS ←(QUOTE (Red Orange Yellow Green Blue Purple Brown] (QUOTE SELECTION) (QUOTE ("" "" "" "")) (QUOTE NEED.NOT.FILL.IN) T)) (STYLESHEET CNS.STYLE]) ) (RPAQQ COLORMENUHEIGHT 320) (RPAQQ COLORMENUWIDTH 360) (DECLARE: DOEVAL@COMPILE EVAL@LOAD DONTCOPY (FILESLOAD (LOADCOMP) LLCOLOR) ) (DEFINEQ (SCALE.POSITION.INTO.SKETCHW [LAMBDA (POS SKETCHW) (* rrb "29-Jan-85 14:50") (* scales a position into a sketch window using its scale factor.) (SK.SCALE.POSITION.INTO.VIEWER POS (WINDOW.SCALE SKETCHW]) (UNSCALE [LAMBDA (COORD SCALE) (* unscales a coordinate) (TIMES COORD SCALE]) (UNSCALE.REGION [LAMBDA (REGION SCALE) (* rrb "15-AUG-83 17:31") (* scales a region from a window region to the larger coordinate space.) (CREATEREGION (TIMES SCALE (fetch (REGION LEFT) of REGION)) (TIMES SCALE (fetch (REGION BOTTOM) of REGION)) (TIMES SCALE (fetch (REGION WIDTH) of REGION)) (TIMES SCALE (fetch (REGION HEIGHT) of REGION]) ) (* stuff for reading input positions) (DEFINEQ (SK.GETGLOBALPOSITION [LAMBDA (W CURSOR NEWPOINTFLG) (* rrb "31-Jul-85 10:25") (* gets a position from the user and returns the global value of it.) (SK.MAP.INPUT.PT.TO.GLOBAL (GETSKWPOSITION W CURSOR NEWPOINTFLG) W]) (GETSKWPOSITION [LAMBDA (W CURSOR NEWPOINTFLG) (* rrb "31-Jul-85 11:26") (* provides a hook for the inputting of a point via mouse from the user. Left button {or middle for now} will return a point that is on the grid or not according to the grid setting. Right will return the other. Returns a instance of record INPUTPT) (RESETFORM (CURSOR (OR CURSOR CROSSHAIRS)) (PROG ((USEGRID (WINDOWPROP W (QUOTE USEGRID))) (GRID (SK.GRIDFACTOR W)) (SCALE (WINDOW.SCALE W)) (HOTSPOTCACHE (SK.HOTSPOT.CACHE W)) XSCREEN YSCREEN XGRID YGRID NEWX NEWY MOUSEDOWN ONGRID? NEARPOS) (RETURN (until (COND (MOUSEDOWN (MOUSESTATE UP)) ((MOUSESTATE (OR LEFT MIDDLE RIGHT)) (COND ((NOT (INSIDEP W (LASTMOUSEX W) (LASTMOUSEY W))) (RETURN))) (SETQ MOUSEDOWN T) NIL)) do (SETQ NEWX (LASTMOUSEX W)) (SETQ NEWY (LASTMOUSEY W)) [COND ((OR (NEQ NEWX XSCREEN) (NEQ NEWY YSCREEN)) (* cursor changed position check if grid pt moved.) (SKETCHW.UPDATE.LOCATORS W) (SETQ XSCREEN NEWX) (SETQ YSCREEN NEWY) [COND ((AND (NOT NEWPOINTFLG) HOTSPOTCACHE (LASTMOUSESTATE MIDDLE) (SETQ NEARPOS (NEAREST.HOT.SPOT HOTSPOTCACHE NEWX NEWY) )) (* on middle, pick the closest point) (SETQ NEWX (fetch (POSITION XCOORD) of NEARPOS)) (SETQ NEWY (fetch (POSITION YCOORD) of NEARPOS)) (SETQ ONGRID? NIL)) ((SETQ ONGRID? (COND ((LASTMOUSESTATE RIGHT) (* if right is down, flip sense of using grid) (NOT USEGRID)) (T (* otherwise use the grid if told to.) USEGRID))) (SETQ NEWX (MAP.WINDOW.ONTO.GRID NEWX SCALE GRID)) (SETQ NEWY (MAP.WINDOW.ONTO.GRID NEWY SCALE GRID] (COND ((OR (NEQ XGRID NEWX) (NEQ YGRID NEWY)) (* grid point has changed too. Redraw point.) (AND XGRID (SHOWSKETCHXY XGRID YGRID W)) (SHOWSKETCHXY (SETQ XGRID NEWX) (SETQ YGRID NEWY) W] finally (RETURN (COND (XGRID (SHOWSKETCHXY XGRID YGRID W) (* if the cursor was outside the window when let up, return NIL) (AND (INSIDEP W (LASTMOUSEX W) (LASTMOUSEY W)) (create INPUTPT INPUT.ONGRID? ← ONGRID? INPUT.POSITION ←(create POSITION XCOORD ← XGRID YCOORD ← YGRID] ) (SKETCH.TRACK.ELEMENTS [LAMBDA (ELEMENTS VIEWER CONSTRAINTFN HOTSPOT) (* rrb "14-Nov-85 10:42") (* gets a point from the user by displaying an image of ELEMENTS. It calls CONSTRAINTFN everytime the cursor moves to allow user constraints on where the image is displayed. All positions and elements are in sketch coordinates.) (PROG (FIGINFO FIRSTHOTSPOT NEWPOS LOWLFT IMAGEPOSX IMAGEPOSY IMAGEBM DELTAPOS NEWGLOBALS SKETCH GDELTAPOS) (COND (T (* read new position from the user) (SETQ FIGINFO (SK.FIGUREIMAGE SCRELTS (DSPCLIPPINGREGION NIL SKW))) [SETQ FIRSTHOTSPOT (CAR (fetch (SCREENELT HOTSPOTS) of (CAR SCRELTS] (SETQ IMAGEBM (fetch (SKFIGUREIMAGE SKFIGURE.BITMAP) of FIGINFO)) (SETQ LOWLFT (fetch (SKFIGUREIMAGE SKFIGURE.LOWERLEFT) of FIGINFO)) (* move the image by the first hotspot of the first element chosen. This will align the image on the grid correctly.) (SETQ IMAGEPOSX (fetch (POSITION XCOORD) of LOWLFT)) (SETQ IMAGEPOSY (fetch (POSITION YCOORD) of LOWLFT)) (* put the cursor on the hot spot) (CURSORPOSITION FIRSTHOTSPOT SKW) (COND ([NULL (ERSETQ (PROGN (SK.SHOW.FIG.FROM.INFO IMAGEBM IMAGEPOSX IMAGEPOSY (QUOTE ERASE) SKW) (SETQ NEWPOS (fetch (INPUTPT INPUT.POSITION) of (GET.BITMAP.POSITION SKW IMAGEBM (QUOTE PAINT) "Move image to its new position." (IDIFFERENCE IMAGEPOSX (fetch (POSITION XCOORD) of FIRSTHOTSPOT)) (IDIFFERENCE IMAGEPOSY (fetch (POSITION YCOORD) of FIRSTHOTSPOT] (* error happened, repaint the image.) (SK.SHOW.FIG.FROM.INFO IMAGEBM IMAGEPOSX IMAGEPOSY (QUOTE PAINT) SKW) (CLOSEPROMPTWINDOW SKW) (ERROR!)) ((NULL NEWPOS) (SK.SHOW.FIG.FROM.INFO IMAGEBM IMAGEPOSX IMAGEPOSY (QUOTE PAINT) SKW) (STATUSPRINT SKW "Position was outside the window, copy not placed.") (RETURN NIL))) (* GET.BITMAP.POSITION returns the position that the cursor was in which is the position of the first hotspot.) (* calculate the delta that the selected point moves.) (SETQ GDELTAPOS (SK.MAP.FROM.WINDOW.TO.NEAREST.GRID [SETQ DELTAPOS (create POSITION XCOORD ←(IDIFFERENCE (fetch (POSITION XCOORD) of NEWPOS) (fetch (POSITION XCOORD) of FIRSTHOTSPOT)) YCOORD ←(IDIFFERENCE (fetch (POSITION YCOORD) of NEWPOS) (fetch (POSITION YCOORD) of FIRSTHOTSPOT] (WINDOW.SCALE SKW]) (SK.READ.POINT.WITH.FEEDBACK [LAMBDA (WINDOW CURSOR FEEDBACKFN FEEDBACKFNDATA) (* rrb "14-Nov-85 13:52") (* reads a point from the user. Each time the cursor moves, a feedback fn is called passing it the new X, new Y, WINDOW and FEEDBACKDATA It is expected to XOR something on the screen that tells the user something.) (RESETFORM (CURSOR (OR CURSOR CROSSHAIRS)) (PROG ((USEGRID (WINDOWPROP WINDOW (QUOTE USEGRID))) (GRID (SK.GRIDFACTOR WINDOW)) (SCALE (WINDOW.SCALE WINDOW)) (HOTSPOTCACHE (SK.HOTSPOT.CACHE WINDOW)) XSCREEN YSCREEN XGRID YGRID NEWX NEWY MOUSEDOWN ONGRID? NEARPOS OLDOPERATION) (OR FEEDBACKFN (SETQ FEEDBACKFN (QUOTE SHOWSKETCHXY))) (SETQ OLDOPERATION (DSPOPERATION (QUOTE INVERT) WINDOW)) (RETURN (PROG1 [until (COND (MOUSEDOWN (MOUSESTATE UP)) ((MOUSESTATE (OR LEFT MIDDLE RIGHT)) (COND ((NOT (INSIDEP WINDOW (LASTMOUSEX WINDOW) (LASTMOUSEY WINDOW))) (RETURN))) (SETQ MOUSEDOWN T) NIL)) do (SETQ NEWX (LASTMOUSEX WINDOW)) (SETQ NEWY (LASTMOUSEY WINDOW)) [COND ((OR (NEQ NEWX XSCREEN) (NEQ NEWY YSCREEN)) (* cursor changed position check if grid pt moved.) (SKETCHW.UPDATE.LOCATORS WINDOW) (SETQ XSCREEN NEWX) (SETQ YSCREEN NEWY) [COND ((AND HOTSPOTCACHE (LASTMOUSESTATE MIDDLE) (SETQ NEARPOS (NEAREST.HOT.SPOT HOTSPOTCACHE NEWX NEWY))) (* on middle, pick the closest point) (SETQ NEWX (fetch (POSITION XCOORD) of NEARPOS)) (SETQ NEWY (fetch (POSITION YCOORD) of NEARPOS)) (SETQ ONGRID? NIL)) ((SETQ ONGRID? (COND ((LASTMOUSESTATE RIGHT) (* if right is down, flip sense of using grid) (NOT USEGRID)) (T (* otherwise use the grid if told to.) USEGRID))) (SETQ NEWX (MAP.WINDOW.ONTO.GRID NEWX SCALE GRID)) (SETQ NEWY (MAP.WINDOW.ONTO.GRID NEWY SCALE GRID] (COND ((OR (NEQ XGRID NEWX) (NEQ YGRID NEWY)) (* grid point has changed too. Call the feedback function if the point is in the window. If it is outside, don't show anything.) (AND XGRID (INSIDEP WINDOW XGRID YGRID) (APPLY* FEEDBACKFN XGRID YGRID WINDOW FEEDBACKFNDATA)) (AND (INSIDEP WINDOW (SETQ XGRID NEWX) (SETQ YGRID NEWY)) (APPLY* FEEDBACKFN XGRID YGRID WINDOW FEEDBACKFNDATA] finally (RETURN (COND ((AND XGRID (INSIDEP WINDOW XGRID YGRID)) (* if the cursor was outside the window when let up, return NIL) (APPLY* FEEDBACKFN XGRID YGRID WINDOW FEEDBACKFNDATA) (create INPUTPT INPUT.ONGRID? ← ONGRID? INPUT.POSITION ←( create POSITION XCOORD ← XGRID YCOORD ← YGRID] (DSPOPERATION OLDOPERATION WINDOW]) (NEAREST.HOT.SPOT [LAMBDA (CACHE X Y) (* rrb "31-Jul-85 10:14") (* returns the nearest hot spot to X Y) (PROG ((BESTMEASURE 10000) BESTX BESTY YDIF THISDIF) [for YBUCKET in CACHE do (SETQ YDIF (ABS (DIFFERENCE (CAR YBUCKET) Y))) (for XBUCKET in (CDR YBUCKET) do (COND ((CDR XBUCKET) (* this bucket has entries) (* use Manhattan distance for efficiency.) [SETQ THISDIF (PLUS YDIF (ABS (DIFFERENCE (CAR XBUCKET) X] (COND ((ILESSP THISDIF BESTMEASURE) (SETQ BESTMEASURE THISDIF) (SETQ BESTX (CAR XBUCKET)) (SETQ BESTY (CAR YBUCKET] (RETURN (AND BESTX (create POSITION XCOORD ← BESTX YCOORD ← BESTY]) (GETWREGION [LAMBDA (W NEWREGIONFN NEWREGIONFNDATA MINWIDTH MINHEIGHT) (* rrb " 7-May-85 09:26") (* gets a region from a window) (PROG ((REG (GETREGION MINWIDTH MINHEIGHT NIL NEWREGIONFN NEWREGIONFNDATA))) (RETURN (CREATEREGION (IDIFFERENCE (fetch LEFT of REG) (DSPXOFFSET NIL W)) (IDIFFERENCE (fetch BOTTOM of REG) (DSPYOFFSET NIL W)) (fetch WIDTH of REG) (fetch HEIGHT of REG]) (GET.BITMAP.POSITION [LAMBDA (WINDOW BITMAP OPERATION MSG XOFFSET YOFFSET) (* rrb "11-Jul-85 11:00") (* gets a position by tracking with a bitmap The spec returns is actually (ONGRID? position) so that caller can tell whether it was placed on grid or not.) (PROG (BUFFER.BITMAP WIDTH HEIGHT) (SETQ WIDTH (BITMAPWIDTH BITMAP)) (SETQ HEIGHT (BITMAPHEIGHT BITMAP)) (SETQ BUFFER.BITMAP (BITMAPCREATE WIDTH HEIGHT)) (STATUSPRINT WINDOW " " MSG) (RETURN (SK.TRACK.BITMAP1 WINDOW BITMAP BUFFER.BITMAP WIDTH HEIGHT (OR OPERATION (QUOTE PAINT)) XOFFSET YOFFSET]) (SK.TRACK.BITMAP1 [LAMBDA (W BITMAP BUFFER.BITMAP WIDTH HEIGHT OPERATION XOFFSET YOFFSET) (* rrb "27-Sep-85 19:12") (* tracks BITMAP until a button goes down and comes up. Returns a list of (ongrid? position) so that caller can know whether the point chosen was on a grid or not.) (* there is other code in BIGFONT that is probably better for this.) (PROG (DOWN LEFT BOTTOM NEW.LEFT NEW.BOTTOM GRID.LEFT GRID.BOTTOM ONGRID? NEARPOS (DSP (WINDOWPROP W (QUOTE DSP))) (USEGRID (WINDOWPROP W (QUOTE USEGRID))) (GRID (SK.GRIDFACTOR W)) (SCALE (WINDOW.SCALE W)) (HOTSPOTCACHE (SK.HOTSPOT.CACHE W))) (OR XOFFSET (SETQ XOFFSET 0)) (OR YOFFSET (SETQ YOFFSET 0)) (TOTOPW W) (RETURN (until (AND DOWN (LASTMOUSESTATE UP)) do (GETMOUSESTATE) (COND ((LASTMOUSESTATE (NOT UP)) (SETQ DOWN T))) (SETQ NEW.LEFT (LASTMOUSEX DSP)) (SETQ NEW.BOTTOM (LASTMOUSEY DSP)) [COND ((OR (NEQ NEW.LEFT LEFT) (NEQ NEW.BOTTOM BOTTOM)) (* cursor changed position check if grid pt moved.) (SKETCHW.UPDATE.LOCATORS W) (SETQ LEFT NEW.LEFT) (SETQ BOTTOM NEW.BOTTOM) [COND ((AND HOTSPOTCACHE (LASTMOUSESTATE MIDDLE) (SETQ NEARPOS (NEAREST.HOT.SPOT HOTSPOTCACHE NEW.LEFT NEW.BOTTOM)) ) (* on middle, pick the closest point) (SETQ ONGRID? NIL) (SETQ NEW.LEFT (fetch (POSITION XCOORD) of NEARPOS)) (SETQ NEW.BOTTOM (fetch (POSITION YCOORD) of NEARPOS))) ((SETQ ONGRID? (COND ((LASTMOUSESTATE RIGHT) (* if right is down, flip sense of using grid) (NOT USEGRID)) (T (* otherwise use the grid if told to.) USEGRID))) (SETQ NEW.LEFT (MAP.WINDOW.ONTO.GRID NEW.LEFT SCALE GRID)) (SETQ NEW.BOTTOM (MAP.WINDOW.ONTO.GRID NEW.BOTTOM SCALE GRID] (COND ((OR (NEQ NEW.LEFT GRID.LEFT) (NEQ NEW.BOTTOM GRID.BOTTOM)) (* grid location changed, move the text image.) [COND (GRID.LEFT (BITBLT BUFFER.BITMAP 0 0 W (IPLUS GRID.LEFT XOFFSET) (IPLUS GRID.BOTTOM YOFFSET) WIDTH HEIGHT (QUOTE INPUT) (QUOTE REPLACE] (SETQ GRID.LEFT NEW.LEFT) (SETQ GRID.BOTTOM NEW.BOTTOM) (BITBLT W (IPLUS GRID.LEFT XOFFSET) (IPLUS GRID.BOTTOM YOFFSET) BUFFER.BITMAP 0 0 NIL NIL (QUOTE INPUT) (QUOTE REPLACE)) (BITBLT BITMAP 0 0 DSP (IPLUS GRID.LEFT XOFFSET) (IPLUS GRID.BOTTOM YOFFSET) WIDTH HEIGHT (QUOTE INPUT) OPERATION] finally (* restore screen) (BITBLT BUFFER.BITMAP 0 0 W (IPLUS GRID.LEFT XOFFSET) (IPLUS GRID.BOTTOM YOFFSET) WIDTH HEIGHT (QUOTE INPUT) (QUOTE REPLACE)) (* return the position if any part of the bitmap is visible.) (RETURN (AND (INTERSECTREGIONS (DSPCLIPPINGREGION NIL DSP) (CREATEREGION (IPLUS LEFT XOFFSET) (IPLUS BOTTOM YOFFSET) WIDTH HEIGHT)) (create INPUTPT INPUT.ONGRID? ← ONGRID? INPUT.POSITION ←(create POSITION XCOORD ← GRID.LEFT YCOORD ← GRID.BOTTOM]) ) [DECLARE: EVAL@COMPILE (RECORD INPUTPT (INPUT.ONGRID? INPUT.POSITION) [TYPE? (AND (LISTP DATUM) (OR (NULL (CAR DATUM)) (EQ (CAR DATUM) T)) (LISTP (CDR DATUM)) (POSITIONP (CADR DATUM)) (NULL (CDDR DATUM]) ] (RPAQ? ALL.SKETCHES ) (RPAQ? INITIAL.SCALE 1.0) (RPAQ? DEFAULT.VISIBLE.SCALE.FACTOR 10.0) (RPAQ? MINIMUM.VISIBLE.SCALE.FACTOR 4.0) (RPAQQ SKETCH.ELEMENT.TYPES NIL) (RPAQQ SKETCH.ELEMENT.TYPE.NAMES NIL) (DECLARE: DOEVAL@COMPILE DONTCOPY (GLOBALVARS ALL.SKETCHES INITIAL.SCALE DEFAULT.VISIBLE.SCALE.FACTOR MINIMUM.VISIBLE.SCALE.FACTOR SKETCH.ELEMENT.TYPES SKETCH.ELEMENT.TYPE.NAMES SK.SELECTEDMARK SK.LOCATEMARK COPYSELECTIONMARK MOVESELECTIONMARK DELETESELECTIONMARK) ) (READVARS SK.SELECTEDMARK SK.LOCATEMARK COPYSELECTIONMARK MOVESELECTIONMARK DELETESELECTIONMARK OTHERCONTROLPOINTMARK) ({(READBITMAP)(7 7 "ON@@" "ON@@" "ON@@" "ON@@" "ON@@" "ON@@" "ON@@")} {(READBITMAP)(11 11 "OON@" "OON@" "L@F@" "L@F@" "L@F@" "L@F@" "L@F@" "L@F@" "L@F@" "OON@" "OON@")} {(READBITMAP)(11 11 "@@@@" "EED@" "BJH@" "EED@" "BJH@" "EED@" "BJH@" "EED@" "BJH@" "EED@" "@@@@")} {(READBITMAP)(19 19 "OL@@@@@@" "N@@@@@@@" "O@@@@@@@" "KH@@@@@@" "I@@@@@@@" "H@@@@@@@" "@CH@@@@@" "@CL@@@@@" "@CN@@@@@" "@AO@@@@@" "@@OH@@@@" "@@GH@@@@" "@@CH@@@@" "@@@@@@@@" "@@@@@@@@" "@@@@@@@@" "@@@@@@@@" "@@@@@@@@" "@@@@@@@@")} {(READBITMAP)(13 13 "L@AH" "H@@H" "@@@@" "AHL@" "AML@" "@OH@" "@G@@" "@OH@" "AML@" "AHL@" "@@@@" "H@@H" "L@AH")} {(READBITMAP)(11 11 "@@@@" "@D@@" "BJH@" "AE@@" "BJH@" "EED@" "BJH@" "AE@@" "BJH@" "@D@@" "@@@@")}) (* accessing functions for the methods of a sketch type.) (DEFINEQ (SK.DRAWFN [LAMBDA (ELEMENTTYPE) (* rrb "17-MAR-83 22:28") (* goes from an element type name to its DRAWFN) (fetch (SKETCHTYPE DRAWFN) of (GETPROP ELEMENTTYPE (QUOTE SKETCHTYPE]) (SK.TRANSFORMFN [LAMBDA (ELEMENTTYPE) (* rrb " 7-Feb-85 12:08") (* goes from an element type name to its TRANSFORMFN) (fetch (SKETCHTYPE TRANSFORMFN) of (GETPROP ELEMENTTYPE (QUOTE SKETCHTYPE]) (SK.EXPANDFN [LAMBDA (ELEMENTTYPE) (* goes from an element type name to its EXPANDFN) (fetch (SKETCHTYPE EXPANDFN) of (GETPROP ELEMENTTYPE (QUOTE SKETCHTYPE]) (SK.INPUT [LAMBDA (ELEMENTTYPE SKETCHW) (* rrb "11-MAR-83 09:54") (* applies an element types input function to a window.) (APPLY* (fetch (SKETCHTYPE INPUTFN) of ELEMENTTYPE) SKETCHW]) (SK.INSIDEFN [LAMBDA (ELEMENTTYPE) (* rrb "30-MAR-83 11:54") (* goes from an element type name to its inside predicate) (fetch (SKETCHTYPE INSIDEFN) of (GETPROP ELEMENTTYPE (QUOTE SKETCHTYPE]) (SK.UPDATEFN [LAMBDA (ELEMENTTYPE) (* rrb "21-Dec-84 11:28") (* goes from an element type name to its updatefn The update function is called when an element in a window has changed. It will get args of the old local screen element, the new global element and the window. If it can update the display more efficiently than erasing and redrawing, it should and return the new local sketch element.) (fetch (SKETCHTYPE UPDATEFN) of (GETPROP ELEMENTTYPE (QUOTE SKETCHTYPE]) ) (/DECLAREDATATYPE (QUOTE SKETCHTYPE) (QUOTE (POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER)) (QUOTE ((SKETCHTYPE 0 POINTER) (SKETCHTYPE 2 POINTER) (SKETCHTYPE 4 POINTER) (SKETCHTYPE 6 POINTER) (SKETCHTYPE 8 POINTER) (SKETCHTYPE 10 POINTER) (SKETCHTYPE 12 POINTER) (SKETCHTYPE 14 POINTER) (SKETCHTYPE 16 POINTER) (SKETCHTYPE 18 POINTER) (SKETCHTYPE 20 POINTER) (SKETCHTYPE 22 POINTER) (SKETCHTYPE 24 POINTER) (SKETCHTYPE 26 POINTER) (SKETCHTYPE 28 POINTER))) (QUOTE 30)) (DECLARE: DONTCOPY [DECLARE: EVAL@COMPILE (RECORD SCREENELT (LOCALPART . GLOBALPART) (RECORD GLOBALPART (COMMONGLOBALPART INDIVIDUALGLOBALPART) (RECORD INDIVIDUALGLOBALPART (GTYPE . GOTHERINFO)) (RECORD COMMONGLOBALPART (MINSCALE MAXSCALE SKANNOTATION))) (RECORD LOCALPART (HOTSPOTS LOCALHOTREGION . OTHERLOCALINFO))) (RECORD GLOBALPART (COMMONGLOBALPART INDIVIDUALGLOBALPART) (RECORD INDIVIDUALGLOBALPART (GTYPE . RESTOFGLOBALPART)) (RECORD COMMONGLOBALPART (MINSCALE MAXSCALE SKELEMENTPROPLIST))) (RECORD COMMONGLOBALPART (MINSCALE MAXSCALE SKANNOTATION)) (RECORD INDIVIDUALGLOBALPART (GTYPE . RESTOFGLOBALPART)) (RECORD LOCALPART (HOTSPOTS LOCALHOTREGION . OTHERLOCALINFO)) (RECORD SKETCH (ALLSKETCHPROPS . SKETCHTCELL) (RECORD ALLSKETCHPROPS (SKETCHKEY SKETCHNAME . SKETCHPROPS) (CREATE (LIST (QUOTE SKETCH) NIL (QUOTE VERSION) SKETCH.VERSION))) [RECORD SKETCHTCELL (SKETCHELTS) (CREATE (CONS SKETCHELTS (LAST SKETCHELTS] [TYPE? (AND (LISTP DATUM) (LISTP (CAR DATUM)) (EQ (CAAR DATUM) (QUOTE SKETCH]) (DATATYPE SKETCHTYPE (LABEL (* the label if it is non-NIL will be used in the sketch menu.) DOCSTR (* if put in the menu, this is the help string for its item.) DRAWFN EXPANDFN obsolete CHANGEFN INPUTFN INSIDEFN REGIONFN TRANSLATEFN UPDATEFN READCHANGEFN TRANSFORMFN (* fn to transform the control points of an element. takes args Gelt Tranfn trandata.) TRANSLATEPTSFN (* fn to move some but not all points of a screen element. Takes args: LocalSelectedPts GlobalDeltaToTranslate ScreenElt SketchWindow) GLOBALREGIONFN (* takes a GLOBAL element and returns the global region it occupies. Note: this is the only fn that takes a global rather that a local element.) )) (RECORD SKETCHCONTEXT (SKETCHBRUSH SKETCHFONT SKETCHTEXTALIGNMENT SKETCHARROWHEAD SKETCHDASHING SKETCHUSEARROWHEAD SKETCHTEXTBOXALIGNMENT SKETCHFILLING SKETCHLINEMODE SKETCHARCDIRECTION SKETCHMOVEMODE SKETCHINPUTSCALE)) ] (/DECLAREDATATYPE (QUOTE SKETCHTYPE) (QUOTE (POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER)) (QUOTE ((SKETCHTYPE 0 POINTER) (SKETCHTYPE 2 POINTER) (SKETCHTYPE 4 POINTER) (SKETCHTYPE 6 POINTER) (SKETCHTYPE 8 POINTER) (SKETCHTYPE 10 POINTER) (SKETCHTYPE 12 POINTER) (SKETCHTYPE 14 POINTER) (SKETCHTYPE 16 POINTER) (SKETCHTYPE 18 POINTER) (SKETCHTYPE 20 POINTER) (SKETCHTYPE 22 POINTER) (SKETCHTYPE 24 POINTER) (SKETCHTYPE 26 POINTER) (SKETCHTYPE 28 POINTER))) (QUOTE 30)) ) (ADDTOVAR BackgroundMenuCommands (Sketch (QUOTE (SKETCHW.CREATE NIL NIL (GETREGION) NIL NIL T T)) "Opens a sketch window for use.")) (RPAQQ BackgroundMenu NIL) (FILESLOAD SKETCHELEMENTS GRAPHZOOM SKETCHEDIT SKETCHOBJ SKETCHBMELT TEDIT) (DECLARE: DOEVAL@COMPILE EVAL@LOAD DONTCOPY (FILESLOAD (LOADCOMP) SKETCHELEMENTS SKETCHOBJ SKETCHEDIT) ) (INIT.GROUP.ELEMENT) (* version checking stuff) (DECLARE: EVAL@COMPILE (RPAQQ SKETCH.VERSION 3) (CONSTANTS (SKETCH.VERSION 3)) ) (DEFINEQ (SK.CHECK.SKETCH.VERSION [LAMBDA (SKETCH) (* rrb " 6-Nov-85 11:11") (* makes sure the sketch is the correct version. If not, it tries to update it. Returns SKETCH.) (COND ((EQ (LISTGET (fetch (SKETCH SKETCHPROPS) of SKETCH) (QUOTE VERSION)) SKETCH.VERSION) SKETCH) (T (SK.INSURE.RECORD.LENGTH (fetch (SKETCH SKETCHELTS) of SKETCH)) (* this is basically a PUTSKETCHPROP expanded in line to avoid coersions which can cause loops.) [PROG (PLIST) (SETQ PLIST (fetch (SKETCH SKETCHPROPS) of SKETCH)) (COND ((SETQ PLIST (fetch (SKETCH SKETCHPROPS) of SKETCH)) (LISTPUT PLIST (QUOTE VERSION) SKETCH.VERSION)) (T (replace (SKETCH SKETCHPROPS) of SKETCH with (LIST (QUOTE VERSION) SKETCH.VERSION] SKETCH]) (SK.INSURE.RECORD.LENGTH [LAMBDA (SKETCHELTS) (* rrb "18-Oct-85 14:51") (* makes sure the elements have the proper number of fields.) (bind INDPART TYPE NFIELDS for ELT in SKETCHELTS do (SETQ INDPART (fetch (GLOBALPART INDIVIDUALGLOBALPART) of ELT)) (SETQ TYPE (fetch (INDIVIDUALGLOBALPART GTYPE) of INDPART)) (COND ([OR (SETQ NFIELDS (CADR (ASSOC TYPE SKETCH.RECORD.LENGTHS))) (AND (RECLOOK TYPE) (SETQ SKETCH.RECORD.LENGTHS (NCONC1 SKETCH.RECORD.LENGTHS (LIST TYPE (SETQ NFIELDS (LENGTH (EVAL (LIST (QUOTE CREATE) TYPE] (SK.INSURE.HAS.LENGTH INDPART NFIELDS TYPE))) (* if it's not a record, either it's an unknown sketch element type or its declaration wasn't copied to the compiled file. In either case, assume it has the correct number of fields.) (COND ((EQ TYPE (QUOTE GROUP)) (* recurse thru the subelements too.) (SK.INSURE.RECORD.LENGTH (fetch (GROUP LISTOFGLOBALELTS) of INDPART]) (SK.INSURE.HAS.LENGTH [LAMBDA (LIST N TYPE) (* rrb " 1-Nov-85 08:52") (* makes sure LIST is at least N long. If not, it creates a record of type TYPE and nconcs the enough fields from the end to make it be N long.) (OR (EQLENGTH LIST N) (NCONC LIST (COND [(RECLOOK TYPE) (NTH (EVAL (LIST (QUOTE CREATE) TYPE)) (ADD1 (LENGTH LIST] (T (* no record, add NILs and hope.) (for I from (ADD1 (LENGTH LIST)) to N collect NIL]) (SK.SET.RECORD.LENGTHS [LAMBDA NIL (* rrb "18-Oct-85 15:35") (* sets up a variable that contains the lengths of the sketch element records.) (SETQ SKETCH.RECORD.LENGTHS (SK.SET.RECORD.LENGTHS.MACRO]) ) (DECLARE: EVAL@COMPILE [PUTPROPS SK.SET.RECORD.LENGTHS.MACRO MACRO (ARGS (CONS (QUOTE LIST) (for X in SKETCH.ELEMENT.TYPE.NAMES collect (LIST (QUOTE LIST) (KWOTE X) (LIST (QUOTE LENGTH) (LIST (QUOTE CREATE) X] ) (DECLARE: DOEVAL@COMPILE DONTCOPY (GLOBALVARS SKETCH.RECORD.LENGTHS) ) (SK.SET.RECORD.LENGTHS) (DECLARE: DONTEVAL@LOAD DOEVAL@COMPILE DONTCOPY COMPILERVARS (ADDTOVAR NLAMA ) (ADDTOVAR NLAML ) (ADDTOVAR LAMA SKETCH.CREATE STATUSPRINT) ) (PUTPROPS SKETCH COPYRIGHT ("Xerox Corporation" 1984 1985)) (DECLARE: DONTCOPY (FILEMAP (NIL (17873 22439 (SKETCH.TEST 17883 . 22437)) (22440 73451 (DRAW.LOCAL.SKETCH 22450 . 22811) (SKETCHW.CREATE 22813 . 30245) (SKETCH.RESET 30247 . 31307) (SKETCHW.FIG.CHANGED 31309 . 31729) ( SK.WINDOW.TITLE 31731 . 32157) (EDITSLIDE 32159 . 32550) (EDITSKETCH 32552 . 32879) (SK.FIX.MENU 32881 . 34034) (SK.PUT.ON.FILE 34036 . 36083) (SK.GET.FROM.FILE 36085 . 40846) (SK.ADD.ELEMENTS.TO.SKETCH 40848 . 41141) (STATUSPRINT 41143 . 42291) (CLEARPROMPTWINDOW 42293 . 42758) (CLOSEPROMPTWINDOW 42760 . 43186) (MYGETPROMPTWINDOW 43188 . 43830) (PROMPT.GETINPUT 43832 . 44524) (SK.INSURE.HAS.MENU 44526 . 45181) (SKETCH.SET.A.DEFAULT 45183 . 48860) (SK.POPUP.SELECTIONFN 48862 . 49313) (GETSKETCHWREGION 49315 . 49526) (READ.FUNCTION 49528 . 50064) (READBRUSHSIZE 50066 . 50439) (READANGLE 50441 . 50880) ( READARCDIRECTION 50882 . 51622) (SK.ADD.ELEMENT 51624 . 52932) (SK.ADD.ELEMENTS 52934 . 53200) ( SK.CHECK.WHENADDEDFN 53202 . 53901) (SK.APPLY.MENU.COMMAND 53903 . 54825) (SK.DELETE.ELEMENT1 54827 . 56229) (SK.MARK.DIRTY 56231 . 56615) (SK.MARK.UNDIRTY 56617 . 57016) (SK.MENU.AND.RETURN.FIELD 57018 . 57601) (SK.SCALE.POSITION.INTO.VIEWER 57603 . 58102) (SKETCH.SET.BRUSH.SHAPE 58104 . 58710) ( SKETCH.SET.BRUSH.SIZE 58712 . 59147) (SKETCHW.CLOSEFN 59149 . 61267) (SKETCHW.OUTFN 61269 . 61570) ( SKETCHW.REOPENFN 61572 . 62041) (MAKE.LOCAL.SKETCH 62043 . 62714) (MAP.SKETCHSPEC.INTO.VIEWER 62716 . 63661) (SKETCHW.REPAINTFN 63663 . 64619) (SKETCHW.REPAINTFN1 64621 . 65459) (SK.DRAWFIGURE.IF 65461 . 65959) (SKETCHW.SCROLLFN 65961 . 69007) (SK.UPDATE.EVENT.SELECTION 69009 . 70495) (LIGHTGRAYWINDOW 70497 . 70677) (SK.ADD.SPACES 70679 . 71167) (SK.SKETCH.MENU 71169 . 71425) ( SK.CHECK.IMAGEOBJ.WHENDELETEDFN 71427 . 72103) (SK.APPLY.IMAGEOBJ.WHENDELETEDFN 72105 . 72849) ( SK.RETURN.TTY 72851 . 73169) (SK.TAKE.TTY 73171 . 73449)) (73494 85972 (SKETCH.COMMANDMENU 73504 . 73824) (SKETCH.COMMANDMENU.ITEMS 73826 . 84892) (CREATE.SKETCHW.COMMANDMENU 84894 . 85231) ( SKETCHW.SELECTIONFN 85233 . 85970)) (86024 93168 (SKETCH.CREATE 86034 . 86704) (GETSKETCHPROP 86706 . 88990) (PUTSKETCHPROP 88992 . 92296) (CREATE.DEFAULT.SKETCH.CONTEXT 92298 . 93166)) (93326 106858 ( SK.COPY.BUTTONEVENTFN 93336 . 102331) (SK.BUTTONEVENT.MARK 102333 . 102742) (SK.BUILD.IMAGEOBJ 102744 . 105646) (SK.BUTTONEVENT.OVERP 105648 . 106190) (SK.BUTTONEVENT.SAME.KEYS 106192 . 106856)) (107087 118672 (SK.SEL.AND.CHANGE 107097 . 107449) (SK.CHANGE.ELT 107451 . 107639) (SK.CHANGE.THING 107641 . 108612) (SK.CHANGEFN 108614 . 109063) (SK.READCHANGEFN 109065 . 109504) (SK.DEFAULT.CHANGEFN 109506 . 111312) (CHANGEABLEFIELDITEMS 111314 . 111912) (SK.SEL.AND.MAKE 111914 . 112363) ( SK.APPLY.CHANGE.COMMAND 112365 . 113183) (SK.ELEMENTS.CHANGEFN 113185 . 114992) (READ.POINT.TO.ADD 114994 . 115875) (GLOBAL.KNOT.FROM.LOCAL 115877 . 116409) (SK.ADD.KNOT.TO.ELEMENT 116411 . 117101) ( SK.GROUP.CHANGEFN 117103 . 118670)) (118745 128601 (ADD.ELEMENT.TO.SKETCH 118755 . 119140) ( ADD.SKETCH.VIEWER 119142 . 119759) (REMOVE.SKETCH.VIEWER 119761 . 120294) (ALL.SKETCH.VIEWERS 120296 . 120571) (VIEWER.BUCKET 120573 . 120720) (ELT.INSIDE.REGION? 120722 . 121101) (ELT.INSIDE.SKWP 121103 . 121446) (SCALE.FROM.SKW 121448 . 121708) (SK.ADDELT.TO.WINDOW 121710 . 122565) ( SK.CALC.REGION.VIEWED 122567 . 122878) (SK.DRAWFIGURE 122880 . 123756) (SK.DRAWFIGURE1 123758 . 124074 ) (SK.LOCAL.FROM.GLOBAL 124076 . 125274) (SKETCH.REGION.VIEWED 125276 . 126059) (SKETCH.VIEW.FROM.NAME 126061 . 126553) (SK.UPDATE.REGION.VIEWED 126555 . 126898) (SKETCH.ADD.AND.DISPLAY 126900 . 127357) ( SKETCH.ADD.AND.DISPLAY1 127359 . 127824) (SK.ADD.ITEM 127826 . 128187) (SKETCHW.ADD.INSTANCE 128189 . 128599)) (128784 140057 (SK.SEL.AND.DELETE 128794 . 129116) (SK.ERASE.AND.DELETE.ITEM 129118 . 129467) (REMOVE.ELEMENT.FROM.SKETCH 129469 . 130384) (SK.DELETE.ELEMENT 130386 . 131420) (SK.DELETE.KNOT 131422 . 131765) (SK.SEL.AND.DELETE.KNOT 131767 . 132626) (SK.DELETE.ELEMENT.KNOT 132628 . 134824) ( SK.CHECK.WHENDELETEDFN 134826 . 135831) (SK.CHECK.PREEDITFN 135833 . 136369) (SK.CHECK.WHENEDITEDFN 136371 . 136910) (SK.CHECK.WHENPOINTDELETEDFN 136912 . 137645) (SK.ERASE.ELT 137647 . 138027) ( SK.DELETE.ELT 138029 . 138330) (SK.DELETE.ITEM 138332 . 138739) (DELFROMTCONC 138741 . 140055)) ( 140092 148827 (SK.COPY.ELT 140102 . 140398) (SK.SEL.AND.COPY 140400 . 140716) (SK.COPY.ELEMENTS 140718 . 144750) (SK.GLOBAL.FROM.LOCAL.ELEMENTS 144752 . 145028) (SK.COPY.ITEM 145030 . 145699) ( SK.INSERT.SKETCH 145701 . 148825)) (148863 169904 (SK.MOVE.ELT 148873 . 149196) (SK.MOVE.ELT.OR.PT 149198 . 149529) (SK.APPLY.DEFAULT.MOVE 149531 . 150030) (SK.SEL.AND.MOVE 150032 . 150543) ( SK.MOVE.ELEMENTS 150545 . 158667) (SKETCH.MOVE.ELEMENTS 158669 . 160364) (SK.TRANSLATE.ELEMENT 160366 . 160793) (SK.MAKE.ELEMENT.MOVE.ARG 160795 . 161381) (SK.MAKE.ELEMENTS.MOVE.ARG 161383 . 161882) ( SK.MAKE.POINTS.AND.ELEMENTS.MOVE.ARG 161884 . 162727) (SK.SHOW.FIG.FROM.INFO 162729 . 163047) ( SK.MOVE.THING 163049 . 163846) (UPDATE.ELEMENT.IN.SKETCH 163848 . 164802) (SK.UPDATE.ELEMENT 164804 . 166180) (SK.UPDATE.ELEMENTS 166182 . 166592) (SK.UPDATE.ELEMENT1 166594 . 169563) ( SK.MOVE.ELEMENT.POINT 169565 . 169902)) (169963 188181 (SK.MOVE.POINTS 169973 . 170307) ( SK.SEL.AND.MOVE.POINTS 170309 . 170595) (SK.DO.MOVE.ELEMENT.POINTS 170597 . 176836) ( SK.MOVE.ITEM.POINTS 176838 . 178436) (SK.TRANSLATEPTSFN 178438 . 178766) (SK.TRANSLATE.POINTS 178768 . 179147) (SK.SELECT.MULTIPLE.POINTS 179149 . 184111) (SK.CONTROL.POINTS.IN.REGION 184113 . 185290) ( SK.ADD.PT.SELECTION 185292 . 185725) (SK.REMOVE.PT.SELECTION 185727 . 186344) (SK.ADD.POINT 186346 . 186903) (SK.ELTS.CONTAINING.PTS 186905 . 187544) (SK.HOTSPOTS.NOT.ON.LIST 187546 . 188179)) (188306 190524 (SK.SET.MOVE.MODE 188316 . 188838) (SK.SET.MOVE.MODE.POINTS 188840 . 189119) ( SK.SET.MOVE.MODE.ELEMENTS 189121 . 189405) (SK.SET.MOVE.MODE.COMBINED 189407 . 189697) (READMOVEMODE 189699 . 190522)) (190584 199153 (SKETCH.CREATE.GROUP 190594 . 191018) (SK.CREATE.GROUP1 191020 . 191457) (SK.UPDATE.GROUP.AFTER.CHANGE 191459 . 192246) (SK.GROUP.ELTS 192248 . 192577) ( SK.SEL.AND.GROUP 192579 . 192899) (SK.GROUP.ELEMENTS 192901 . 194533) (SK.UNGROUP.ELT 194535 . 194867) (SK.SEL.AND.UNGROUP 194869 . 195714) (SK.UNGROUP.ELEMENT 195716 . 197088) ( SK.GLOBAL.REGION.OF.LOCAL.ELEMENTS 197090 . 197809) (SK.GLOBAL.REGION.OF.GLOBAL.ELEMENTS 197811 . 198460) (SKETCH.REGION.OF.SKETCH 198462 . 198800) (SK.FLASHREGION 198802 . 199151)) (199154 208254 ( INIT.GROUP.ELEMENT 199164 . 200058) (GROUP.DRAWFN 200060 . 200509) (GROUP.EXPANDFN 200511 . 201620) ( GROUP.INSIDEFN 201622 . 202037) (GROUP.REGIONFN 202039 . 202364) (GROUP.GLOBALREGIONFN 202366 . 202736 ) (GROUP.TRANSLATEFN 202738 . 204135) (GROUP.TRANSFORMFN 204137 . 206357) (GROUP.READCHANGEFN 206359 . 208252)) (208255 209081 (REGION.CENTER 208265 . 208772) (REMOVE.LAST 208774 . 209079)) (209324 211301 (SK.DO.GROUP 209334 . 210068) (SK.DO.UNGROUP 210070 . 210653) (SK.GROUP.UNDO 210655 . 210977) ( SK.UNGROUP.UNDO 210979 . 211299)) (211533 220480 (SK.SEL.AND.TRANSFORM 211543 . 211957) ( SK.TRANSFORM.ELEMENTS 211959 . 213066) (SK.TRANSFORM.ITEM 213068 . 213676) (SK.TRANSFORM.ELEMENT 213678 . 214121) (SK.TRANSFORM.POINT 214123 . 214362) (SK.TRANSFORM.POINT.LIST 214364 . 214585) ( SK.TRANSFORM.REGION 214587 . 216292) (SK.PUT.ELTS.ON.GRID 216294 . 216762) ( SK.TRANSFORM.GLOBAL.ELEMENTS 216764 . 217266) (GLOBALELEMENTP 217268 . 217554) ( SK.TRANSFORM.SCALE.FACTOR 217556 . 218720) (SK.TRANSFORM.BRUSH 218722 . 219100) ( SK.TRANSFORM.ARROWHEADS 219102 . 219890) (SCALE.BRUSH 219892 . 220478)) (220481 238149 ( TWO.PT.TRANSFORMATION.INPUTFN 220491 . 223069) (SK.TWO.PT.TRANSFORM.ELTS 223071 . 223519) ( SK.SEL.AND.TWO.PT.TRANSFORM 223521 . 224150) (SK.APPLY.AFFINE.TRANSFORM 224152 . 224952) ( SK.COMPUTE.TWO.PT.TRANSFORMATION 224954 . 228390) (SK.COMPUTE.SLOPE 228392 . 229038) ( SK.THREE.PT.TRANSFORM.ELTS 229040 . 229495) (SK.COMPUTE.THREE.PT.TRANSFORMATION 229497 . 233384) ( SK.SEL.AND.THREE.PT.TRANSFORM 233386 . 234021) (THREE.PT.TRANSFORMATION.INPUTFN 234023 . 238147)) ( 238150 241952 (SK.COPY.AND.TWO.PT.TRANSFORM.ELTS 238160 . 238622) (SK.SEL.COPY.AND.TWO.PT.TRANSFORM 238624 . 239296) (SK.COPY.AND.THREE.PT.TRANSFORM.ELTS 239298 . 239771) ( SK.SEL.COPY.AND.THREE.PT.TRANSFORM 239773 . 240448) (SK.COPY.AND.TRANSFORM.ELEMENTS 240450 . 241390) ( SK.COPY.AND.TRANSFORM.ITEM 241392 . 241950)) (243887 252360 (SKETCH.ELEMENTS.OF.SKETCH 243897 . 244639 ) (SKETCH.LIST.OF.ELEMENTS 244641 . 245302) (SKETCH.ADD.ELEMENT 245304 . 246316) ( SKETCH.DELETE.ELEMENT 246318 . 247818) (DELFROMGROUPELT 247820 . 248673) (SKETCH.ELEMENT.TYPE 248675 . 248954) (SKETCH.ELEMENT.CHANGED 248956 . 250337) (SK.ELEMENT.CHANGED1 250339 . 251011) ( SK.UPDATE.GLOBAL.IMAGE.OBJECT.ELEMENT 251013 . 252358)) (252410 255797 (INSURE.SKETCH 252420 . 254397) (LOCALSPECS.FROM.VIEWER 254399 . 254724) (SK.LOCAL.ELT.FROM.GLOBALPART 254726 . 255228) ( SKETCH.FROM.VIEWER 255230 . 255412) (INSPECT.SKETCH 255414 . 255795)) (255798 259583 (MAPSKETCHSPECS 255808 . 256408) (MAPCOLLECTSKETCHSPECS 256410 . 257107) (MAPSKETCHSPECSUNTIL 257109 . 257905) ( MAPGLOBALSKETCHSPECS 257907 . 258535) (MAPGLOBALSKETCHELEMENTS 258537 . 259581)) (259618 262435 ( SK.SHOWMARKS 259628 . 260273) (MARKPOINT 260275 . 260997) (SK.MARKHOTSPOTS 260999 . 262011) ( SK.MARK.SELECTION 262013 . 262433)) (263045 268672 (SK.SELECT.ITEM 263055 . 265223) (IN.SKETCH.ELT? 265225 . 267053) (SK.MARK.HOTSPOT 267055 . 267601) (SK.MARK.POSITION 267603 . 267974) (SK.SELECT.ELT 267976 . 268345) (SK.DESELECT.ELT 268347 . 268670)) (268809 279289 (SK.HOTSPOT.CACHE 268819 . 269128) (SK.HOTSPOT.CACHE.FOR.OPERATION 269130 . 270170) (SK.BUILD.CACHE 270172 . 270752) ( SK.ELEMENT.PROTECTED? 270754 . 271314) (SK.HAS.SOME.HOTSPOTS 271316 . 271710) (SK.SET.HOTSPOT.CACHE 271712 . 272035) (SK.CREATE.HOTSPOT.CACHE 272037 . 272412) (SK.ELTS.FROM.HOTSPOT 272414 . 273176) ( SK.ADD.HOTSPOTS.TO.CACHE 273178 . 273517) (SK.ADD.HOTSPOTS.TO.CACHE1 273519 . 273949) ( SK.ADD.HOTSPOT.TO.CACHE 273951 . 275488) (SK.REMOVE.HOTSPOTS.FROM.CACHE 275490 . 275831) ( SK.REMOVE.HOTSPOTS.FROM.CACHE1 275833 . 276245) (SK.REMOVE.HOTSPOT.FROM.CACHE 276247 . 276890) ( SK.REMOVE.VALUE.FROM.CACHE.BUCKET 276892 . 277586) (SK.FIND.CACHE.BUCKET 277588 . 278078) ( SK.ADD.VALUE.TO.CACHE.BUCKET 278080 . 279287)) (279347 303019 (SK.ADD.SELECTION 279357 . 280035) ( SK.COPY.INSERTFN 280037 . 281555) (SK.FIGUREIMAGE 281557 . 285278) (SCREENELEMENTP 285280 . 285647) ( SK.ITEM.REGION 285649 . 286153) (SK.ELEMENT.GLOBAL.REGION 286155 . 286685) (SK.LOCAL.ITEMS.IN.REGION 286687 . 288080) (SK.REGIONFN 288082 . 288390) (SK.GLOBAL.REGIONFN 288392 . 288736) ( SK.REMOVE.SELECTION 288738 . 289401) (SK.SELECT.MULTIPLE.ITEMS 289403 . 298647) (SK.PUT.MARKS.UP 298649 . 299056) (SK.TAKE.MARKS.DOWN 299058 . 299478) (SK.TRANSLATE.GLOBALPART 299480 . 301367) ( SK.TRANSLATE.ITEM 301369 . 302220) (SK.TRANSLATEFN 302222 . 302428) (TRANSLATE.SKETCH 302430 . 303017) ) (303341 304058 (ELT.INSIDE.SKETCHWP 303351 . 303689) (SK.INSIDE.REGION 303691 . 304056)) (304106 306763 (SK.INPUT.SCALE 304116 . 304870) (SK.UPDATE.SKETCHCONTEXT 304872 . 305512) (SK.SET.INPUT.SCALE 305514 . 305975) (SK.SET.INPUT.SCALE.CURRENT 305977 . 306321) (SK.SET.INPUT.SCALE.VALUE 306323 . 306761)) (306810 308414 (SK.SET.FEEDBACK.MODE 306820 . 307822) (SK.SET.FEEDBACK.POINT 307824 . 308002) (SK.SET.FEEDBACK.VERBOSE 308004 . 308215) (SK.SET.FEEDBACK.ALWAYS 308217 . 308412)) (308562 320143 ( SKETCHW.SCALE 308572 . 308649) (SKETCH.ZOOM 308651 . 309565) (SAME.ASPECT.RATIO 309567 . 310623) ( SKETCH.DO.ZOOM 310625 . 311782) (SKETCH.NEW.VIEW 311784 . 312192) (ZOOM.UPDATE.ELT 312194 . 312888) ( SK.UPDATE.AFTER.SCALE.CHANGE 312890 . 314537) (SKETCH.AUTOZOOM 314539 . 317540) ( SKETCH.GLOBAL.REGION.ZOOM 317542 . 320141)) (320852 326974 (SKETCH.HOME 320862 . 321360) (SK.FRAME.IT 321362 . 321896) (SK.MOVE.TO.VIEW 321898 . 323135) (SK.NAME.CURRENT.VIEW 323137 . 323911) ( SKETCH.ADD.VIEW 323913 . 324623) (SK.RESTORE.VIEW 324625 . 325799) (SK.FORGET.VIEW 325801 . 326972)) ( 327170 343466 (SK.SET.GRID 327180 . 327545) (SK.DISPLAY.GRID 327547 . 328057) (SK.DISPLAY.GRID.POINTS 328059 . 328248) (SK.REMOVE.GRID.POINTS 328250 . 328675) (SK.TAKE.DOWN.GRID 328677 . 329004) ( SK.SHOW.GRID 329006 . 331691) (SK.GRIDFACTOR 331693 . 332238) (SK.TURN.GRID.ON 332240 . 332588) ( SK.TURN.GRID.OFF 332590 . 332963) (SK.MAKE.GRID.LARGER 332965 . 333317) (SK.MAKE.GRID.SMALLER 333319 . 333671) (SK.CHANGE.GRID 333673 . 334211) (GRID.FACTOR1 334213 . 334623) (LEASTPOWEROF2GT 334625 . 335281) (GREATESTPOWEROF2LT 335283 . 335938) (SK.DEFAULT.GRIDFACTOR 335940 . 336386) (SK.PUT.ON.GRID 336388 . 336863) (MAP.WINDOW.ONTO.GRID 336865 . 337237) (MAP.SCREEN.ONTO.GRID 337239 . 337771) ( MAP.GLOBAL.PT.ONTO.GRID 337773 . 338235) (MAP.GLOBAL.REGION.ONTO.GRID 338237 . 339487) ( MAP.WINDOW.POINT.ONTO.GLOBAL.GRID 339489 . 340039) (MAP.WINDOW.ONTO.GLOBAL.GRID 340041 . 340381) ( SK.UPDATE.GRIDFACTOR 340383 . 340957) (SK.MAP.FROM.WINDOW.TO.GLOBAL.GRID 340959 . 341559) ( SK.MAP.INPUT.PT.TO.GLOBAL 341561 . 342505) (SK.MAP.FROM.WINDOW.TO.NEAREST.GRID 342507 . 343464)) ( 343599 345202 (SKETCH.TITLE 343609 . 343927) (SK.SHRINK.ICONCREATE 343929 . 345200)) (350470 356495 ( SK.ADD.HISTEVENT 350480 . 351262) (SK.SEL.AND.UNDO 351264 . 353215) (SK.UNDO.LAST 353217 . 354799) ( SK.UNDO.NAME 354801 . 355181) (SKEVENTTYPEFNS 355183 . 355498) (SK.TYPE.OF.FIRST.ARG 355500 . 356493)) (356496 357279 (SK.DELETE.UNDO 356506 . 356891) (SK.ADD.UNDO 356893 . 357277)) (357280 358467 ( SK.CHANGE.UNDO 357290 . 357943) (SK.CHANGE.REDO 357945 . 358465)) (358468 360367 (SK.UNDO.UNDO 358478 . 359553) (SK.UNDO.MENULABEL 359555 . 359930) (SK.LABEL.FROM.TYPE 359932 . 360365)) (361156 379665 ( SKETCHW.HARDCOPYFN 361166 . 365513) (\SK.LIST.PAGE.IMAGE 365515 . 367280) (SK.LIST.IMAGE 367282 . 375678) (SK.LIST.IMAGE.ON.FILE 375680 . 376390) (SK.SET.HARDCOPY.MODE 376392 . 377628) ( SK.UNSET.HARDCOPY.MODE 377630 . 378061) (SK.UPDATE.AFTER.HARDCOPY 378063 . 378714) ( DEFAULTPRINTINGIMAGETYPE 378716 . 379228) (SK.SWITCH.REGION.X.AND.Y 379230 . 379663)) (379907 387373 ( SHOW.GLOBAL.COORDS 379917 . 380419) (LOCATOR.CLOSEFN 380421 . 380778) (SKETCHW.FROM.LOCATOR 380780 . 381155) (SKETCHW.UPDATE.LOCATORS 381157 . 381756) (LOCATOR.UPDATE 381758 . 382520) ( UPDATE.GLOBAL.LOCATOR 382522 . 383221) (UPDATE.GLOBALCOORD.LOCATOR 383223 . 383823) ( ADD.GLOBAL.DISPLAY 383825 . 384753) (ADD.GLOBAL.GRIDDED.DISPLAY 384755 . 384975) ( CREATE.GLOBAL.DISPLAYER 384977 . 385924) (UPDATE.GLOBAL.GRIDDED.COORD.LOCATOR 385926 . 387371)) ( 387586 387976 (READBRUSHSHAPE 387596 . 387974)) (387977 396056 (SK.CHANGE.DASHING 387987 . 391127) ( READ.AND.SAVE.NEW.DASHING 391129 . 392430) (READ.NEW.DASHING 392432 . 393504) (READ.DASHING.CHANGE 393506 . 394478) (DASHINGP 394480 . 394874) (SK.CACHE.DASHING 394876 . 395621) (SK.DASHING.LABEL 395623 . 396054)) (396057 398941 (READ.FILLING.CHANGE 396067 . 397197) (SK.CACHE.FILLING 397199 . 397850) (READ.AND.SAVE.NEW.FILLING 397852 . 398471) (SK.FILLING.LABEL 398473 . 398939)) (399298 408965 (DISPLAYREADCOLORHLSLEVELS 399308 . 400159) (DISPLAYREADCOLORLEVEL 400161 . 401007) (DRAWREADCOLORBOX 401009 . 401822) (READ.CHANGE.COLOR 401824 . 401975) (READCOLOR1 401977 . 404158) ( READCOLORCOMMANDMENUSELECTEDFN 404160 . 404529) (READCOLOR2 404531 . 408963)) (408966 410244 ( CREATE.CNS.MENU 408976 . 410242)) (410392 411419 (SCALE.POSITION.INTO.SKETCHW 410402 . 410745) ( UNSCALE 410747 . 410879) (UNSCALE.REGION 410881 . 411417)) (411466 428631 (SK.GETGLOBALPOSITION 411476 . 411834) (GETSKWPOSITION 411836 . 415032) (SKETCH.TRACK.ELEMENTS 415034 . 418316) ( SK.READ.POINT.WITH.FEEDBACK 418318 . 422317) (NEAREST.HOT.SPOT 422319 . 423436) (GETWREGION 423438 . 424063) (GET.BITMAP.POSITION 424065 . 424778) (SK.TRACK.BITMAP1 424780 . 428629)) (430362 432488 ( SK.DRAWFN 430372 . 430682) (SK.TRANSFORMFN 430684 . 431009) (SK.EXPANDFN 431011 . 431236) (SK.INPUT 431238 . 431566) (SK.INSIDEFN 431568 . 431909) (SK.UPDATEFN 431911 . 432486)) (436761 440171 ( SK.CHECK.SKETCH.VERSION 436771 . 437876) (SK.INSURE.RECORD.LENGTH 437878 . 439166) ( SK.INSURE.HAS.LENGTH 439168 . 439822) (SK.SET.RECORD.LENGTHS 439824 . 440169))))) STOP