home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / GRAPHICS / MISC / EEDRW23S.ZIP / EEMODIFY.C < prev    next >
Encoding:
C/C++ Source or Header  |  1991-01-12  |  43.4 KB  |  1,272 lines

  1. /*****************************************************************************
  2. *   Program to draw EE diagrams.                         *
  3. *                                         *
  4. * This module handles object modification.                     *
  5. *                                         *
  6. * Written by:  Gershon Elber            IBM PC Ver 1.0,    Oct. 1989    *
  7. *****************************************************************************/
  8.  
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <alloc.h>
  13. #include <dos.h>
  14. #include "Program.h"
  15. #include "EECreate.h"
  16. #include "EELibs.h"
  17. #include "EEModify.h"
  18. #include "EERedraw.h"
  19. #include "EEString.h"
  20.  
  21. #define UNDELETE_STACK_SIZE 10
  22.  
  23. static char *EditMenuStrs[] =
  24. {
  25.     "Done",
  26.     "",
  27.     "EditPartName",
  28.     "Un/DrawChipName",
  29.     "ReposPartName",
  30.     "ReposChipName",
  31.     "RePosLibItem"
  32. };
  33. #define EDIT_MENU_SIZE (sizeof(EditMenuStrs) / sizeof(char *))
  34.  
  35. static int
  36.     UnDeleteStackPtr = 0;
  37. static DrawGenericStruct
  38.     *LastSnappedStruct = NULL;
  39. static DrawGenericStruct *UnDeleteStack[UNDELETE_STACK_SIZE];
  40. static int PickedBoxMinX, PickedBoxMinY, PickedBoxMaxX, PickedBoxMaxY;
  41. static IntrCursorShapeStruct Cursor;
  42. static IntrPopUpMenuStruct
  43.     *EditPopUpMenu = NULL;
  44.  
  45. static void MoveStructs(DrawPickedStruct *DrawStructs, int Dx, int Dy);
  46. static void MoveOneStruct(DrawGenericStruct *DrawStructs, int Dx, int Dy);
  47. static int PlaceStruct(DrawGenericStruct *DrawStruct);
  48. static DrawGenericStruct *CopyStructLocal(DrawGenericStruct *DrawStruct);
  49.  
  50. /*****************************************************************************
  51. * Routine to move an object(s) to a new position.                 *
  52. * If DrawStruct is of type DrawPickedStruct, a list of objects picked is     *
  53. * assumed, otherwise exactly one structure is assumed been picked.         *
  54. *****************************************************************************/
  55. BooleanType MoveStruct(DrawGenericStruct *DrawStruct)
  56. {
  57.     BooleanType RetVal;
  58.  
  59.     /* Remove this structure(s) from display and global structure list.         */
  60.     DeleteStruct(DrawStruct);
  61.  
  62.     RetVal = PlaceStruct(DrawStruct);        /* Place it in its new position. */
  63.  
  64.     UnDeleteStruct();             /* And undelete it in its new position. */
  65.  
  66.     return RetVal;
  67. }
  68.  
  69. /*****************************************************************************
  70. * Routine to copy a new entity of an object and reposition it.             *
  71. * If DrawStruct is of type DrawPickedStruct, a list of objects picked is     *
  72. * assumed, otherwise exactly one structure is assumed been picked.         *
  73. *****************************************************************************/
  74. BooleanType CopyStruct(DrawGenericStruct *DrawStruct)
  75. {
  76.     BooleanType RetVal;
  77.  
  78.     DrawGenericStruct *NewDrawStruct;
  79.     DrawPickedStruct *PickedItem,
  80.         *PickedList = NULL;
  81.  
  82.     NewDrawStruct = CopyStructLocal(DrawStruct);
  83.  
  84.     if ((RetVal = PlaceStruct(NewDrawStruct)) != FALSE) {
  85.     /* Draw the new structure and chain it in: */
  86.     if (NewDrawStruct -> StructType == DRAW_PICK_ITEM_STRUCT_TYPE) {
  87.         RedrawStructList(NewDrawStruct, GR_COPY_PUT, EE_DRAW_COLOR);
  88.  
  89.         PickedList = (DrawPickedStruct *) NewDrawStruct;
  90.         while (PickedList) {
  91.         PickedList -> PickedStruct -> Pnext =
  92.                             EEActiveWindow -> EEDrawList;
  93.         EEActiveWindow -> EEDrawList = PickedList -> PickedStruct;
  94.  
  95.         PickedItem = PickedList;
  96.         PickedList = PickedList -> Pnext;
  97.         MyFree((VoidPtr) PickedItem);
  98.         }
  99.     }
  100.     else {
  101.         RedrawOneStruct(NewDrawStruct, GR_COPY_PUT, EE_DRAW_COLOR);
  102.  
  103.         NewDrawStruct->Pnext = EEActiveWindow -> EEDrawList;
  104.         EEActiveWindow -> EEDrawList = NewDrawStruct;
  105.     }
  106.     }
  107.     else
  108.     FreeStruct(NewDrawStruct);
  109.  
  110.     /* Free the original DrawPickedStruct chain: */
  111.     if (DrawStruct -> StructType == DRAW_PICK_ITEM_STRUCT_TYPE) {
  112.     PickedList = (DrawPickedStruct *) DrawStruct;
  113.  
  114.     while (PickedList != NULL) {
  115.         PickedItem = PickedList;
  116.         PickedList = PickedList -> Pnext;
  117.         MyFree((VoidPtr) PickedItem);
  118.     }
  119.     }
  120.  
  121.     return RetVal;
  122. }
  123.  
  124. /*****************************************************************************
  125. * Routine to delete an object from global drawing object list.             *
  126. *****************************************************************************/
  127. void DeleteStruct(DrawGenericStruct *DrawStruct)
  128. {
  129.     int i;
  130.     DrawGenericStruct
  131.     *DrawList = EEActiveWindow -> EEDrawList;
  132.     DrawPickedStruct
  133.     *PickedList = NULL;
  134.  
  135.     /* Effectively hides the cursor to prevent from its    interference with   */
  136.     /* the erased object(s).                            */
  137.     IntrPushCursorType();
  138.  
  139.     if (DrawStruct -> StructType == DRAW_PICK_ITEM_STRUCT_TYPE) {
  140.     PickedList = (DrawPickedStruct *) DrawStruct;
  141.     while (PickedList) {
  142.         if (PickedList -> PickedStruct == EEActiveWindow -> EEDrawList)
  143.         EEActiveWindow -> EEDrawList =
  144.                     EEActiveWindow -> EEDrawList -> Pnext;
  145.         else {
  146.         DrawList = EEActiveWindow -> EEDrawList;
  147.         while (DrawList -> Pnext) {
  148.             if (DrawList -> Pnext == PickedList -> PickedStruct) {
  149.             DrawList -> Pnext = DrawList -> Pnext -> Pnext;
  150.             break;
  151.             }
  152.             DrawList = DrawList -> Pnext;
  153.         }
  154.         }
  155.  
  156.         PickedList = PickedList -> Pnext;
  157.     }
  158.  
  159.     RedrawStructList(DrawStruct, GR_COPY_PUT, EE_ERASE_COLOR);
  160.     }
  161.     else {
  162.     if (DrawStruct == EEActiveWindow -> EEDrawList)
  163.         EEActiveWindow -> EEDrawList =
  164.                 EEActiveWindow -> EEDrawList -> Pnext;
  165.     else {
  166.         DrawList = EEActiveWindow -> EEDrawList;
  167.         while (DrawList -> Pnext) {
  168.         if (DrawList -> Pnext == DrawStruct) {
  169.             DrawList -> Pnext = DrawList -> Pnext -> Pnext;
  170.             break;
  171.         }
  172.         DrawList = DrawList -> Pnext;
  173.         }
  174.     }
  175.  
  176.     RedrawOneStruct(DrawStruct, GR_COPY_PUT, EE_ERASE_COLOR);
  177.     }
  178.  
  179.     if (UnDeleteStackPtr >= UNDELETE_STACK_SIZE - 1) {
  180.     /* Delete last deleted item, and shift stack. */
  181.     FreeStruct(UnDeleteStack[0]);
  182.     for (i = 0; i < UnDeleteStackPtr; i++)
  183.         UnDeleteStack[i] = UnDeleteStack[i + 1];
  184.     UnDeleteStack[UnDeleteStackPtr] = DrawStruct;
  185.     }
  186.     else
  187.     UnDeleteStack[UnDeleteStackPtr++] = DrawStruct;
  188.  
  189.     IntrPopCursorType();                /* Reenable the cursor. */
  190. }
  191.  
  192. /*****************************************************************************
  193. * Routine to cut an object from global drawing object list.             *
  194. *   This routine is the same as delete but the original list is NOT removed. *
  195. *****************************************************************************/
  196. void CutStruct(DrawGenericStruct *DrawStruct)
  197. {
  198.     int i;
  199.     DrawPickedStruct *PickedItem, *PickedList;
  200.     DrawGenericStruct *DrawStructCopy;
  201.  
  202.     /* Make a copy of the original picked item. */
  203.     DrawStructCopy = CopyStructLocal(DrawStruct);
  204.  
  205.     if (DrawStruct -> StructType == DRAW_PICK_ITEM_STRUCT_TYPE) {
  206.     /* Delete the picked wrapper if this is a picked list. */
  207.         for (PickedList = (DrawPickedStruct *) DrawStruct; PickedList != NULL; ) {
  208.         PickedItem = PickedList;
  209.         PickedList = PickedList -> Pnext;
  210.         MyFree((VoidPtr) PickedItem);
  211.     }
  212.     }
  213.  
  214.     /* And push it into the delete stack: */
  215.     if (UnDeleteStackPtr >= UNDELETE_STACK_SIZE - 1) {
  216.     /* Delete last deleted item, and shift stack. */
  217.     FreeStruct(UnDeleteStack[0]);
  218.     for (i = 0; i < UnDeleteStackPtr; i++)
  219.         UnDeleteStack[i] = UnDeleteStack[i + 1];
  220.     UnDeleteStack[UnDeleteStackPtr] = DrawStructCopy;
  221.     }
  222.     else
  223.     UnDeleteStack[UnDeleteStackPtr++] = DrawStructCopy;
  224. }
  225.  
  226. /*****************************************************************************
  227. * Routine to undelete a structure from the undelete stack.             *
  228. *****************************************************************************/
  229. BooleanType UnDeleteStruct(void)
  230. {
  231.     DrawGenericStruct *DrawStruct;
  232.     DrawPickedStruct  *PickedItem,
  233.     *PickedList = NULL;
  234.  
  235.     if (UnDeleteStackPtr == 0) {
  236.     Cursor.CursorType = INTR_CURSOR_ARROW;
  237.     IntrQueryContinue("No struct to undelete", EEPopUpFrameColor,
  238.                   EEPopUpBackColor, EEPopUpForeColor,
  239.                           EEPopUpXorColor, EEWindowsFrameWidth, &Cursor,
  240.                           INTR_WNDW_PLACE_CENTER);
  241.         return FALSE;
  242.     }
  243.     else {
  244.     DrawStruct = UnDeleteStack[--UnDeleteStackPtr];
  245.     if (DrawStruct -> StructType == DRAW_PICK_ITEM_STRUCT_TYPE) {
  246.         RedrawStructList(DrawStruct, GR_COPY_PUT, EE_DRAW_COLOR);
  247.  
  248.         for (PickedList = (DrawPickedStruct *) DrawStruct;
  249.          PickedList != NULL; ) {
  250.         PickedList -> PickedStruct -> Pnext =
  251.                     EEActiveWindow -> EEDrawList;
  252.         EEActiveWindow -> EEDrawList = PickedList -> PickedStruct;
  253.  
  254.         PickedItem = PickedList;
  255.         PickedList = PickedList -> Pnext;
  256.         MyFree((VoidPtr) PickedItem);
  257.         }
  258.     }
  259.     else {
  260.         RedrawOneStruct(DrawStruct, GR_COPY_PUT, EE_DRAW_COLOR);
  261.  
  262.         DrawStruct -> Pnext = EEActiveWindow -> EEDrawList;
  263.         EEActiveWindow -> EEDrawList = DrawStruct;
  264.     }
  265.         return TRUE;
  266.     }
  267. }
  268.  
  269. /*****************************************************************************
  270. * Routine to paste a structure from the undelete stack.                 *
  271. *   This routine is the same as undelete but original list is NOT removed.   *
  272. *****************************************************************************/
  273. BooleanType PasteStruct(void)
  274. {
  275.     DrawGenericStruct *DrawStruct;
  276.     DrawPickedStruct  *PickedItem,
  277.     *PickedList = NULL;
  278.  
  279.     if (UnDeleteStackPtr == 0) {
  280.     Cursor.CursorType = INTR_CURSOR_ARROW;
  281.     IntrQueryContinue("No struct to paste", EEPopUpFrameColor,
  282.                   EEPopUpBackColor, EEPopUpForeColor,
  283.                           EEPopUpXorColor, EEWindowsFrameWidth, &Cursor,
  284.                           INTR_WNDW_PLACE_CENTER);
  285.         return FALSE;
  286.     }
  287.     else {
  288.     DrawStruct = CopyStructLocal(UnDeleteStack[UnDeleteStackPtr - 1]);
  289.         if (DrawStruct -> StructType == DRAW_PICK_ITEM_STRUCT_TYPE)
  290.         MoveStructs((DrawPickedStruct *) DrawStruct, EESnapDistance,
  291.                                      EESnapDistance);
  292.         else
  293.         MoveOneStruct(DrawStruct, EESnapDistance, EESnapDistance);
  294.         PlaceStruct(DrawStruct);
  295.     if (DrawStruct -> StructType == DRAW_PICK_ITEM_STRUCT_TYPE) {
  296.         RedrawStructList(DrawStruct, GR_COPY_PUT, EE_DRAW_COLOR);
  297.  
  298.         for (PickedList = (DrawPickedStruct *) DrawStruct;
  299.          PickedList != NULL; ) {
  300.         PickedList -> PickedStruct -> Pnext =
  301.                     EEActiveWindow -> EEDrawList;
  302.         EEActiveWindow -> EEDrawList = PickedList -> PickedStruct;
  303.  
  304.         PickedItem = PickedList;
  305.         PickedList = PickedList -> Pnext;
  306.         MyFree((VoidPtr) PickedItem);
  307.         }
  308.     }
  309.     else {
  310.         RedrawOneStruct(DrawStruct, GR_COPY_PUT, EE_DRAW_COLOR);
  311.  
  312.         DrawStruct -> Pnext = EEActiveWindow -> EEDrawList;
  313.         EEActiveWindow -> EEDrawList = DrawStruct;
  314.     }
  315.         return TRUE;
  316.     }
  317. }
  318.  
  319. /*****************************************************************************
  320. * Routine to drop a structure from the undelete top of stack.             *
  321. *****************************************************************************/
  322. void DropStruct(void)
  323. {
  324.     if (UnDeleteStackPtr == 0) {
  325.     Cursor.CursorType = INTR_CURSOR_ARROW;
  326.     IntrQueryContinue("No struct to drop", EEPopUpFrameColor,
  327.                   EEPopUpBackColor, EEPopUpForeColor,
  328.                           EEPopUpXorColor, EEWindowsFrameWidth, &Cursor,
  329.                           INTR_WNDW_PLACE_CENTER);
  330.     }
  331.     else {
  332.     IntrDrawMessage("Dropping top of stack", EEPopUpForeColor,
  333.                                  EEPopUpBackColor);
  334.     FreeStruct(UnDeleteStack[--UnDeleteStackPtr]);
  335.         delay(200);
  336.     IntrEraseMessage();
  337.     }
  338. }
  339.  
  340. /*****************************************************************************
  341. * Routine to place a given object.                         *
  342. *****************************************************************************/
  343. static BooleanType PlaceStruct(DrawGenericStruct *DrawStruct)
  344. {
  345.     int x, y;
  346.     BooleanType
  347.         RetVal = FALSE;
  348.  
  349.     delay(250);            /* Make sure no events are waiting in the queue. */
  350.     IntrInputFlush();
  351.  
  352.     IntrSetIdleFunction(AutoPanActiveWindow);
  353.  
  354.     switch (DrawStruct -> StructType) {
  355.     case DRAW_POLYLINE_STRUCT_TYPE:
  356.         RetVal = PlacePolylineStruct((DrawPolylineStruct *) DrawStruct);
  357.             break;
  358.     case DRAW_CONNECTION_STRUCT_TYPE:
  359.         GRCurrentCursorX = GRMapX(((DrawConnectionStruct *) DrawStruct) -> PosX);
  360.         GRCurrentCursorY = GRMapY(((DrawConnectionStruct *) DrawStruct) -> PosY);
  361.         RetVal = PlaceConnectionStruct((DrawConnectionStruct *) DrawStruct);
  362.             break;
  363.     case DRAW_TEXT_STRUCT_TYPE:
  364.         GRCurrentCursorX = GRMapX(((DrawTextStruct *) DrawStruct) -> PosX);
  365.         GRCurrentCursorY = GRMapY(((DrawTextStruct *) DrawStruct) -> PosY);
  366.         RetVal = PlaceTextStruct((DrawTextStruct *) DrawStruct);
  367.             break;
  368.     case DRAW_LIB_ITEM_STRUCT_TYPE:
  369.         GRCurrentCursorX = GRMapX(((DrawLibItemStruct *) DrawStruct) -> PosX);
  370.         GRCurrentCursorY = GRMapY(((DrawLibItemStruct *) DrawStruct) -> PosY);
  371.         RetVal = PlaceLibItem((DrawLibItemStruct *) DrawStruct);
  372.             break;
  373.     case DRAW_PICK_ITEM_STRUCT_TYPE:
  374.         /* Place a box instead: */
  375.         IntrPushCursorType();
  376.             Cursor.CursorType = INTR_CURSOR_BOX;
  377.             GRCurrentCursorX = (GRMapX(PickedBoxMaxX) - GRMapX(PickedBoxMinX)) / 2;
  378.             GRCurrentCursorY = (GRMapY(PickedBoxMaxY) - GRMapY(PickedBoxMinY)) / 2;
  379.             Cursor.Width = (GRMapX(PickedBoxMaxX) - GRMapX(PickedBoxMinX)) / 2;
  380.             Cursor.Height = (GRMapY(PickedBoxMaxY) - GRMapY(PickedBoxMinY)) / 2;
  381.         IntrSetCursorType(&Cursor);
  382.  
  383.         GRCurrentCursorX = GRMapX((PickedBoxMinX + PickedBoxMaxX) / 2);
  384.         GRCurrentCursorY = GRMapY((PickedBoxMinY + PickedBoxMaxY) / 2);
  385.  
  386.         IntrDrawMessage("Place picked box", EEPopUpForeColor,
  387.                                 EEPopUpBackColor);
  388.         /* Move all object is the selected block out of drawing area: */
  389.         MoveStructs((DrawPickedStruct *) DrawStruct, -10000, -10000);
  390.  
  391.         if (IntrGetEventWaitSA(&x, &y) == INTR_EVNT_SELECT) {
  392.         x = EE_SNAP(GRInvMapX(x));
  393.         y = EE_SNAP(GRInvMapY(y));
  394.  
  395.         MoveStructs((DrawPickedStruct *) DrawStruct,
  396.                 x - (PickedBoxMaxX + PickedBoxMinX) / 2 + 10000,
  397.                 y - (PickedBoxMaxY + PickedBoxMinY) / 2 + 10000);
  398.  
  399.         IntrPopCursorType();
  400.         IntrEraseMessage();
  401.         RetVal = TRUE;
  402.         }
  403.         else {
  404.         MoveStructs((DrawPickedStruct *) DrawStruct, 10000, 10000);
  405.  
  406.         IntrPopCursorType();
  407.         IntrEraseMessage();
  408.         RetVal = FALSE;
  409.         }
  410.             break;
  411.     }
  412.  
  413.     IntrSetIdleFunction(NULL);
  414.  
  415.     return RetVal;
  416. }
  417.  
  418. /*****************************************************************************
  419. * Given list of structures as DrawPickStruct list move them all by Dx, Dy    *
  420. * (given in drawing space).                             *
  421. *****************************************************************************/
  422. static void MoveStructs(DrawPickedStruct *DrawStructs, int Dx, int Dy)
  423. {
  424.     /* Make sure we will stay on the snap boundaries. */
  425.     Dx = EE_SNAP(Dx);
  426.     Dy = EE_SNAP(Dy);
  427.  
  428.     while (DrawStructs) {
  429.     MoveOneStruct(DrawStructs -> PickedStruct, Dx, Dy);
  430.  
  431.     DrawStructs = DrawStructs -> Pnext;
  432.     }
  433. }
  434.  
  435. /*****************************************************************************
  436. * Given a structures move it by Dx, Dy.                         *
  437. *****************************************************************************/
  438. static void MoveOneStruct(DrawGenericStruct *DrawStruct, int Dx, int Dy)
  439. {
  440.     int i, *Points;
  441.     DrawPolylineStruct *DrawPoly;
  442.     DrawConnectionStruct *DrawConnect;
  443.     DrawTextStruct *DrawText;
  444.     DrawLibItemStruct *DrawLibItem;
  445.  
  446.     switch (DrawStruct -> StructType) {
  447.         case DRAW_POLYLINE_STRUCT_TYPE:
  448.         DrawPoly = (DrawPolylineStruct *) DrawStruct;
  449.         Points = DrawPoly -> Points;
  450.         for (i = 0; i < DrawPoly -> NumOfPoints; i++) {
  451.             Points[i * 2] += Dx;
  452.             Points[i * 2 + 1] += Dy;
  453.         }
  454.         break;
  455.     case DRAW_CONNECTION_STRUCT_TYPE:
  456.         DrawConnect = (DrawConnectionStruct *) DrawStruct;
  457.         DrawConnect -> PosX += Dx;
  458.         DrawConnect -> PosY += Dy;
  459.         break;
  460.     case DRAW_TEXT_STRUCT_TYPE:
  461.         DrawText = (DrawTextStruct *) DrawStruct;
  462.         DrawText -> PosX += Dx;
  463.         DrawText -> PosY += Dy;
  464.         break;
  465.     case DRAW_LIB_ITEM_STRUCT_TYPE:
  466.         DrawLibItem = (DrawLibItemStruct *) DrawStruct;
  467.         DrawLibItem -> PosX += Dx;
  468.         DrawLibItem -> PosY += Dy;
  469.         DrawLibItem -> PartNameX += Dx;
  470.         DrawLibItem -> PartNameY += Dy;
  471.         DrawLibItem -> ChipNameX += Dx;
  472.         DrawLibItem -> ChipNameY += Dy;
  473.         DrawLibItem -> BBoxMinX += Dx;
  474.         DrawLibItem -> BBoxMinY += Dy;
  475.         DrawLibItem -> BBoxMaxX += Dx;
  476.         DrawLibItem -> BBoxMaxY += Dy;
  477.         break;
  478.     }
  479. }
  480.  
  481. /*****************************************************************************
  482. * Routine to edit library items and modify its entries.                 *
  483. *****************************************************************************/
  484. BooleanType EditLibraryItem(void)
  485. {
  486.     int PopPosition;
  487.     char Line[LINE_LEN_SHORT], *OldStr;
  488.     TextOrientationType Orient;
  489.     BooleanType
  490.         RetVal = FALSE;
  491.     DrawLibItemStruct *LibItem;
  492.     DrawPickedStruct *PickedItem,
  493.     *PickedList = NULL;
  494.  
  495.     Cursor.CursorType = INTR_CURSOR_ARROW;
  496.     if (EditPopUpMenu == NULL) {
  497.         EditPopUpMenu =
  498.             IntrPopUpMenuCreate("Modify Lib Item", (char **) EditMenuStrs,
  499.                         0, EDIT_MENU_SIZE, EEPopUpFrameColor,
  500.                               EEPopUpBackColor, EEPopUpForeColor,
  501.                             EEPopUpXorColor, EEWindowsFrameWidth, &Cursor);
  502.     }
  503.  
  504.     LibItem = (DrawLibItemStruct *) PickStruct("Pick Library Item to Edit:",
  505.                                         TRUE);
  506.  
  507.     PopPosition = GRMapX(LibItem -> PosX) < GRScreenMaxX / 2 ?
  508.                             INTR_WNDW_PLACE_RIGHT :
  509.                             INTR_WNDW_PLACE_LEFT;
  510.  
  511.     if (LibItem != NULL &&
  512.     LibItem -> StructType == DRAW_LIB_ITEM_STRUCT_TYPE) {
  513.     DrawLibPart(LibItem, GR_COPY_PUT, EE_HIGHLIGHT_COLOR);
  514.     SetHighLightStruct((DrawGenericStruct *) LibItem);
  515.  
  516.     while (IntrPopUpMenu(EditPopUpMenu, PopPosition) &&
  517.            EditPopUpMenu -> SelectedIndex != 0) {
  518.         switch (EditPopUpMenu -> SelectedIndex) {
  519.             case 2: /* EditPartName */
  520.                 if (LibItem -> PartName != NULL) {
  521.                     strcpy(Line, LibItem -> PartName);
  522.                     OldStr = LibItem -> PartName;
  523.                     LibItem -> PartName = NULL;
  524.                 }
  525.                 else {
  526.                     Line[0] = 0;
  527.                     OldStr = NULL;
  528.                 }
  529.  
  530.                 IntrQueryLine("Enter new part name:", Line,
  531.                 LINE_LEN_SHORT - 1, EEPopUpFrameColor, EEPopUpBackColor,
  532.                 EEPopUpForeColor, EEWindowsFrameWidth, PopPosition);
  533.  
  534.                 if (OldStr != NULL) {
  535.                     GRSetWriteMode(GR_COPY_PUT);
  536.                     GRSetColor(EE_ERASE_COLOR);
  537.                     PutTextInfo(LibItem -> PartNameOrient,
  538.                             LibItem -> PartNameX,
  539.                             LibItem -> PartNameY,
  540.                     1,
  541.                     OldStr);
  542.                     MyFree((VoidPtr) OldStr);
  543.                 }
  544.  
  545.                 if (strlen(Line) > 0) {
  546.                     LibItem -> PartName = strdup(Line);
  547.                     if (OldStr == NULL) {
  548.                         LibItem -> PartNameX = LibItem -> PosX;
  549.                         LibItem -> PartNameY = LibItem -> PosY;
  550.                     }
  551.                     if (LibItem -> PartNameOrient == TEXT_ORIENT_NON)
  552.                         PlaceString(LibItem -> PartName,
  553.                     &LibItem -> PartNameOrient,
  554.                     1,
  555.                             &LibItem -> PartNameX,
  556.                     &LibItem -> PartNameY,
  557.                                     PopPosition);
  558.                     GRSetWriteMode(GR_COPY_PUT);
  559.                     GRSetColor(EE_HIGHLIGHT_COLOR);
  560.                     PutTextInfo(LibItem -> PartNameOrient,
  561.                     LibItem -> PartNameX,
  562.                     LibItem -> PartNameY,
  563.                     1,
  564.                     LibItem -> PartName);
  565.                 }
  566.                 else
  567.                 LibItem -> PartNameOrient = TEXT_ORIENT_NON;
  568.                 RetVal = TRUE;
  569.                 break;
  570.             case 3: /* Un/DrawChipName */
  571.             if (CanDrawChipName(LibItem -> ChipName)) {
  572.             if (LibItem -> ChipNameOrient != TEXT_ORIENT_NON) {
  573.                 GRSetWriteMode(GR_COPY_PUT);
  574.                 GRSetColor(EE_ERASE_COLOR);
  575.                 PutTextInfo(LibItem -> ChipNameOrient,
  576.                             LibItem -> ChipNameX,
  577.                             LibItem -> ChipNameY,
  578.                     1,
  579.                     LibItem -> ChipName);
  580.                 LibItem -> ChipNameOrient = TEXT_ORIENT_NON;
  581.             }
  582.                 else {
  583.                 LibItem -> ChipNameX = LibItem -> PosX;
  584.                         LibItem -> ChipNameY = LibItem -> PosY;
  585.                 if (PlaceString(LibItem -> ChipName,
  586.                             &LibItem -> ChipNameOrient,
  587.                         1,
  588.                         &LibItem -> ChipNameX,
  589.                         &LibItem -> ChipNameY,
  590.                                     PopPosition)) {
  591.                 GRSetWriteMode(GR_COPY_PUT);
  592.                 GRSetColor(EE_HIGHLIGHT_COLOR);
  593.                 PutTextInfo(LibItem -> ChipNameOrient,
  594.                         LibItem -> ChipNameX,
  595.                         LibItem -> ChipNameY,
  596.                         1,
  597.                         LibItem -> ChipName);
  598.                 }
  599.             }
  600.             RetVal = TRUE;
  601.                 }
  602.                 else
  603.                     IntrQueryContinue("Chip name is NOT drawable for this item",
  604.                               EEPopUpFrameColor, EEPopUpBackColor,
  605.                               EEPopUpForeColor, EEPopUpXorColor,
  606.                       EEWindowsFrameWidth, &Cursor,
  607.                            PopPosition);
  608.                 break;
  609.             case 4: /* ReposPartName */
  610.                 if (LibItem -> PartNameOrient == TEXT_ORIENT_NON) {
  611.                 Cursor.CursorType = INTR_CURSOR_ARROW;
  612.                     IntrQueryContinue("Picked item has no part name",
  613.                               EEPopUpFrameColor, EEPopUpBackColor,
  614.                               EEPopUpForeColor, EEPopUpXorColor,
  615.                       EEWindowsFrameWidth, &Cursor,
  616.                            PopPosition);
  617.                     break;
  618.                 }
  619.  
  620.                 GRSetWriteMode(GR_COPY_PUT);
  621.                 GRSetColor(EE_ERASE_COLOR);
  622.                 PutTextInfo(LibItem -> PartNameOrient,
  623.                 LibItem -> PartNameX,
  624.                 LibItem -> PartNameY,
  625.                 1,
  626.                 LibItem -> PartName);
  627.  
  628.             /* Since when auto panning it will be redrawn, we        */
  629.             /* disable this string drawing temporarily.             */
  630.             Orient = LibItem -> PartNameOrient;
  631.             LibItem -> PartNameOrient = TEXT_ORIENT_NON;
  632.                 RetVal = PlaceString(LibItem -> PartName,
  633.                      &Orient,
  634.                      1,
  635.                      &LibItem -> PartNameX,
  636.                      &LibItem -> PartNameY,
  637.                                  PopPosition);
  638.             LibItem -> PartNameOrient = Orient;
  639.  
  640.                 GRSetWriteMode(GR_COPY_PUT);
  641.             GRSetColor(EE_HIGHLIGHT_COLOR);
  642.             PutTextInfo(LibItem -> PartNameOrient,
  643.                 LibItem -> PartNameX,
  644.                 LibItem -> PartNameY,
  645.                 1,
  646.                 LibItem -> PartName);
  647.                 break;
  648.             case 5: /* ReposChipName */
  649.                 if (LibItem -> ChipNameOrient == TEXT_ORIENT_NON ||
  650.             !CanDrawChipName(LibItem -> ChipName)) {
  651.                     Cursor.CursorType = INTR_CURSOR_ARROW;
  652.                     IntrQueryContinue("Picked item has no chip name",
  653.                       EEPopUpFrameColor, EEPopUpBackColor,
  654.                                       EEPopUpForeColor, EEPopUpXorColor,
  655.                                       EEWindowsFrameWidth, &Cursor,
  656.                                       PopPosition);
  657.                     break;
  658.                 }
  659.  
  660.             GRSetWriteMode(GR_COPY_PUT);
  661.             GRSetColor(EE_ERASE_COLOR);
  662.             PutTextInfo(LibItem -> ChipNameOrient,
  663.                 LibItem -> ChipNameX,
  664.                 LibItem -> ChipNameY,
  665.                 1,
  666.                 LibItem -> ChipName);
  667.  
  668.             /* Since when auto panning it will be redrawn, we        */
  669.             /* disable this string drawing temporarily.             */
  670.             Orient = LibItem -> ChipNameOrient;
  671.             LibItem -> ChipNameOrient = TEXT_ORIENT_NON;
  672.             RetVal = PlaceString(LibItem -> ChipName,
  673.                      &Orient,
  674.                      1,
  675.                      &LibItem -> ChipNameX,
  676.                      &LibItem -> ChipNameY,
  677.                                  PopPosition);
  678.             LibItem -> ChipNameOrient = Orient;
  679.  
  680.                 GRSetWriteMode(GR_COPY_PUT);
  681.             GRSetColor(EE_HIGHLIGHT_COLOR);
  682.             PutTextInfo(LibItem -> ChipNameOrient,
  683.                     LibItem -> ChipNameX,
  684.                 LibItem -> ChipNameY,
  685.                 1,
  686.                 LibItem -> ChipName);
  687.                 break;
  688.             case 6: /* RePosLibItem */
  689.             RetVal = RePosLibItem(LibItem, PopPosition);
  690.                 break;
  691.         }
  692.     }
  693.  
  694.     SetHighLightStruct(NULL);
  695.     DrawLibPart(LibItem, GR_COPY_PUT, EE_DRAW_COLOR);
  696.     }
  697.  
  698.     if (LibItem -> StructType == DRAW_PICK_ITEM_STRUCT_TYPE) {
  699.     PickedList = (DrawPickedStruct *) LibItem;
  700.  
  701.     while (PickedList != NULL) {
  702.         /* More than one item were picked - free them all: */
  703.         PickedItem = PickedList;
  704.         PickedList = PickedList -> Pnext;
  705.         MyFree((VoidPtr) PickedItem);
  706.     }
  707.     }
  708.  
  709.     return RetVal;
  710. }
  711.  
  712. /*****************************************************************************
  713. * Routine to place a string. Returns string xy position and orientation      *
  714. * (vertically/horizontally). Returns TRUE if successful, FALSE otherwise.    *
  715. *****************************************************************************/
  716. BooleanType PlaceString(char *Str, TextOrientationType *Orient, int Scale,
  717.                           int *x, int *y, int PopPosition)
  718. {
  719.     int CrsrBoxWidth, CrsrBoxHeight,
  720.     LocalX = *x,
  721.         LocalY = *y,
  722.     Size = MAX(1, GRFontSize + (Scale - 1)) - DEFAULT_ZOOM_FACTOR;
  723.     TextOrientationType LocalOrient;
  724.     BooleanType RetVal;
  725.     char Line[LINE_LEN];
  726.  
  727.     Cursor.CursorType = INTR_CURSOR_ARROW;
  728.     GRPushTextSetting();
  729.     GRSetTextStyle(GRFontName, TEXT_ORIENT_HORIZ, Size);
  730.     if (IntrQueryYesNo("Horizonal?", EEPopUpFrameColor,
  731.                        EEPopUpBackColor, EEPopUpForeColor, EEPopUpXorColor,
  732.                        EEWindowsFrameWidth, &Cursor, PopPosition)) {
  733.     LocalOrient = TEXT_ORIENT_HORIZ;
  734.     CrsrBoxWidth = GRGetTextWidth(Str) / 2;
  735.     CrsrBoxHeight = GRGetTextHeight(Str) / 2;
  736.     }
  737.     else {
  738.     LocalOrient = TEXT_ORIENT_VERT;
  739.     CrsrBoxWidth = GRGetTextHeight(Str) / 2;
  740.     CrsrBoxHeight = GRGetTextWidth(Str) / 2;
  741.     }
  742.     GRPopTextSetting();
  743.  
  744.     IntrPushCursorType();
  745.     Cursor.CursorType = INTR_CURSOR_BOX;
  746.     Cursor.Width = CrsrBoxWidth;
  747.     Cursor.Height = CrsrBoxHeight;
  748.     IntrSetCursorType(&Cursor);
  749.  
  750.     sprintf(Line, "Place \"%s\":", Str);
  751.     IntrDrawMessage(Line, EEPopUpForeColor, EEPopUpBackColor);
  752.  
  753.     if (LocalX >= 0 && LocalY >= 0) {
  754.     GRCurrentCursorX = GRMapX(LocalX);
  755.     GRCurrentCursorY = GRMapY(LocalY);
  756.     }
  757.     PutCursorInActiveWindow();
  758.  
  759.     IntrSetIdleFunction(AutoPanActiveWindow);
  760.  
  761.     if ((RetVal = IntrGetEventWaitSA(&LocalX, &LocalY) == INTR_EVNT_SELECT)
  762.                                 != FALSE) {
  763.     *x = EE_SNAP(GRInvMapX(LocalX));
  764.     *y = EE_SNAP(GRInvMapY(LocalY));
  765.         *Orient = LocalOrient;
  766.     }
  767.  
  768.     IntrSetIdleFunction(NULL);
  769.  
  770.     Cursor.CursorType = INTR_CURSOR_ARROW;
  771.  
  772.     IntrPopCursorType();
  773.     IntrEraseMessage();
  774.  
  775.     return RetVal;
  776. }
  777.  
  778. /*****************************************************************************
  779. * Routine to create a new copy of given struct.                     *
  780. *****************************************************************************/
  781. static DrawGenericStruct *CopyStructLocal(DrawGenericStruct *DrawStruct)
  782. {
  783.     DrawGenericStruct
  784.         *NewDrawStruct = NULL;
  785.     DrawPickedStruct *NewPickedItem,
  786.     *PickedList = NULL,
  787.     *LastPickedItem = NULL;
  788.  
  789.     switch (DrawStruct -> StructType) {
  790.     case DRAW_POLYLINE_STRUCT_TYPE:
  791.         NewDrawStruct = (DrawGenericStruct *)
  792.                      MyMalloc(sizeof(DrawPolylineStruct));
  793.         GEN_COPY(NewDrawStruct, DrawStruct, sizeof(DrawPolylineStruct));
  794.         ((DrawPolylineStruct *) NewDrawStruct) -> Points = (int *)
  795.         MyMalloc(sizeof(int) * 2 *
  796.              ((DrawPolylineStruct *) DrawStruct) -> NumOfPoints);
  797.         GEN_COPY(((DrawPolylineStruct *) NewDrawStruct) -> Points,
  798.              ((DrawPolylineStruct *) DrawStruct) -> Points,
  799.              sizeof(int) * 2 *
  800.              ((DrawPolylineStruct *) DrawStruct) -> NumOfPoints);
  801.         break;
  802.     case DRAW_CONNECTION_STRUCT_TYPE:
  803.         NewDrawStruct = (DrawGenericStruct *)
  804.                        MyMalloc(sizeof(DrawConnectionStruct));
  805.         GEN_COPY(NewDrawStruct, DrawStruct, sizeof(DrawConnectionStruct));
  806.         break;
  807.     case DRAW_TEXT_STRUCT_TYPE:
  808.         NewDrawStruct = (DrawGenericStruct *) MyMalloc(sizeof(DrawTextStruct));
  809.         GEN_COPY(NewDrawStruct, DrawStruct, sizeof(DrawTextStruct));
  810.         ((DrawTextStruct *) NewDrawStruct) -> Text =
  811.         strdup(((DrawTextStruct *) DrawStruct) -> Text);
  812.         break;
  813.     case DRAW_LIB_ITEM_STRUCT_TYPE:
  814.         NewDrawStruct = (DrawGenericStruct *)
  815.                       MyMalloc(sizeof(DrawLibItemStruct));
  816.         GEN_COPY(NewDrawStruct, DrawStruct, sizeof(DrawLibItemStruct));
  817.         if (((DrawLibItemStruct *) DrawStruct) -> ChipName)
  818.         (((DrawLibItemStruct *) NewDrawStruct) -> ChipName) =
  819.             strdup(((DrawLibItemStruct *) DrawStruct) -> ChipName);
  820.         if (((DrawLibItemStruct *) DrawStruct) -> PartName)
  821.         (((DrawLibItemStruct *) NewDrawStruct) -> PartName) =
  822.             strdup(((DrawLibItemStruct *) DrawStruct) -> PartName);
  823.         break;
  824.     case DRAW_PICK_ITEM_STRUCT_TYPE:
  825.         PickedList = (DrawPickedStruct *) DrawStruct;
  826.         while (PickedList) {
  827.         NewPickedItem = (DrawPickedStruct *)
  828.                        MyMalloc(sizeof(DrawPickedStruct));
  829.         NewPickedItem -> StructType = DRAW_PICK_ITEM_STRUCT_TYPE;
  830.         NewPickedItem -> Pnext = NULL;
  831.         if (NewDrawStruct == NULL)
  832.             NewDrawStruct = (DrawGenericStruct *) NewPickedItem;
  833.         if (LastPickedItem != NULL)
  834.             LastPickedItem -> Pnext = NewPickedItem;
  835.         LastPickedItem = NewPickedItem;
  836.  
  837.         NewPickedItem -> PickedStruct =
  838.             CopyStructLocal(PickedList -> PickedStruct);
  839.  
  840.         PickedList = PickedList -> Pnext;
  841.         }
  842.         break;
  843.     }
  844.  
  845.     return NewDrawStruct;
  846. }
  847.  
  848. /*****************************************************************************
  849. * Routine to delete a given struct.                         *
  850. *****************************************************************************/
  851. void FreeStruct(DrawGenericStruct *DrawStruct)
  852. {
  853.     DrawPickedStruct *PickedList, *PickedItem;
  854.  
  855.     switch (DrawStruct -> StructType) {
  856.     case DRAW_POLYLINE_STRUCT_TYPE:
  857.         MyFree((VoidPtr) ((DrawPolylineStruct *) DrawStruct) -> Points);
  858.         MyFree((VoidPtr) DrawStruct);
  859.         break;
  860.     case DRAW_CONNECTION_STRUCT_TYPE:
  861.         MyFree((VoidPtr) DrawStruct);
  862.         break;
  863.     case DRAW_TEXT_STRUCT_TYPE:
  864.         MyFree((VoidPtr) ((DrawTextStruct *) DrawStruct) -> Text);
  865.         MyFree((VoidPtr) DrawStruct);
  866.         break;
  867.     case DRAW_LIB_ITEM_STRUCT_TYPE:
  868.         if (((DrawLibItemStruct *) DrawStruct) -> ChipName)
  869.         MyFree((VoidPtr) ((DrawLibItemStruct *) DrawStruct) -> ChipName);
  870.         if (((DrawLibItemStruct *) DrawStruct) -> PartName)
  871.         MyFree((VoidPtr) ((DrawLibItemStruct *) DrawStruct) -> PartName);
  872.         MyFree((VoidPtr) DrawStruct);
  873.         break;
  874.     case DRAW_PICK_ITEM_STRUCT_TYPE:
  875.         PickedList = (DrawPickedStruct *) DrawStruct;
  876.         while (PickedList) {
  877.         PickedItem = PickedList;
  878.         PickedList = PickedList -> Pnext;
  879.         FreeStruct(PickedItem -> PickedStruct);
  880.         MyFree((VoidPtr) PickedItem);
  881.         }
  882.         break;
  883.     }
  884. }
  885.  
  886. /*****************************************************************************
  887. * Routine to pick a object from global drawing object list.             *
  888. *****************************************************************************/
  889. DrawGenericStruct *PickStruct(char *Header, BooleanType OnlyLibItem)
  890. {
  891.     BooleanType Snapped, Draw = TRUE;
  892.     int i, x, y, OrigX, OrigY, OrigXScrn, OrigYScrn, Event;
  893.     DrawPickedStruct *DontPickList = NULL, *PickedList = NULL, *PickedItem;
  894.     DrawGenericStruct *DrawStruct;
  895.  
  896.     IntrPushCursorType();
  897.     Cursor.CursorType = INTR_CURSOR_CROSS;
  898.     IntrSetCursorType(&Cursor);
  899.  
  900.     IntrDrawMessage(Header, EEPopUpForeColor, EEPopUpBackColor);
  901.  
  902.     if (IntrGetEventWaitSA(&OrigXScrn, &OrigYScrn) == INTR_EVNT_ABORT) {
  903.     IntrPopCursorType();
  904.     IntrEraseMessage();
  905.  
  906.     return NULL;
  907.     }
  908.     OrigX = OrigXScrn;
  909.     OrigY = OrigYScrn;
  910.     OrigX = EE_SNAP(GRInvMapX(OrigX));
  911.     OrigY = EE_SNAP(GRInvMapY(OrigY));
  912.  
  913.     do {
  914.     x = OrigX;
  915.     y = OrigY;
  916.     if ((Snapped = SnapPoint2(&x, &y, OnlyLibItem,
  917.             EEActiveWindow -> EEDrawList, DontPickList)) == FALSE) break;
  918.  
  919.     /* Lets see if the user likes this picked structure: */
  920.     do {
  921.         Draw = !Draw;
  922.         RedrawOneStruct(LastSnappedStruct, GR_COPY_PUT,
  923.                 Draw ? EE_DRAW_COLOR : EE_ERASE_COLOR);
  924.         delay(300);
  925.         Event = IntrGetTextEventNoWait();
  926.     }
  927.     while (Event != INTR_EVNT_ABORT && Event != INTR_EVNT_SELECT);
  928.     if (!Draw) RedrawOneStruct(LastSnappedStruct, GR_COPY_PUT, EE_DRAW_COLOR);
  929.  
  930.     if (Event == INTR_EVNT_ABORT) {
  931.         /* Put this structure in the dont pick list, and try again: */
  932.         PickedItem = (DrawPickedStruct *) MyMalloc(sizeof(DrawPickedStruct));
  933.         PickedItem -> StructType = DRAW_PICK_ITEM_STRUCT_TYPE;
  934.         PickedItem -> PickedStruct = LastSnappedStruct;
  935.         PickedItem -> Pnext = DontPickList;
  936.         DontPickList = PickedItem;
  937.     }
  938.     } while (Event != INTR_EVNT_SELECT);
  939.  
  940.     if (DontPickList == NULL && !Snapped) {
  941.     /*   Wait for the second points to define a box everything inside is */
  942.     /* to considered picked.                         */
  943.         Cursor.CursorType = INTR_CURSOR_BOX_LAST;
  944.         Cursor.LastX = OrigXScrn;
  945.         Cursor.LastY = OrigYScrn;
  946.     IntrSetCursorType(&Cursor);
  947.     if (IntrGetEventWaitSA(&x, &y) == INTR_EVNT_ABORT) {
  948.         IntrPopCursorType();
  949.         IntrEraseMessage();
  950.  
  951.         return NULL;
  952.     }
  953.     x = EE_SNAP(GRInvMapX(x));
  954.     y = EE_SNAP(GRInvMapY(y));
  955.     if (x < OrigX) {
  956.         i = x;
  957.         x = OrigX;
  958.         OrigX = i;
  959.     }
  960.     if (y < OrigY) {
  961.         i = y;
  962.         y = OrigY;
  963.         OrigY = i;
  964.     }
  965.  
  966.     for (DrawStruct = EEActiveWindow -> EEDrawList;
  967.          DrawStruct != NULL;
  968.          DrawStruct = DrawStruct -> Pnext) {
  969.         if (DrawStructInBox(OrigX, OrigY, x, y, DrawStruct)) {
  970.         /* Put this structure in the picked list: */
  971.         PickedItem = (DrawPickedStruct *)
  972.             MyMalloc(sizeof(DrawPickedStruct));
  973.         PickedItem -> StructType = DRAW_PICK_ITEM_STRUCT_TYPE;
  974.         PickedItem -> PickedStruct = DrawStruct;
  975.         PickedItem -> Pnext = PickedList;
  976.         PickedList = PickedItem;
  977.         }
  978.     }
  979.  
  980.     IntrEraseMessage();
  981.     IntrPopCursorType();
  982.  
  983.     if (PickedList && PickedList -> Pnext == NULL) {
  984.         /* Only one item was picked - convert to scalar form (no list): */
  985.         PickedItem = PickedList;
  986.         PickedList = (DrawPickedStruct *) PickedList -> PickedStruct;
  987.         MyFree((VoidPtr) PickedItem);
  988.     }
  989.  
  990.     if (PickedList != NULL) {
  991.         PickedBoxMinX = OrigX;
  992.         PickedBoxMinY = OrigY;
  993.         PickedBoxMaxX = x;
  994.         PickedBoxMaxY = y;
  995.     }
  996.  
  997.     return (DrawGenericStruct *) PickedList;
  998.     }
  999.     else {
  1000.     while (DontPickList) {
  1001.         PickedItem = DontPickList;
  1002.         DontPickList = DontPickList -> Pnext;
  1003.         MyFree((VoidPtr) PickedItem);
  1004.     }
  1005.  
  1006.     IntrEraseMessage();
  1007.     IntrPopCursorType();
  1008.  
  1009.     return Snapped ? LastSnappedStruct : NULL;
  1010.     }
  1011. }
  1012.  
  1013. /*****************************************************************************
  1014. * Interface routine to snap a point relative to all structures defined.      *
  1015. *****************************************************************************/
  1016. BooleanType SnapPoint(int *OrigX, int *OrigY, BooleanType OnlyLibItem)
  1017. {
  1018.     return SnapPoint2(OrigX, OrigY, OnlyLibItem,
  1019.                          EEActiveWindow -> EEDrawList, NULL);
  1020. }
  1021.  
  1022. /*****************************************************************************
  1023. * Routine to search all objects for the closest point to a given point, in   *
  1024. * drawing space, and snap it to that points if closer than SnapDistance.     *
  1025. * Note we use L1 norm as distance measure, as it is the fastest.         *
  1026. * This routine updates LastSnappedStruct to the last object used in to snap  *
  1027. * a point. This variable is global to this module only (see above).         *
  1028. * If DontSnapList is not NULL, structes in this list are skipped.         *
  1029. * The routine returns TRUE if point was snapped.                 *
  1030. * The points is also snapped to the EE_SNAP.                     *
  1031. *****************************************************************************/
  1032. BooleanType SnapPoint2(int *OrigX, int *OrigY, BooleanType OnlyLibItem,
  1033.            DrawGenericStruct *DrawList, DrawPickedStruct *DontSnapList)
  1034. {
  1035.     int i, *Points, x = *OrigX, y = *OrigY, x1, y1, x2, y2, NumOfPoints2,
  1036.     ClosestX = 16383, ClosestY = 16383;
  1037.     unsigned int Dist, CrntDist = 16383;
  1038.     DrawPickedStruct *DontSnap;
  1039.  
  1040.     for (; DrawList != NULL; DrawList = DrawList -> Pnext) {
  1041.     /* Make sure this structure is NOT in the dont snap list: */
  1042.     for (DontSnap = DontSnapList;
  1043.          DontSnap != NULL;
  1044.          DontSnap = DontSnap -> Pnext)
  1045.         if (DontSnap -> PickedStruct == DrawList) break;
  1046.     if (DontSnap -> PickedStruct == DrawList) continue;
  1047.  
  1048.     switch (DrawList -> StructType) {
  1049.         case DRAW_POLYLINE_STRUCT_TYPE:
  1050.         if (OnlyLibItem) break;
  1051.         Points = ((DrawPolylineStruct *) DrawList) -> Points;
  1052.         NumOfPoints2 =
  1053.             ((DrawPolylineStruct *) DrawList) -> NumOfPoints * 2;
  1054.         for (i = 0; i < NumOfPoints2; i += 2) {
  1055.             Dist = ((unsigned int) ABS(Points[i] - x)) +
  1056.                ((unsigned int) ABS(Points[i+1] - y));
  1057.             if (CrntDist > Dist) {
  1058.             CrntDist = Dist;
  1059.             LastSnappedStruct = DrawList;
  1060.             ClosestX = Points[i];
  1061.             ClosestY = Points[i+1];
  1062.             }
  1063.             if (i < NumOfPoints2 - 2) {
  1064.             /* Maybe we should snap the point to the middle of   */
  1065.             /* the line instead.                     */
  1066.             if ((Points[i] > x && Points[i+2] < x) ||
  1067.                 (Points[i] < x && Points[i+2] > x)) {
  1068.                 /* X value in middle of current line segment: */
  1069.                 Dist = (unsigned int) ABS(Points[i+1] - y);
  1070.                 if (CrntDist > Dist) {
  1071.                 CrntDist = Dist;
  1072.                 LastSnappedStruct = DrawList;
  1073.                 ClosestX = x;
  1074.                 ClosestY = Points[i+1];
  1075.                 }
  1076.             }
  1077.             if ((Points[i+1] > y) && (Points[i+3] < y) ||
  1078.                 (Points[i+1] < y) && (Points[i+3] > y)) {
  1079.                 /* Y value in middle of current line segment: */
  1080.                 Dist = (unsigned int) ABS(Points[i] - x);
  1081.                 if (CrntDist > Dist) {
  1082.                 CrntDist = Dist;
  1083.                 LastSnappedStruct = DrawList;
  1084.                 ClosestX = Points[i];
  1085.                 ClosestY = y;
  1086.                 }
  1087.             }
  1088.             }
  1089.         }
  1090.         break;
  1091.         case DRAW_CONNECTION_STRUCT_TYPE:
  1092.         if (OnlyLibItem) break;
  1093.         Dist = ((unsigned int)
  1094.             ABS(((DrawConnectionStruct *) DrawList) -> PosX - x)) +
  1095.                ((unsigned int)
  1096.             ABS(((DrawConnectionStruct *) DrawList) -> PosY - y));
  1097.         if (CrntDist > Dist) {
  1098.             CrntDist = Dist;
  1099.             LastSnappedStruct = DrawList;
  1100.             ClosestX = ((DrawConnectionStruct *) DrawList) -> PosX;
  1101.             ClosestY = ((DrawConnectionStruct *) DrawList) -> PosY;
  1102.         }
  1103.         break;
  1104.         case DRAW_TEXT_STRUCT_TYPE:
  1105.         if (OnlyLibItem) break;
  1106.         if (((DrawTextStruct *) DrawList) -> Orient ==
  1107.                             TEXT_ORIENT_HORIZ) {
  1108.             x1 = GRMapX(((DrawTextStruct *) DrawList) -> PosX) -
  1109.             GRGetTextWidth(((DrawTextStruct *) DrawList) -> Text) / 2;
  1110.             x2 = GRMapX(((DrawTextStruct *) DrawList) -> PosX) +
  1111.             GRGetTextWidth(((DrawTextStruct *) DrawList) -> Text) / 2;
  1112.             y1 = GRMapY(((DrawTextStruct *) DrawList) -> PosY) -
  1113.             GRGetTextHeight(((DrawTextStruct *) DrawList) -> Text) / 2;
  1114.             y2 = GRMapY(((DrawTextStruct *) DrawList) -> PosY) +
  1115.             GRGetTextHeight(((DrawTextStruct *) DrawList) -> Text) / 2;
  1116.         }
  1117.         else {
  1118.             x1 = GRMapX(((DrawTextStruct *) DrawList) -> PosX) -
  1119.             GRGetTextHeight(((DrawTextStruct *) DrawList) -> Text) / 2;
  1120.             x2 = GRMapX(((DrawTextStruct *) DrawList) -> PosX) +
  1121.             GRGetTextHeight(((DrawTextStruct *) DrawList) -> Text) / 2;
  1122.             y1 = GRMapY(((DrawTextStruct *) DrawList) -> PosY) -
  1123.             GRGetTextWidth(((DrawTextStruct *) DrawList) -> Text) / 2;
  1124.             y2 = GRMapY(((DrawTextStruct *) DrawList) -> PosY) +
  1125.             GRGetTextWidth(((DrawTextStruct *) DrawList) -> Text) / 2;
  1126.         }
  1127.         x1 = GRInvMapX(x1);
  1128.         x2 = GRInvMapX(x2);
  1129.         y1 = GRInvMapY(y1);
  1130.         y2 = GRInvMapY(y2);
  1131.         if (x >= x1 && x <= x2) {
  1132.             if (y >= y1 && y <= y2)
  1133.             Dist = 0;
  1134.             else
  1135.             Dist = MIN(ABS(y - y1), ABS(y - y2));
  1136.         }
  1137.         else if (y >= y1 && y <= y2) {
  1138.             if (x >= x1 && x <= x2)
  1139.             Dist = 0;
  1140.             else
  1141.             Dist = MIN(ABS(x - x1), ABS(x - x2));
  1142.         }
  1143.         else
  1144.             Dist = 16363;
  1145.         if (CrntDist > Dist) {
  1146.             CrntDist = Dist;
  1147.             LastSnappedStruct = DrawList;
  1148.             ClosestX = x + Dist;
  1149.             ClosestY = y;
  1150.         }
  1151.         break;
  1152.         case DRAW_LIB_ITEM_STRUCT_TYPE:
  1153.         /* Check this library item iff our point is in its bbox: */
  1154.         if (((DrawLibItemStruct *) DrawList) -> BBoxMinX -
  1155.                             EESnapDistance <= x &&
  1156.             ((DrawLibItemStruct *) DrawList) -> BBoxMaxX +
  1157.                             EESnapDistance >= x &&
  1158.             ((DrawLibItemStruct *) DrawList) -> BBoxMinY -
  1159.                             EESnapDistance <= y &&
  1160.             ((DrawLibItemStruct *) DrawList) -> BBoxMaxY +
  1161.                             EESnapDistance >= y)
  1162.             SnapLibItemPoint(x, y, &ClosestX, &ClosestY,
  1163.                      (DrawLibItemStruct *) DrawList);
  1164.         Dist = ((unsigned int) ABS(ClosestX - x)) +
  1165.                ((unsigned int) ABS(ClosestY - y));
  1166.         if (CrntDist > Dist) {
  1167.             CrntDist = Dist;
  1168.             LastSnappedStruct = DrawList;
  1169.         }
  1170.         break;
  1171.     }
  1172.     }
  1173.  
  1174.     /* Lets find the euclidian L2 distance: */
  1175.     if (SQR(((double) ClosestX) - x) + SQR(((double) ClosestY) - y) <
  1176.     SQR(EESnapDistance)) {
  1177.     /* We snap the point, make sure it is on EE_SNAP boundary: */
  1178.     ClosestX = EE_SNAP(ClosestX);
  1179.     ClosestY = EE_SNAP(ClosestY);
  1180.     *OrigX = ClosestX;
  1181.     *OrigY = ClosestY;
  1182.  
  1183.     return TRUE;
  1184.     }
  1185.     else
  1186.     return FALSE;
  1187. }
  1188.  
  1189. /*****************************************************************************
  1190. * Routine to test if an object has non empty intersection with the box       *
  1191. * defined by x1/y1 and x2/y2 (x1 < x2, y1 < y2), and return TRUE if so. This *
  1192. * routine is used to pick all points in a given box.                 *
  1193. *****************************************************************************/
  1194. BooleanType DrawStructInBox(int x1, int y1, int x2, int y2,
  1195.                         DrawGenericStruct *DrawStruct)
  1196. {
  1197.     int i, *Points, xt1, yt1, xt2, yt2, NumOfPoints2;
  1198.  
  1199.     switch (DrawStruct -> StructType) {
  1200.         case DRAW_POLYLINE_STRUCT_TYPE:
  1201.         Points = ((DrawPolylineStruct *) DrawStruct) -> Points;
  1202.         NumOfPoints2 =
  1203.             ((DrawPolylineStruct *) DrawStruct) -> NumOfPoints * 2;
  1204.         for (i = 0; i < NumOfPoints2; i += 2) {
  1205.             if (Points[i] >= x1 && Points[i] <= x2 &&
  1206.             Points[i+1] >= y1 && Points[i+1] <=y2) return TRUE;
  1207.         }
  1208.         break;
  1209.         case DRAW_CONNECTION_STRUCT_TYPE:
  1210.         if (((DrawConnectionStruct *) DrawStruct) -> PosX >= x1 &&
  1211.             ((DrawConnectionStruct *) DrawStruct) -> PosX <= x2 &&
  1212.             ((DrawConnectionStruct *) DrawStruct) -> PosY >= y1 &&
  1213.             ((DrawConnectionStruct *) DrawStruct) -> PosY <= y2)
  1214.             return TRUE;
  1215.         break;
  1216.         case DRAW_TEXT_STRUCT_TYPE:
  1217.         if (((DrawTextStruct *) DrawStruct) -> Orient ==
  1218.                             TEXT_ORIENT_HORIZ) {
  1219.             xt1 = GRMapX(((DrawTextStruct *) DrawStruct) -> PosX) -
  1220.             GRGetTextWidth(((DrawTextStruct *) DrawStruct) ->
  1221.                                   Text) / 2;
  1222.             xt2 = GRMapX(((DrawTextStruct *) DrawStruct) -> PosX) +
  1223.             GRGetTextWidth(((DrawTextStruct *) DrawStruct) ->
  1224.                                   Text) / 2;
  1225.             yt1 = GRMapY(((DrawTextStruct *) DrawStruct) -> PosY) -
  1226.             GRGetTextHeight(((DrawTextStruct *) DrawStruct) ->
  1227.                                   Text) / 2;
  1228.             yt2 = GRMapY(((DrawTextStruct *) DrawStruct) -> PosY) +
  1229.             GRGetTextHeight(((DrawTextStruct *) DrawStruct) ->
  1230.                                   Text) / 2;
  1231.         }
  1232.         else {
  1233.             xt1 = GRMapX(((DrawTextStruct *) DrawStruct) -> PosX) -
  1234.             GRGetTextHeight(((DrawTextStruct *) DrawStruct) ->
  1235.                                   Text) / 2;
  1236.             xt2 = GRMapX(((DrawTextStruct *) DrawStruct) -> PosX) +
  1237.             GRGetTextHeight(((DrawTextStruct *) DrawStruct) ->
  1238.                                   Text) / 2;
  1239.             yt1 = GRMapY(((DrawTextStruct *) DrawStruct) -> PosY) -
  1240.             GRGetTextWidth(((DrawTextStruct *) DrawStruct) ->
  1241.                                   Text) / 2;
  1242.             yt2 = GRMapY(((DrawTextStruct *) DrawStruct) -> PosY) +
  1243.             GRGetTextWidth(((DrawTextStruct *) DrawStruct) ->
  1244.                                   Text) / 2;
  1245.         }
  1246.         xt1 = GRInvMapX(xt1);
  1247.         xt2 = GRInvMapX(xt2);
  1248.         yt1 = GRInvMapY(yt1);
  1249.         yt2 = GRInvMapY(yt2);
  1250.         if ((xt1 >= x1 && xt1 <= x2 && yt1 >= y1 && yt1 <= y2) ||
  1251.             (xt2 >= x1 && xt2 <= x2 && yt2 >= y1 && yt2 <= y2))
  1252.             return TRUE;
  1253.         break;
  1254.         case DRAW_LIB_ITEM_STRUCT_TYPE:
  1255.         /* Check this library item iff our point is in its bbox: */
  1256.         xt1 = ((DrawLibItemStruct *) DrawStruct) -> BBoxMinX;
  1257.         xt2 = ((DrawLibItemStruct *) DrawStruct) -> BBoxMaxX;
  1258.         yt1 = ((DrawLibItemStruct *) DrawStruct) -> BBoxMinY;
  1259.         yt2 = ((DrawLibItemStruct *) DrawStruct) -> BBoxMaxY;
  1260.  
  1261.         /* See if we can trivially reject using the bounding boxes,  */
  1262.         /* otherwise use the full power of the library to decide.    */
  1263.         if (!(xt1 > x2 || yt1 > y2 || xt2 < x1 || yt2 < y1) &&
  1264.             LibItemInBox(x1, y1, x2, y2,
  1265.             (DrawLibItemStruct *) DrawStruct))
  1266.             return TRUE;
  1267.         break;
  1268.     }
  1269.  
  1270.     return FALSE;
  1271. }
  1272.