home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d5xx / d502 / cells.lha / CELLS / CELLSSource.lzh / cDoParts.c < prev    next >
C/C++ Source or Header  |  1991-04-20  |  11KB  |  403 lines

  1. /*
  2.  *  CELLS       An Implementation of the WireWorld cellular automata
  3.  *              as described in Scientific American, Jan 1990.
  4.  *
  5.  *              Copyright 1990 by Davide P. Cervone.
  6.  *  You may use this code, provided this copyright notice is kept intact.
  7.  *  See the CELLS.HELP file for complete information on distribution conditions.
  8.  */
  9.  
  10. /*
  11.  *  File:  cDoParts.c               Handle the parts requesters.
  12.  */
  13.  
  14.  
  15. #include "cGadget.h"
  16. #include "cRequest.h"
  17. #include "cReqNP.h"
  18. #include "cReqLP.h"
  19. #include "cParts.h"
  20.  
  21. extern LIBRARY *RemoveListItem();
  22.  
  23. extern char NPNameBuf[];        /* the new part name */
  24. extern char LPNameBuf[];        /* the part name to load */
  25. extern int Viewing;             /* TRUE if parts requester is in VIEW mode */
  26.  
  27. #define LPGADGET    LPRequest.er_Request.ReqGadget
  28.  
  29.  
  30. /*
  31.  *  NPGadgetUP()
  32.  *
  33.  *  Handle the New Part requester's gadget up events:
  34.  *
  35.  *  OK and NAME:
  36.  *    remove the requester and put the PART button back to normal.
  37.  *    If the part was able to be created, cancel the selection.
  38.  *
  39.  *  CANCEL:
  40.  *   remove the requester and put the PARTS button back to normal.
  41.  */
  42.  
  43. static void NPGadgetUp(theGadget,theMessage)
  44. struct Gadget *theGadget;
  45. struct IntuiMessage *theMessage;
  46. {
  47.    switch(theGadget->GadgetID)
  48.    {
  49.       case NP_OK:
  50.       case NP_NAME:
  51.          RemoveRequest(&NPRequest);
  52.          InvertGadget(&cGadget[ID_PART]);
  53.          if (MakePart(NPNameBuf)) CancelSelect();
  54.          break;
  55.  
  56.       case NP_CANCEL:
  57.          InvertGadget(&cGadget[ID_PART]);
  58.          RemoveRequest(&NPRequest);
  59.          break;
  60.    }
  61. }
  62.  
  63.  
  64. /*
  65.  *  AddPart()
  66.  *
  67.  *  If the New Part requester is not already showing,
  68.  *    clear the part name buffer
  69.  *    Invert the PART gadget and put up the requester.
  70.  *    If the requester could not be openned, put the button back to normal.
  71.  */
  72.  
  73. void AddPart()
  74. {
  75.    if (ActiveRequest != &NPRequest)
  76.    {
  77.       NPNameBuf[0] = 0;
  78.       InvertGadget(&cGadget[ID_PART]);
  79.       AddRequest(&NPRequest,NULL,NPGadgetUp,NULL);
  80.       if (ActiveRequest == NULL) InvertGadget(&cGadget[ID_PART]);
  81.    }
  82. }
  83.  
  84.  
  85. /*
  86.  *  FindPart()
  87.  *
  88.  *  If a library and a part name were specified,
  89.  *    starting at the first part in the list,
  90.  *    while there are still more parts and we have not found the right one,
  91.  *      if the name lengths are equal, check to see if they are equal
  92.  *      If not, go on to the next part
  93.  *  If the part was not found, and we are displaying errors, do so.
  94.  */
  95.  
  96. static PART *FindPart(Name,theLibrary,ShowError)
  97. char *Name;
  98. LIBRARY *theLibrary;
  99. int ShowError;
  100. {
  101.    PART *thePart = NULL;
  102.    int NotFound = TRUE;
  103.    UWORD theSize;
  104.    
  105.    if (theLibrary && Name && Name[0])
  106.    {
  107.       thePart = theLibrary->FirstPart;
  108.       theSize = strlen(Name);
  109.       while (thePart && NotFound)
  110.       {
  111.          if (theSize == thePart->NameLen) NotFound = strcmp(thePart->Name,Name);
  112.          if (NotFound) thePart = thePart->Next;
  113.       }
  114.    }
  115.    if (thePart == NULL && ShowError)
  116.       DoError("Part '%s' Not Found in Library '%s'\n",Name,theLibrary->Name);
  117.    return(thePart);
  118. }
  119.  
  120.  
  121. /*
  122.  *  LoadPart()
  123.  *
  124.  *  If a part was given,
  125.  *    Get the part's data into the NewGen grid array
  126.  *    Set the selct type and mouse move type to immitate a selection
  127.  *    Invert the SELECT GADGET
  128.  *    Start COPY mode.
  129.  */
  130.  
  131. static void LoadPart(thePart)
  132. PART *thePart;
  133. {
  134.    if (thePart)
  135.    {
  136.       PartToGrid(NewGen,thePart);
  137.       SelectType = SEL_WAIT; MouseMoveType = MM_SELECT;
  138.       InvertGadget(&cGadget[ID_SELECT]);
  139.       DoMoveCopy(MM_COPY);
  140.    }
  141. }
  142.  
  143.  
  144. /*
  145.  *  RemovePart()
  146.  *
  147.  *  Unlink the part from the list.
  148.  *  Remove the part from the requester's list or viewing area.
  149.  *  Free the part's memory.
  150.  *  Record that the circuit has been modified.
  151.  */
  152.  
  153. static void RemovePart(thePart,theLibrary)
  154. PART *thePart;
  155. LIBRARY *theLibrary;
  156. {
  157.    if (thePart->Next) thePart->Next->Prev = thePart->Prev;
  158.    if (thePart->Prev) thePart->Prev->Next = thePart->Next;
  159.    if (thePart == theLibrary->FirstPart) theLibrary->FirstPart = thePart->Next;
  160.    if (Viewing)
  161.       RemoveViewItem(LPGADGET[LP_PNAMES].UserData,thePart);
  162.      else
  163.       RemoveListItem(LPGADGET[LP_PNAMES].UserData,thePart);
  164.    FreePart(thePart);
  165.    Changed = TRUE;
  166. }
  167.  
  168.  
  169. /*
  170.  *  RemoveLibrary()
  171.  *
  172.  *  If the library is not allowed to be deleted,
  173.  *    give a warning
  174.  *  Otherwise,
  175.  *    Unlink the library from the library list.
  176.  *    Remove the library from the requester, and record the newly selected
  177.  *      library.
  178.  *    Reset the parts list on the requester to show the new current library.
  179.  *    Free the library's memory.
  180.  *    Mark the circuit as changed.
  181.  */
  182.  
  183. static void RemoveLibrary(theLibrary)
  184. LIBRARY *theLibrary;
  185. {
  186.    if (theLibrary->Flags & PL_NODELETE)
  187.    {
  188.       DoError("Can't Remove Library '%s'\n",theLibrary->Name);
  189.    } else {
  190.       if (theLibrary->Next) theLibrary->Next->Prev = theLibrary->Prev;
  191.       if (theLibrary->Prev) theLibrary->Prev->Next = theLibrary->Next;
  192.       if (theLibrary == FirstLibrary) FirstLibrary = theLibrary->Next;
  193.       SelectedLibrary = RemoveListItem(LPGADGET[LP_LNAMES].UserData,theLibrary);
  194.       if (Viewing)
  195.          SetView(&(LPGADGET[LP_PNAMES]),SelectedLibrary->FirstPart,NULL);
  196.         else
  197.          SetList(&(LPGADGET[LP_PNAMES]),SelectedLibrary->FirstPart,NULL);
  198.       FreeLibrary(theLibrary);
  199.       Changed = TRUE;
  200.    }
  201. }
  202.  
  203.  
  204. /*
  205.  *  LPGadgetUP()
  206.  *
  207.  *  Handle the Load part requester gadget up events:
  208.  *
  209.  *  USE and NAME:
  210.  *    Remove the requester and put the PART button back to normal
  211.  *    Find the selected part in the current library
  212.  *    If the part was found, load it, otherwise go back to drawing mode.
  213.  *
  214.  *  REMOVE:
  215.  *    If the selected list is the Parts List and a name is specified,
  216.  *      find the selected part in the library and remove it if possible.
  217.  *    Otherwise if a name is supplied (i.e., not in the Parts List)
  218.  *      warn about only being able to delete parts from the Parts List
  219.  *    Otherwise (no part name supplied)
  220.  *      remove the selected library
  221.  *    activate the name gadget
  222.  *
  223.  *  CANCEL:
  224.  *    Remove the requester and put things back to normal
  225.  *
  226.  *  SLIDERS:
  227.  *    Note the fact that sliders are no longer active
  228.  */
  229.  
  230. void LPGadgetUp(theGadget,theMessage)
  231. struct Gadget *theGadget;
  232. struct IntuiMessage *theMessage;
  233. {
  234.    PART *thePart;
  235.  
  236.    switch(theGadget->GadgetID)
  237.    {
  238.       case LP_USE:
  239.       case LP_NAME:
  240.          RemoveRequest(&LPRequest);
  241.          InvertGadget(&cGadget[ID_PART]);
  242.          thePart = FindPart(LPNameBuf,SelectedLibrary,TRUE);
  243.          if (thePart)
  244.             LoadPart(thePart);
  245.            else
  246.             SetPointerColor(PenInUse);
  247.          break;
  248.  
  249.       case LP_REMOVE:
  250.          if (SelectedLibrary == &PartsList && LPNameBuf[0])
  251.          {
  252.             thePart = FindPart(LPNameBuf,SelectedLibrary,TRUE);
  253.             if (thePart) RemovePart(thePart,SelectedLibrary);
  254.          } else if (LPNameBuf[0]) {
  255.             DoError("Only Parts in the Parts List can be Removed");
  256.          } else {
  257.             RemoveLibrary(SelectedLibrary);
  258.          }
  259.          ActivateName(LPGADGET[LP_PNAMES].UserData);
  260.          break;
  261.  
  262.       case LP_CANCEL:
  263.          RemoveRequest(&LPRequest);
  264.          InvertGadget(&cGadget[ID_PART]);
  265.          SetPointerColor(PenInUse);
  266.          break;
  267.  
  268.       case LP_PSLIDE:
  269.       case LP_LSLIDE:
  270.          EndListSlider(theGadget->UserData);
  271.          break;
  272.    }
  273. }
  274.  
  275.  
  276. /*
  277.  *  LPGadgetDown()
  278.  *
  279.  *  Do gadget down events fot the Load Part requester:
  280.  *
  281.  *  VIEW:
  282.  *    Find the selected part in the library (if possible)
  283.  *    Set viewing mode starting at the selected part (it it could be found,
  284.  *      otherwise start at the top of the list).
  285.  *
  286.  *  PART NAME:
  287.  *    Check if a part was selected; if so,
  288.  *      remove the requester and put things back to normal
  289.  *      load the part
  290.  *
  291.  *  LIBRARY NAME:
  292.  *    Check if a new library was selected; if so
  293.  *      set the parts list to show the contents of the new library, and
  294.  *      record the new library as the selected one
  295.  *    activate the name gadget
  296.  *
  297.  *  ARROWS and SLIDERS:
  298.  *    Scroll the appropriate list up or down
  299.  *
  300.  *  NAME:
  301.  *    Unselect any selected parts when the name gadget is clicked
  302.  */
  303.  
  304. void LPGadgetDown(theGadget,theMessage)
  305. struct Gadget *theGadget;
  306. struct IntuiMessage *theMessage;
  307. {
  308.    PART *thePart;
  309.    LIBRARY *theLibrary;
  310.  
  311.    switch(theGadget->GadgetID)
  312.    {
  313.       case LP_VIEW:
  314.          thePart = FindPart(LPNameBuf,SelectedLibrary,FALSE);
  315.          SetViewMode(LPGADGET[LP_PNAMES].UserData,
  316.             SelectedLibrary->FirstPart,thePart);
  317.          break;
  318.  
  319.       case LP_PNAMES:
  320.          thePart = (PART *)DoListHit(theGadget->UserData,theMessage);
  321.          if (thePart)
  322.          {
  323.             RemoveRequest(&LPRequest);
  324.             InvertGadget(&cGadget[ID_PART]);
  325.             LoadPart(thePart);
  326.          }
  327.          break;
  328.  
  329.       case LP_LNAMES:
  330.          theLibrary =
  331.             (LIBRARY *)DoListHit(theGadget->UserData,theMessage);
  332.          if (theLibrary)
  333.          {
  334.             if (Viewing)
  335.                SetView(&(LPGADGET[LP_PNAMES]),theLibrary->FirstPart,NULL);
  336.               else
  337.                SetList(&(LPGADGET[LP_PNAMES]),theLibrary->FirstPart,NULL);
  338.             SelectedLibrary = theLibrary;
  339.          }
  340.          ActivateName(LPGADGET[LP_PNAMES].UserData);
  341.          break;
  342.  
  343.       case LP_PUARROW:
  344.       case LP_LUARROW:
  345.          DoListScrollUp(theGadget->UserData,theGadget,theMessage);
  346.          break;
  347.  
  348.       case LP_PDARROW:
  349.       case LP_LDARROW:
  350.          DoListScrollDown(theGadget->UserData,theGadget,theMessage);
  351.          break;
  352.  
  353.       case LP_PSLIDE:
  354.       case LP_LSLIDE:
  355.          StartListSlider(theGadget->UserData);
  356.          break;
  357.  
  358.       case LP_NAME:
  359.          UnsetListSelect(theGadget->UserData,TRUE);
  360.          break;
  361.    }
  362. }
  363.  
  364.  
  365. /*
  366.  *  GetPart()
  367.  *
  368.  *  If the Load Part requester is not already active,
  369.  *    Clear the name buffer.
  370.  *    Set the pointer colors to normal and invert the PART button
  371.  *    Set the library list (selecting the current library)
  372.  *    Set the parts list to the proper viewing mode, and add the
  373.  *      requester with the correct routines for processing the gadgets
  374.  *    If the requester did not open, put things back to normal
  375.  */
  376.  
  377. void GetPart()
  378. {
  379.    extern void DoListMouse();
  380.    extern void ViewGadgetDown(),ViewGadgetUp(),DoViewMouse();
  381.  
  382.    if (ActiveRequest != &LPRequest)
  383.    {
  384.       LPNameBuf[0] = 0;
  385.       RestorePointerColor();
  386.       InvertGadget(&cGadget[ID_PART]);
  387.       SetList(&(LPGADGET[LP_LNAMES]),FirstLibrary,SelectedLibrary);
  388.       if (Viewing)
  389.       {
  390.          SetView(&(LPGADGET[LP_PNAMES]),SelectedLibrary->FirstPart,NULL);
  391.          AddRequest(&LPRequest,ViewGadgetDown,ViewGadgetUp,DoViewMouse);
  392.       } else {
  393.          SetList(&(LPGADGET[LP_PNAMES]),SelectedLibrary->FirstPart,NULL);
  394.          AddRequest(&LPRequest,LPGadgetDown,LPGadgetUp,DoListMouse);
  395.       }
  396.       if (ActiveRequest == NULL)
  397.       {
  398.          InvertGadget(&cGadget[ID_PART]);
  399.          SetPointerColor(PenInUse);
  400.       }
  401.    }
  402. }
  403.