home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d5xx / d502 / cells.lha / CELLS / CELLSSource.lzh / cDoKey.c < prev    next >
C/C++ Source or Header  |  1991-04-20  |  9KB  |  358 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:  cDoKey.c             Handles keyboard events
  12.  */
  13.  
  14.  
  15. #include "cGadget.h"
  16.  
  17. #define ESC         0x45
  18. #define DBUFKEY     0x35        /* 'B' key */
  19. #define HELP        0x5F
  20. #define DELETE      0x46
  21. #define BACKSPACE   0x41
  22. #define ENTER       0x43
  23.  
  24. int Shifted;                    /* TRUE if gadgets are shifted */
  25. int DelayedShift;               /* TRUE if gadgets should be shifted */
  26.                                 /*  at the next opportunity */
  27.  
  28.  
  29. /*
  30.  *  DisableGadget()
  31.  *
  32.  *  Remove the gadget, disable it, add it back in, then refresh the gadget.
  33.  *  (the OffGadget call refreshes ALL the gadgets - too noisey)
  34.  */
  35.  
  36. static void DisableGadget(theGadget)
  37. struct Gadget *theGadget;
  38. {
  39.    int pos;
  40.  
  41.    pos = RemoveGadget(myWindow,theGadget);
  42.    theGadget->Flags |= GADGDISABLED;
  43.    AddGadget(myWindow,theGadget,pos);
  44.    RefreshGList(theGadget,myWindow,NULL,1);
  45. }
  46.  
  47.  
  48. /*
  49.  *  EnableGadget()
  50.  *
  51.  *  Remove the gadget, enable it, and add it back in.  Clear the
  52.  *  gadgets background, and then refresh the gadget.
  53.  */
  54.  
  55. static void EnableGadget(theGadget)
  56. struct Gadget *theGadget;
  57. {
  58.    int x = theGadget->LeftEdge,
  59.        y = theGadget->TopEdge,
  60.        w = theGadget->Width,
  61.        h = theGadget->Height;
  62.    int pos;
  63.  
  64.    pos = RemoveGadget(myWindow,theGadget);
  65.    theGadget->Flags &= ~GADGDISABLED;
  66.    AddGadget(myWindow,theGadget,pos);
  67.    SetAPen(wrp,FOREGROUND);
  68.    SetDrMd(wrp,JAM1);
  69.    RectFill(wrp,x,y,x+w-1,y+h-1);
  70.    RefreshGList(theGadget,myWindow,NULL,1);
  71. }
  72.  
  73.  
  74. /*
  75.  *  SetRunning()
  76.  *
  77.  *  If the START gadget is not shifted,
  78.  *    turn the gadget into the STOP gadget and refresh it.
  79.  *    disable the editing buttons.
  80.  *  set the Running flag.
  81.  */
  82.  
  83. void SetRunning()
  84. {
  85.    struct Gadget *theGadget = &cGadget[ID_START];
  86.    short i;
  87.  
  88.    if (theGadget->GadgetID == ID_START)
  89.    {
  90.       Forbid();
  91.       theGadget->GadgetID = ID_STOP;
  92.       theGadget->GadgetText = &cIText[TEXT_STOP];
  93.       if (theGadget->Flags & SELECTED) InvertGadget(theGadget);
  94.       theGadget->MyFlags &= ~BUTTON_SELECTED;
  95.       RefreshGList(theGadget,myWindow,NULL,1);
  96.       Permit();
  97.       for (i=ID_SAVE; i<ID_HELP; DisableGadget(&cGadget[i++]));
  98.    }
  99.    Running = TRUE;
  100. }
  101.  
  102.  
  103. /*
  104.  *  SetStopped()
  105.  *
  106.  *  If the START gadget is still the STOP gadget,
  107.  *    turn the gadget back into the START gadget,
  108.  *    enable the editing gadgets again
  109.  *  Reset the Running flag.
  110.  */
  111.  
  112. void SetStopped()
  113. {
  114.    struct Gadget *theGadget = &cGadget[ID_START];
  115.    short i;
  116.  
  117.    if (theGadget->GadgetID == ID_STOP)
  118.    {
  119.       Forbid();
  120.       theGadget->GadgetID = ID_START;
  121.       theGadget->GadgetText = &cIText[ID_START];
  122.       if (theGadget->Flags & SELECTED) InvertGadget(theGadget);
  123.       theGadget->MyFlags &= ~BUTTON_SELECTED;
  124.       RefreshGList(theGadget,myWindow,NULL,1);
  125.       Permit();
  126.       for (i=ID_SAVE; i<ID_HELP; EnableGadget(&cGadget[i++]));
  127.    }
  128.    Running = FALSE;
  129. }
  130.  
  131.  
  132. /*
  133.  *  ShowShiftedGadgets()
  134.  *
  135.  *  For each of the button gadgets:
  136.  *    if the button is not selected and is allowed to shift, and the
  137.  *    gadget is not already shifted, and if we are not running,
  138.  *    or we are allowed to shift while running,
  139.  *      set the gadget to the shifted name and refresh it.
  140.  *    go on to the next gadget.
  141.  *  if the Zoom gadget is still the Zoom gadget,
  142.  *    convert it to the Shrink gadget.
  143.  */
  144.  
  145. void ShowShiftedGadgets()
  146. {
  147.    struct Gadget *theGadget = &cGadget[0];
  148.    
  149.    while (theGadget && (theGadget->MyFlags & IS_BUTTON))
  150.    {
  151.       if ((theGadget->MyFlags & (BUTTON_NOSHIFT|BUTTON_SELECTED)) == 0 &&
  152.            theGadget->GadgetID < ID_OFFSET &&
  153.           (!Running || (theGadget->MyFlags & BUTTON_RUNSHIFT)))
  154.       {
  155.          Forbid();
  156.          theGadget->GadgetText = &cIText[theGadget->GadgetID+TEXT_OFFSET];
  157.          theGadget->GadgetID += ID_OFFSET;
  158.          if (theGadget->Flags & SELECTED) InvertGadget(theGadget);
  159.          theGadget->MyFlags &= ~BUTTON_SELECTED;
  160.          RefreshGList(theGadget,myWindow,NULL,1);
  161.          Permit();
  162.       }
  163.       theGadget = theGadget->NextGadget;
  164.    }
  165.    theGadget = &cGadget[ID_ZOOM];
  166.    if (theGadget->GadgetID == ID_ZOOM)
  167.    {
  168.       Forbid();
  169.       theGadget->GadgetRender = (APTR) &cImage[IM_SHRINK];
  170.       theGadget->GadgetID = ID_SHRINK;
  171.       if (theGadget->Flags & SELECTED) InvertGadget(theGadget);
  172.       theGadget->MyFlags &= ~BUTTON_SELECTED;
  173.       RefreshGList(theGadget,myWindow,NULL,1);
  174.       Permit();
  175.    }
  176. }
  177.  
  178.  
  179. /*
  180.  *  ShowNormalGadgets()
  181.  *
  182.  *  For each button gadget:
  183.  *    if the button is not selected and is allowed to shift, and the
  184.  *    gadget is shifted, and if we are not running,
  185.  *    or we are allowed to shift while running,
  186.  *      set the gadget to the unshifted name and refresh it.
  187.  *    go on to the next gadget.
  188.  *  if the Zoom gadget is the Shrink gadget,
  189.  *    convert it to the Zoom gadget
  190.  */
  191.  
  192. void ShowNormalGadgets()
  193. {
  194.    struct Gadget *theGadget = &cGadget[0];
  195.    
  196.    while (theGadget && (theGadget->MyFlags & IS_BUTTON))
  197.    {
  198.       if ((theGadget->MyFlags & (BUTTON_NOSHIFT|BUTTON_SELECTED)) == 0 &&
  199.            theGadget->GadgetID >= ID_OFFSET &&
  200.           (!Running || (theGadget->MyFlags & BUTTON_RUNSHIFT)))
  201.       {
  202.          Forbid();
  203.          theGadget->GadgetID -= ID_OFFSET;
  204.          theGadget->GadgetText = &cIText[theGadget->GadgetID];
  205.          if (theGadget->Flags & SELECTED) InvertGadget(theGadget);
  206.          theGadget->MyFlags &= ~BUTTON_SELECTED;
  207.          RefreshGList(theGadget,myWindow,NULL,1);
  208.          Permit();
  209.       }
  210.       theGadget = theGadget->NextGadget;
  211.    }
  212.    theGadget = &cGadget[ID_ZOOM];
  213.    if (theGadget->GadgetID == ID_SHRINK)
  214.    {
  215.       Forbid();
  216.       theGadget->GadgetRender = (APTR) &cImage[IM_ZOOM];
  217.       theGadget->GadgetID = ID_ZOOM;
  218.       if (theGadget->Flags & SELECTED) InvertGadget(theGadget);
  219.       theGadget->MyFlags &= ~BUTTON_SELECTED;
  220.       RefreshGList(theGadget,myWindow,NULL,1);
  221.       Permit();
  222.    }
  223. }
  224.  
  225.  
  226. /*
  227.  *  ShiftGadgets()
  228.  *
  229.  *  If no requester is active,
  230.  *    if shift keys are pressed,
  231.  *      if we're not already shifted, shift the gadgets
  232.  *    Otherwise
  233.  *      if we're already shifted, unshift the gadgets
  234.  *  record the delayed shift
  235.  */
  236.  
  237. void ShiftGadgets(keys)
  238. ULONG keys;
  239. {
  240.    if (ActiveRequest == NULL)
  241.    {
  242.       if (keys)
  243.       {
  244.          if (!Shifted) ShowShiftedGadgets();
  245.          Shifted = TRUE;
  246.       } else {
  247.          if (Shifted)  ShowNormalGadgets();
  248.          Shifted = FALSE;
  249.       }
  250.    }
  251.    DelayedShift = (keys != 0);
  252. }
  253.  
  254.  
  255. /*
  256.  *  UpdateShiftKeys()
  257.  *
  258.  *  If delayed shift is different frlom the current shift, and there
  259.  *  is no active gadget, update the gadgets as needed, and record the
  260.  *  status.
  261.  */
  262.  
  263. void UpdateShiftKeys()
  264. {
  265.    if (DelayedShift != Shifted && ActiveRequest == NULL)
  266.    {
  267.       if (DelayedShift)
  268.          ShowShiftedGadgets();
  269.         else
  270.          ShowNormalGadgets();
  271.       Shifted = DelayedShift;
  272.    }
  273. }
  274.  
  275.  
  276. /*
  277.  *  DoKey()
  278.  *
  279.  *  Do the right thing for each of the special keys:
  280.  *
  281.  *    ESC:          Attempt to quit.
  282.  *    DBUFKEY:      Change the double-buffer mode.
  283.  *    CURSORUP:             Increase the generation delay time.
  284.  *    CURSORDOWN:           Decrease the generation delay time.
  285.  *    HELP:                 Unshift all gadgets, and do the HELP function.
  286.  *    DELETE or BACKSPACE:  Do the Clear function.
  287.  *    ENTER:                Cancel any selection, and step the circuit.
  288.  */
  289.  
  290. int DoKey(theCode,theMessage,NotDone)
  291. USHORT theCode;
  292. struct IntuiMessage *theMessage;
  293. short NotDone;
  294. {
  295.    switch(theCode)
  296.    {
  297.       case ESC:
  298.          NotDone = DoQuit(NotDone);
  299.          break;
  300.  
  301.       case DBUFKEY:
  302.          SetDBufMode(!DBufMode);
  303.          break;
  304.  
  305.       case CURSORUP:
  306.          if (GenerationDelay > 8)
  307.             GenerationDelay = GenerationDelay * 4 / 3;
  308.            else
  309.             GenerationDelay++;
  310.          break;
  311.  
  312.       case CURSORDOWN:
  313.          if (GenerationDelay > 8)
  314.             GenerationDelay = GenerationDelay * 3 / 4;
  315.            else
  316.             if (GenerationDelay) GenerationDelay--;
  317.          break;
  318.  
  319.       case HELP:
  320.          ShiftGadgets(FALSE);
  321.          DoHelp();
  322.          break;
  323.  
  324.       case DELETE:
  325.       case BACKSPACE:
  326.          DoClear();
  327.          break;
  328.  
  329.       case ENTER:
  330.          if (SelectType) CancelSelect();
  331.          StepCells();
  332.          break;
  333.    }
  334.    return(NotDone);
  335. }
  336.  
  337.  
  338. /*
  339.  *  DoInactive()
  340.  *
  341.  *  If the inactivated window is the CELLS window,
  342.  *    fake a menu up (to finish drawing or dragging),
  343.  *    fake a select up (to finish drawing or selecting),
  344.  *    unshift the gadgets.
  345.  */
  346.  
  347. void DoInactive(theWindow,theMessage)
  348. struct Window *theWindow;
  349. struct IntuiMessage *theMessage;
  350. {
  351.    if (theWindow == myWindow)
  352.    {
  353.       DoMouseButton(MENUUP,theMessage->MouseX,theMessage->MouseY,theMessage);
  354.       DoMouseButton(SELECTUP,theMessage->MouseX,theMessage->MouseY,theMessage);
  355.       ShiftGadgets(FALSE);
  356.    }
  357. }
  358.