(FILECREATED "27-Jan-87 11:23:32" {DANTE}<NEWMAN>LISP>DVNPATCH003.;16 16200  

      changes to:  (VARS DVNPATCH003COMS)
		   (FNS EDITMOVEREGION EDITMOVESUBTREE NOT.TRACKCURSOR MOVEDESCENDENTS 
			COLLECT.CHILD.NODES CREATE.NEW.NODEPOSITION)

      previous date: "26-Jan-87 18:06:11" {DANTE}<NEWMAN>LISP>DVNPATCH003.;15)


(* Copyright (c) 1987 by Xerox Corporation. All rights reserved.)

(PRETTYCOMPRINT DVNPATCH003COMS)

(RPAQQ DVNPATCH003COMS [(P (if (NOT (OR (MEMBER (QUOTE GRAPHER)
						  SYSFILES)
					  (MEMBER (QUOTE GRAPHER)
						  FILELST)))
				 then
				 (ERROR 
			       "GRAPHER is not loaded.  It must be loaded before MOVENODESPATCH.")))
			  (* * This file is intended to patch the methods by which GRAPHER and the 
			     NoteCards browser card allow the user to move nodes within the graph. It 
			     make available two new methods of node movement, both of which allow the 
			     movement of several nodes in the graph at once. The first method allows 
			     the user to move the root node of a subtree, and then moves all children 
			     of that node in analogous fashion. The second method allows the user to 
			     sweep out a region of the graph window, after which all nodes within 
			     that region are moved to new locations within a new region of the same 
			     size as the first which is specified by the user in response to a 
			     prompt.)
			  (FNS NC.BrowserMoveNodesInRegionFn NC.BrowserMoveSubtreeFn EDITMOVEREGION 
			       EDITMOVESUBTREE NOT.TRACKCURSOR RECURSIVE.COLLECTDESCENDENTS 
			       MOVEDESCENDENTS COLLECT.CHILD.NODES CREATE.NEW.NODEPOSITION 
			       GETBOXPOSITION.FROMINITIALREGION)
			  (P (DREMOVE (SASSOC "Move Node" EDITGRAPHMENUCOMMANDS)
				      EDITGRAPHMENUCOMMANDS)
			     [ADDTOVAR EDITGRAPHMENUCOMMANDS (Move% Node (QUOTE MOVENODE)
									 
							      "Moves a single node in the graph."
									 (SUBITEMS
									   (Move% Single% Node
									     (QUOTE MOVENODE)
									     
							      "Moves a single node in the graph.")
									   (Move% Node% and% Subtree
									     (EDITMOVESUBTREE 
										      GRAPHWINDOW)
									     
			       "Moves a subtree of nodes relative to the movement of their root.")
									   (Move% Region
									     (EDITMOVEREGION 
										      GRAPHWINDOW)
									     
			    "Moves a group of nodes within a specified region to another region."]
			     (SETQ EDITGRAPHMENU NIL)
			     (if (OR (MEMBER (QUOTE NOTECARDS)
					     SYSFILES)
				     (MEMBER (QUOTE NOTECARDS)
					     FILELST))
				 then
				 (for Var in (QUOTE (NC.GraphEditUnfixedMenuItems 
								     NC.GraphEditUnfixedMenuItems 
									    NC.GraphEditMenuItems))
				      do
				      (DREMOVE (ASSOC (QUOTE Move% Node)
						      (EVAL Var))
					       (EVAL Var))
				      (APPLY (QUOTE ADDTOVAR)
					     (LIST Var (QUOTE (Move% Node NC.BrowserMoveNodeFn 
									  "Move a browser node."
									  (SUBITEMS (
Move% Single% Node NC.BrowserMoveNodeFn "Move a browser node.")
										    (
Move% Node% &% Subtree NC.BrowserMoveSubtreeFn 
		       "Move a subtree of nodes following the movement of the root.")
										    (Move% Region
										      
								    NC.BrowserMoveNodesInRegionFn 
				    "Move all nodes within a specified region to another region."])
(if (NOT (OR (MEMBER (QUOTE GRAPHER)
		     SYSFILES)
	     (MEMBER (QUOTE GRAPHER)
		     FILELST)))
    then
    (ERROR "GRAPHER is not loaded.  It must be loaded before MOVENODESPATCH."))
(* * This file is intended to patch the methods by which GRAPHER and the NoteCards browser 
card allow the user to move nodes within the graph. It make available two new methods of node 
movement, both of which allow the movement of several nodes in the graph at once. The first 
method allows the user to move the root node of a subtree, and then moves all children of that 
node in analogous fashion. The second method allows the user to sweep out a region of the graph
 window, after which all nodes within that region are moved to new locations within a new 
region of the same size as the first which is specified by the user in response to a prompt.)

(DEFINEQ

(NC.BrowserMoveNodesInRegionFn
  [LAMBDA (Window)                                           (* Newman "26-Jan-87 12:35")

          (* * Move all the browser nodes in a region.)


    (EDITMOVEREGION Window)
    (NC.MarkCardDirty (NC.CoerceToCard Window])

(NC.BrowserMoveSubtreeFn
  [LAMBDA (Window)                                           (* Newman "26-Jan-87 12:36")

          (* * Move a browser node and all its descendents.)


    (EDITMOVESUBTREE Window)
    (NC.MarkCardDirty (NC.CoerceToCard Window])

(EDITMOVEREGION
  [LAMBDA (Window)                                           (* Newman "27-Jan-87 11:08")

          (* * This function moves all the nodes within a selected region to another region of similar shape and size.)


    (if (NOT (WINDOWP Window))
	then (ERROR Window " not a window.")
      else (PROMPTPRINT " Select the region containing the nodes you wish to move.")
	     (PROG* ((DisplayStream (WINDOWPROP Window (QUOTE DSP)))
		     (Region (GETWREGION Window))
		     (Graph (WINDOWPROP Window (QUOTE GRAPH)))
		     (NodeList (for Node in (fetch (GRAPH GRAPHNODES) of Graph)
				  when (OR (INTERSECTREGIONS Region (NODEREGION Node))
					       (SUBREGIONP Region (NODEREGION Node)))
				  collect Node)))
		    (if (NULL Graph)
			then (ERROR Window " not a graph window.")
		      elseif (NULL NodeList)
			then (PROMPTPRINT "No nodes in the region selected."))
		    (for Node in NodeList do (FLIPNODE Node DisplayStream))
		    (bind OldPos (NewRegionPosition ←(GETBOXPOSITION.FROMINITIALREGION Window 
											   Region 
										    DisplayStream))
		       for SelectedNode in NodeList eachtime (SETQ OldPos
								     (fetch (GRAPHNODE NODEPOSITION)
									of SelectedNode))
		       do (MOVENODE SelectedNode OldPos (CREATE.NEW.NODEPOSITION
					  SelectedNode
					  (DIFFERENCE (fetch (POSITION XCOORD) of 
										NewRegionPosition)
							(fetch (REGION LEFT) of Region))
					  (DIFFERENCE (fetch (POSITION YCOORD) of 
										NewRegionPosition)
							(fetch (REGION BOTTOM) of Region)))
					Graph DisplayStream)
			    (EXTENDEXTENT (WFROMDS DisplayStream)
					    (NODEREGION SelectedNode))
                                                             (* extent the graph extent because the node may be 
							     outside the old extent.)
			    (FLIPNODE SelectedNode DisplayStream])

(EDITMOVESUBTREE
  [LAMBDA (WINDOW)                                           (* Newman "27-Jan-87 11:10")

          (* * Code derived from EDITMOVENODE by Richard Burton. Changes to prompt strings, and changes the to TRACKCURSOR to
	  a call to NOT.TRACKCURSOR)

                                                             (* hilite nodes until the cursor goes down then move 
							     it)
    (PROG ((DS (WINDOWPROP WINDOW (QUOTE DSP)))
	     (REG (WINDOWPROP WINDOW (QUOTE REGION)))
	     (GRAPH (WINDOWPROP WINDOW (QUOTE GRAPH)))
	     OLDPOS NOW NEAR NODELST)
	    (COND
	      (GRAPH (SETQ NODELST (fetch (GRAPH GRAPHNODES) of GRAPH)))
	      (T (RETURN)))
	    (printout PROMPTWINDOW T "Move the cursor to the node " "that is the common root of " 
		      "the subtree you want to move "
		      "and press any button.")
	    [SETQ NEAR (NODELST/AS/MENU NODELST (SETQ OLDPOS (CURSORPOSITION NIL DS]
	FLIP(AND NOW (FLIPNODE NOW DS))
	    (AND NEAR (FLIPNODE NEAR DS))
	    (SETQ NOW NEAR)
	LP  (GETMOUSESTATE)
	    (COND
	      ((LASTMOUSESTATE (NOT UP))                   (* button up, process it.)
		(AND NOW (FLIPNODE NOW DS))              (* NOW node has been selected.)
		)
	      ([EQ NOW (SETQ NEAR (NODELST/AS/MENU NODELST (CURSORPOSITION NIL DS OLDPOS]
		(GO LP))
	      (T (GO FLIP)))
	    (printout PROMPTWINDOW T "Holding the button down, " "move the node to its new position" 
		      "and release the button.")
	    (NOT.TRACKCURSOR NOW DS GRAPH)
	    (printout PROMPTWINDOW T "Done."])

(NOT.TRACKCURSOR
  [LAMBDA (Node DisplayStream Graph)                         (* Newman "27-Jan-87 11:21")

          (* * Gets an old, and a new region from the user, and uses these to calculate all the new positions for all the 
	  children of Node.)


    (if (NULL Node)
	then (PROMPTPRINT "No node selected.")
      else (PROG* ((Children (RECURSIVE.COLLECTDESCENDENTS Node Graph))
		     [OldRegion (APPLY (QUOTE UNIONREGIONS)
					 (for EachNode in (CONS Node Children)
					    collect (FLIPNODE EachNode DisplayStream)
						      (NODEREGION EachNode]
		     (NewRegionPosition (GETBOXPOSITION.FROMINITIALREGION (WFROMDS DisplayStream)
									    OldRegion DisplayStream))
		     (deltaX (DIFFERENCE (fetch (POSITION XCOORD) of NewRegionPosition)
					   (fetch (REGION LEFT) of OldRegion)))
		     (deltaY (DIFFERENCE (fetch (POSITION YCOORD) of NewRegionPosition)
					   (fetch (REGION BOTTOM) of OldRegion)))
		     (OldPos (fetch (GRAPHNODE NODEPOSITION) of Node))
		     (NewPos (CREATE.NEW.NODEPOSITION Node deltaX deltaY)))
		    [if (NOT (EQUAL OldPos NewPos))
			then (MOVENODE Node OldPos NewPos Graph DisplayStream)
			       (EXTENDEXTENT (WFROMDS DisplayStream)
					       (NODEREGION Node))
			       (CALL.MOVENODEFN Node OldPos Graph (WFROMDS DisplayStream)
						  NewPos)
			       (if Children
				   then (PROG [(MovedNodes (LIST (fetch (GRAPHNODE NODEID)
									  of Node]
					          (MOVEDESCENDENTS Graph Node DisplayStream deltaX 
								     deltaY]
		    (for EachNode in (CONS Node Children) do (FLIPNODE EachNode 
										 DisplayStream])

(RECURSIVE.COLLECTDESCENDENTS
  [LAMBDA (Node Graph)                                       (* Newman "26-Jan-87 13:18")

          (* * Collect all descendents of Node in Graph.)


    (for Child in (COLLECT.CHILD.NODES Node Graph) join (CONS Child (
								     RECURSIVE.COLLECTDESCENDENTS
									  Child Graph])

(MOVEDESCENDENTS
  [LAMBDA (Graph Node DisplayStream deltaX deltaY)           (* Newman "27-Jan-87 11:08")

          (* * Moves Node and all Children of Node by deltaX and deltaY.)



          (* * first, finds all descendents of Node. For each of these, create a new position based on the old and the 
	  deltas. Then, if the child has not been moved yet, we add it to the list of moved nodes, move the node, and call 
	  the MOVENODEFN,)


    (bind (MovedNodes ←(LIST Node))
	    NewPos for Child in (RECURSIVE.COLLECTDESCENDENTS Node Graph)
       eachtime (SETQ NewPos (CREATE.NEW.NODEPOSITION Child deltaX deltaY))
       unless (MEMBER (fetch (GRAPHNODE NODEID) of Child)
			  MovedNodes)
       do (SETQ MovedNodes (CONS (fetch (GRAPHNODE NODEID) of Child)
				       MovedNodes))
	    (MOVENODE Child (fetch NODEPOSITION of Child)
			NewPos Graph DisplayStream)
	    (EXTENDEXTENT (WFROMDS DisplayStream)
			    (NODEREGION Child))            (* we must call EXTENDEXTENT to extend the graph 
							     extent in case we have moved a node outside the 
							     previous extent.)
	    (CALL.MOVENODEFN Child NewPos Graph (WFROMDS DisplayStream)
			       (fetch NODEPOSITION of Child])

(COLLECT.CHILD.NODES
  [LAMBDA (Node Graph)                                       (* Newman "27-Jan-87 11:16")

          (* * collect all immediate children (only one generation) of Node in Graph.)


    (bind (GraphNodes ←(fetch (GRAPH GRAPHNODES) of Graph)) for NodeID
       in (fetch (GRAPHNODE TONODES) of Node)
       collect 

          (* ??? (ASSOC (if (AND (LISTP NodeID) (EQUAL (CAR NodeID) (QUOTE Link% Parameters))) then (* Special case where the
	  second item in the list is the NodeID) (CADR NodeID) else NodeID) GraphNodes))


		 (GETNODEFROMID NodeID GraphNodes])

(CREATE.NEW.NODEPOSITION
  [LAMBDA (Node deltaX deltaY)                               (* Newman "27-Jan-87 11:06")

          (* * Creates a new position for Node by adding deltaX and deltaY to the appropriate coordinates.)


    (PROG ((OldPos (fetch (GRAPHNODE NODEPOSITION) of Node)))
	    (RETURN (create POSITION
				XCOORD ←(PLUS deltaX (fetch (POSITION XCOORD) of OldPos))
				YCOORD ←(PLUS deltaY (fetch (POSITION YCOORD) of OldPos])

(GETBOXPOSITION.FROMINITIALREGION
  [LAMBDA (Window Region DisplayStream)                      (* Newman "26-Jan-87 11:38")

          (* * This function obtains a new region from the user, and it prompts the user using the region passed in as 
	  Region. DisplayStream is the displaystream of Window, and Region is considered to be a region within Window.
	  This function was written to be called from EDITMOVEREGION.)



          (* All of the garbage below to calculate the third and fourth arguments to GETBOXPOSITION exists to put the ghost 
	  box prompting the user in exactly the same place as the region passed in.)


    (GETBOXPOSITION (fetch (REGION WIDTH) of Region)
		      (fetch (REGION HEIGHT) of Region)
		      (DIFFERENCE (PLUS (fetch (REGION LEFT) of Region)
					    (fetch (REGION LEFT) of (WINDOWPROP Window
										      (QUOTE REGION)
										      ))
					    (WINDOWPROP Window (QUOTE BORDER)))
				    (fetch (REGION LEFT) of (DSPCLIPPINGREGION NIL 
										    DisplayStream)))
		      (DIFFERENCE (PLUS (fetch (REGION BOTTOM) of Region)
					    (fetch (REGION BOTTOM) of (WINDOWPROP Window
											(QUOTE
											  REGION)))
					    (WINDOWPROP Window (QUOTE BORDER)))
				    (fetch (REGION BOTTOM) of (DSPCLIPPINGREGION NIL 
										    DisplayStream)))
		      Window "Select new region for nodes."])
)
(DREMOVE (SASSOC "Move Node" EDITGRAPHMENUCOMMANDS)
	 EDITGRAPHMENUCOMMANDS)
[ADDTOVAR EDITGRAPHMENUCOMMANDS (Move% Node (QUOTE MOVENODE)
					    "Moves a single node in the graph."
					    (SUBITEMS (Move% Single% Node (QUOTE MOVENODE)
									  
							      "Moves a single node in the graph.")
						      (Move% Node% and% Subtree (EDITMOVESUBTREE
										  GRAPHWINDOW)
										
			       "Moves a subtree of nodes relative to the movement of their root.")
						      (Move% Region (EDITMOVEREGION GRAPHWINDOW)
								    
			    "Moves a group of nodes within a specified region to another region."]
(SETQ EDITGRAPHMENU NIL)
[if (OR (MEMBER (QUOTE NOTECARDS)
		SYSFILES)
	(MEMBER (QUOTE NOTECARDS)
		FILELST))
    then
    (for Var in (QUOTE (NC.GraphEditUnfixedMenuItems NC.GraphEditUnfixedMenuItems 
						     NC.GraphEditMenuItems))
	 do
	 (DREMOVE (ASSOC (QUOTE Move% Node)
			 (EVAL Var))
		  (EVAL Var))
	 (APPLY (QUOTE ADDTOVAR)
		(LIST Var (QUOTE (Move% Node NC.BrowserMoveNodeFn "Move a browser node."
					     (SUBITEMS (Move% Single% Node NC.BrowserMoveNodeFn 
									   "Move a browser node.")
						       (Move% Node% &% Subtree 
									  NC.BrowserMoveSubtreeFn 
				    "Move a subtree of nodes following the movement of the root.")
						       (Move% Region NC.BrowserMoveNodesInRegionFn 
				    "Move all nodes within a specified region to another region."]
(PUTPROPS DVNPATCH003 COPYRIGHT ("Xerox Corporation" 1987))
(DECLARE: DONTCOPY
  (FILEMAP (NIL (4183 14718 (NC.BrowserMoveNodesInRegionFn 4193 . 4472) (NC.BrowserMoveSubtreeFn 4474 . 
4753) (EDITMOVEREGION 4755 . 6862) (EDITMOVESUBTREE 6864 . 8539) (NOT.TRACKCURSOR 8541 . 10358) (
RECURSIVE.COLLECTDESCENDENTS 10360 . 10717) (MOVEDESCENDENTS 10719 . 12063) (COLLECT.CHILD.NODES 12065
 . 12703) (CREATE.NEW.NODEPOSITION 12705 . 13210) (GETBOXPOSITION.FROMINITIALREGION 13212 . 14716))))
)
STOP