home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d5xx / d502 / cells.lha / CELLS / CELLSSource.lzh / cDoGadget.c < prev    next >
C/C++ Source or Header  |  1991-04-20  |  12KB  |  537 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:  cDoGadget.c      Handles main control panel gadget events
  12.  */
  13.  
  14.  
  15. #include "cGadget.h"
  16.  
  17. int Running;                    /* TRUE if the circuit is running */
  18. int QuitInProgress;             /* TRUE if save requester is up during a QUIT */
  19. int SliderActive;               /* TRUE if a slider knob is being dragged */
  20. int Changed;                    /* TRUE if the circuit has been modified */
  21.  
  22. extern char FileName[];         /* Circuit's current name */
  23.  
  24.  
  25. /*
  26.  *  DoStart()
  27.  *
  28.  *  If the circuit is not already running,
  29.  *    cancel any selection and restore the pointer colors
  30.  *    copy the current states for use by RESET
  31.  *    assume that running will change the circuit
  32.  *    run the circuit until done
  33.  *    reset pointer to drawing color
  34.  *  return FALSE if QUIT was pressed during the run
  35.  */
  36.  
  37. static short DoStart(NotDone)
  38. short NotDone;
  39. {
  40.    if (!Running)
  41.    {
  42.       if (SelectType) CancelSelect();
  43.       RestorePointerColor();
  44.       CopyGrid(CurGen,ResetArray);
  45.       Changed = TRUE;
  46.       SetRunning();
  47.       NotDone = RunCells(NotDone);
  48.       SetPointerColor(PenInUse);
  49.    }
  50.    return(NotDone);
  51. }
  52.  
  53.  
  54. /*
  55.  *  DoReset()
  56.  *
  57.  *  If no cells selected:
  58.  *    setup UNDO unless the circuit is running
  59.  *    update the grid from the reset array and mark as changed
  60.  *    if the circuit is running,
  61.  *      set up the new generation array and linked lists
  62.  *
  63.  *    If cells are selected:
  64.  *      cancel the selection
  65.  */
  66.  
  67. static void DoReset()
  68. {
  69.    switch(SelectType)
  70.    {
  71.       case SEL_NONE:
  72.          if (!Running) CopyGrid(CurGen,UndoArray);
  73.          UpdateGrid(CurGen,ResetArray);
  74.          Changed = TRUE;
  75.          if (Running)
  76.          {
  77.             CopyGrid(CurGen,NewGen);
  78.             SetupLists(CurGen);
  79.          }
  80.          break;
  81.  
  82.       case SEL_WAIT:
  83.       case SEL_MOVE:
  84.          CancelSelect();
  85.          DoSelect();
  86.          break;
  87.    }
  88. }
  89.  
  90. /*
  91.  *  DoUndo()
  92.  *
  93.  *  Mark the circuit as modified
  94.  *  If cells are selected:
  95.  *    Undo only those that are selected, but copy the current states into
  96.  *    the UNDO buffer
  97.  *    Cancel the selection
  98.  *  If cells are being moved or copied:
  99.  *    cancel the selection and do then do the default function:
  100.  *  Otherwise:
  101.  *    swap the current states and the UNDO states and update the screen
  102.  */
  103.  
  104. static void DoUndo()
  105. {
  106.    register short x,y;
  107.    register short i;
  108.    UBYTE tmp;
  109.  
  110.    Changed = TRUE;
  111.    switch(MouseMoveType)
  112.    {
  113.       case MM_SELECT:
  114.          for (y=0,i=0; y<MAXGRIDH; y++)
  115.          {
  116.             for (x=0; x<MAXGRIDW; x++,i++)
  117.             {
  118.                if (NewGen[i])
  119.                {
  120.                   tmp = CurGen[i];
  121.                   CurGen[i] = UndoArray[i];
  122.                   UndoArray[i] = tmp;
  123.                } else {
  124.                   UndoArray[i] = CurGen[i];
  125.                }
  126.             }
  127.          }
  128.          CancelSelect();
  129.          break;
  130.  
  131.       case MM_MOVE:
  132.       case MM_COPY:
  133.          CancelSelect();
  134.       default:
  135.          CopyGrid(CurGen,NewGen);
  136.          UpdateGrid(CurGen,UndoArray);
  137.          CopyGrid(NewGen,UndoArray);
  138.          break;
  139.    }
  140. }
  141.  
  142.  
  143. /*
  144.  *  DoClear()
  145.  *
  146.  *  Mark the circuit as modified and sate the current states in the UNDO buffer
  147.  *  If no cells selected:
  148.  *    clear the grid and the screen
  149.  *    set the pen color to WIRE
  150.  *  If cells selected,
  151.  *    clear only those cells that are selected
  152.  *    cancel the selection
  153.  */
  154.  
  155. void DoClear()
  156. {
  157.    Changed = TRUE;
  158.    CopyGrid(CurGen,UndoArray);
  159.    switch(SelectType)
  160.    {
  161.       case SEL_NONE:
  162.          ClearGrid(CurGen);
  163.          ClearScreen(TRUE);
  164.          SetPenColor(ID_WIREC);
  165.          break;
  166.  
  167.       case SEL_WAIT:
  168.          RemoveGrid(NewGen,CurGen);
  169.          CancelSelect();
  170.          break;
  171.    }
  172. }
  173.  
  174.  
  175. /*
  176.  *  DoClip()
  177.  *
  178.  *  Mark the circuit as modified and save the current states in the UNDO buffer
  179.  *  If cells are selected:
  180.  *    clear the grid and put back only the selected cells
  181.  *    refresh the screen and cancel the selection
  182.  *  If no cells are selected:
  183.  *    clear all cells outside the visible area of the screen
  184.  *    (no refresh is necessary since it can't be seen)
  185.  */
  186.  
  187. static void DoClip()
  188. {
  189.    register short x,y;
  190.    register short i;
  191.  
  192.    Changed = TRUE;
  193.    CopyGrid(CurGen,UndoArray);
  194.    switch(SelectType)
  195.    {
  196.       case SEL_WAIT:
  197.          ClearGrid(CurGen);
  198.          ReplaceGrid(NewGen,CurGen);
  199.          ClearScreen(FALSE);
  200.          CancelSelect();
  201.          break;
  202.          
  203.       case SEL_NONE:
  204.          for (y=0,i=0; y<MAXGRIDH; y++)
  205.             for (x=0; x<MAXGRIDW; x++,i++)
  206.                if (x < GridX || x >= GridX+GridW ||
  207.                    y < GridY || y >= GridY+GridH)
  208.                        CurGen[i] = BLANK;
  209.          break;
  210.    }
  211. }
  212.  
  213.  
  214. /*
  215.  *  DoCenter()
  216.  *
  217.  *  Cancel any selection.
  218.  *  Mark the circuit as modified and copy the grid into the UNDO buffer
  219.  *  Find the active area of the grid and clear the New Generation array
  220.  *  (as work area).  Clear the screen (it will be refrehsed later).
  221.  *
  222.  *  Calculate the offset to the new center position, and the offset in
  223.  *  the grid array that corresponds to it.  Copy the active area of the
  224.  *  circuit into the New Generation array.
  225.  *
  226.  *  Set the viewing position to the new center.
  227.  *  Clear the grid and update it from the new generation.
  228.  *  Update the slider positions.
  229.  */
  230.  
  231. static void DoCenter()
  232. {
  233.    short x,y,w,h;
  234.    register short X,Y;
  235.    short dx,dy;
  236.    register short i,di;
  237.  
  238.    if (SelectType) CancelSelect();
  239.  
  240.    Changed = TRUE;
  241.    CopyGrid(CurGen,UndoArray);
  242.    GetBounds(CurGen,&x,&y,&w,&h,BLANK);
  243.    ClearGrid(NewGen);
  244.    ClearScreen(FALSE);
  245.  
  246.    dx = (MAXGRIDW - w) / 2 - x;
  247.    dy = (MAXGRIDH - h) / 2 - y;
  248.    di = dx + MAXGRIDW * dy;
  249.    for (Y=y; Y<y+h; Y++)
  250.       for (X=x,i=X+MAXGRIDW*Y; X<x+w; X++,i++)
  251.          NewGen[i+di] = CurGen[i];
  252.  
  253.    GridX = (MAXGRIDW - GridW) / 2;
  254.    GridY = (MAXGRIDH - GridH) / 2;
  255.    ClearGrid(CurGen);
  256.    UpdateGrid(CurGen,NewGen);
  257.    UpdateSliders();
  258. }
  259.  
  260.  
  261. /*
  262.  *  DoWipe()
  263.  *
  264.  *  Mark the circuit as changed and save the states into the UNDO buffer
  265.  *  If no cells are selected, wipe the electrons off the entire grid,
  266.  *  otherwise wipe the electrons off the new generation grid, and replace
  267.  *  the current states by the (wiped) new generation only where the cells
  268.  *  are selected.  Cancel the selection.
  269.  */
  270.  
  271. static void DoWipe()
  272. {
  273.    Changed = TRUE;
  274.    CopyGrid(CurGen,UndoArray);
  275.    switch(SelectType)
  276.    {
  277.       case SEL_NONE:
  278.          WipeGrid(CurGen,TRUE);
  279.          break;
  280.  
  281.       case SEL_WAIT:
  282.          WipeGrid(NewGen,FALSE);
  283.          ReplaceGrid(NewGen,CurGen);
  284.          CancelSelect();
  285.          break;
  286.    }
  287. }
  288.  
  289.  
  290. /*
  291.  * DoQuit()
  292.  *
  293.  *  Cancel any selection.
  294.  *  If changes have been made to the circuit since the last SAVE,
  295.  *    Invert the QUIT button and ask if changes should be saved
  296.  *    If yes, then
  297.  *      if we already know the file name, we'll do the save and be done,
  298.  *      otherwise we will put up the requester and need to quit later.
  299.  *      do the save operation
  300.  *    Otherwise ask if they really want to quit
  301.  *    put the QUIT button back to normal
  302.  *  Otherwise
  303.  *    it is safe to quit, so do so.
  304.  */
  305.  
  306. int DoQuit(NotDone)
  307. int NotDone;
  308. {
  309.    if (SelectType) CancelSelect();
  310.    if (Changed)
  311.    {
  312.       InvertGadget(&cGadget[ID_QUIT]);
  313.       RestorePointerColor();
  314.       if (DoQuestion("Save Changes before Quiting?"))
  315.       {
  316.          if (FileName[0]) NotDone = FALSE; else QuitInProgress = TRUE;
  317.          DoSave();
  318.       } else {
  319.          if (DoQuestion("Really Quit?")) NotDone = FALSE;
  320.       }
  321.       SetPointerColor(PenInUse);
  322.       InvertGadget(&cGadget[ID_QUIT]);
  323.    } else {
  324.       NotDone = FALSE;
  325.    }
  326.    return(NotDone);
  327. }
  328.  
  329.  
  330. /*
  331.  *  DoGadgetUp()
  332.  *
  333.  *  Do the right things for each possible button or gadget:
  334.  *
  335.  *  START:      start the circuit
  336.  *  STEP:       cancel the selection and step the circuit
  337.  *  STOP:       stop a running circuit
  338.  *  RESET:      do the Reset function
  339.  *  WIPE:       do the Wipe function
  340.  *  RENAME:     Save the circuit under a different name
  341.  *  LOAD:       Load a circuit or library
  342.  *  NEW:        Clear the grid for a new circuit
  343.  *  SELECT:     Start selecting cells
  344.  *  MOVE:       If cells are selected, move them, otherwise start selecting
  345.  *  COPY:       If cells are selected, copy them, otherwise start selecting
  346.  *  CLEAR:      Do the Clear function
  347.  *  CLIP:       Do the Clip function
  348.  *  PART:       If cells are selected, make them into a part, otherwise
  349.  *              get a part from the parts list
  350.  *  UNDO        Do the Undo function
  351.  *  CENTER:     Do the Center function
  352.  *  SLIDEH:     The horizontal slider is done being dragged
  353.  *  SLIDEV:     The vertical slider is done being dragged
  354.  *  ZOOM:       Zoom in on the grid
  355.  *  SHRINK:     Zoom out from the grid
  356.  *  HELP:       Do the Help function
  357.  *  ABOUT:      Show the About box
  358.  *  QUIT:       Attempt to Quit from CELLS
  359.  *  ARROWS:     Ignore arrow up events
  360.  */
  361.  
  362. int DoGadgetUp(theGadget,theMessage,NotDone)
  363. struct Gadget *theGadget;
  364. struct IntuiMessage *theMessage;
  365. {
  366.    switch(theGadget->GadgetID)
  367.    {
  368.       case ID_START:
  369.          NotDone = DoStart(NotDone);
  370.          break;
  371.  
  372.       case ID_STEP:
  373.          if (SelectType) CancelSelect();
  374.          StepCells();
  375.          break;
  376.  
  377.       case ID_STOP:
  378.          if (Running) SetStopped();
  379.          break;
  380.  
  381.       case ID_RESET:
  382.          DoReset();
  383.          break;
  384.  
  385.       case ID_WIPE:
  386.          DoWipe();
  387.          break;
  388.  
  389.       case ID_SAVE:
  390.          DoSave();
  391.          break;
  392.  
  393.       case ID_RENAME:
  394.          DoSaveAs();
  395.          break;
  396.  
  397.       case ID_LOAD:
  398.          DoLoad();
  399.          break;
  400.  
  401.       case ID_NEW:
  402.          DoNew();
  403.          break;
  404.  
  405.       case ID_SELECT:
  406.          DoSelect();
  407.          break;
  408.  
  409.       case ID_MOVE:
  410.          if (SelectType)
  411.             DoMoveCopy(MM_MOVE);
  412.            else
  413.             DoSelect();
  414.          break;
  415.  
  416.       case ID_COPY:
  417.          if (SelectType)
  418.             DoMoveCopy(MM_COPY);
  419.            else
  420.             DoSelect();
  421.          break;
  422.  
  423.       case ID_CLEAR:
  424.          DoClear();
  425.          break;
  426.  
  427.       case ID_CLIP:
  428.          DoClip();
  429.          break;
  430.  
  431.       case ID_PART:
  432.          if (SelectType)
  433.             AddPart();
  434.            else
  435.             GetPart();
  436.          break;
  437.  
  438.       case ID_UNDO:
  439.          DoUndo();
  440.          break;
  441.  
  442.       case ID_CENTER:
  443.          DoCenter();
  444.          break;
  445.  
  446.       case ID_SLIDEH:
  447.          StopMouseMoves(); SliderActive = FALSE;
  448.          DoSlideH();
  449.          break;
  450.  
  451.       case ID_SLIDEV:
  452.          StopMouseMoves(); SliderActive = FALSE;
  453.          DoSlideV();
  454.          break;
  455.  
  456.       case ID_ZOOM:
  457.          DoZoom();
  458.          break;
  459.  
  460.       case ID_SHRINK:
  461.          DoShrink();
  462.          break;
  463.  
  464.       case ID_HELP:
  465.          DoHelp();
  466.          break;
  467.  
  468.       case ID_ABOUT:
  469.          DoAbout();
  470.          break;
  471.  
  472.       case ID_QUIT:
  473.          NotDone = DoQuit(NotDone);
  474.          break;
  475.  
  476.       case ID_LARROW:
  477.       case ID_RARROW:
  478.       case ID_UARROW:
  479.       case ID_DARROW:
  480.          break;
  481.    }
  482.    return(NotDone);
  483. }
  484.  
  485.  
  486. /*
  487.  *  DoGadgetDown()
  488.  *
  489.  *  Do the right thing for each gadget down event:
  490.  *
  491.  *  SLIDEH or SLIDEV:   if the knob is hit, start reporting mouse moves and
  492.  *                      set the slider active flag, otherwise wait for a
  493.  *                      gadget up event.
  494.  *  Color Gadgets:      Set the point in use to the selected color.
  495.  *  Arrows:             Scroll the correct direction.
  496.  */
  497.  
  498. void DoGadgetDown(theGadget,theMessage)
  499. struct Gadget *theGadget;
  500. struct IntuiMessage *theMessage;
  501. {
  502.    switch(theGadget->GadgetID)
  503.    {
  504.       case ID_SLIDEH:
  505.       case ID_SLIDEV:
  506.          if (cSlider[theGadget->GadgetID-ID_SLIDEH+PROP_SLIDEH].Flags & KNOBHIT)
  507.          {
  508.             StartMouseMoves();
  509.             SliderActive = TRUE;
  510.          }
  511.          break;
  512.  
  513.       case ID_BLANKC:
  514.       case ID_WIREC:
  515.       case ID_TAILC:
  516.       case ID_HEADC:
  517.          SetPenColor(theGadget->GadgetID);
  518.          break;
  519.  
  520.       case ID_LARROW:
  521.          DoScrollLeft(theGadget);
  522.          break;
  523.  
  524.       case ID_RARROW:
  525.          DoScrollRight(theGadget);
  526.          break;
  527.  
  528.       case ID_UARROW:
  529.          DoScrollUp(theGadget);
  530.          break;
  531.  
  532.       case ID_DARROW:
  533.          DoScrollDown(theGadget);
  534.          break;
  535.    }
  536. }
  537.