home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 199.lha / DmfSrc_v2.5 / mxgadget.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-12-27  |  10.9 KB  |  352 lines

  1. /*
  2.  *
  3.  *            Copywrite (C) 1986 by Davide P. Cervone
  4.  *
  5.  *    Permission is granted for any individual or institution to use,
  6.  *    copy, or redistribute this software, provided this copywrite
  7.  *    notice is retained.
  8.  *
  9.  */
  10.  
  11. #include <exec/types.h>
  12. #include <exec/devices.h>
  13. #include <libraries/dos.h>
  14. #include <intuition/intuition.h>
  15. #include <graphics/gfxbase.h>
  16. #include <graphics/regions.h>
  17. #include <graphics/copper.h>
  18. #include <graphics/gels.h>
  19. #include <devices/keymap.h>
  20. #include <hardware/blit.h>
  21.  
  22. #include "mxgadget.h"
  23.  
  24. #define  USERDATA(x)     ((struct MxGadgetMasks *) x->UserData)
  25.  
  26. SelectGadget(theGadget,theWindow,theRequester)
  27. struct Gadget *theGadget;
  28. struct Window *theWindow;
  29. struct Requester *theRequester;
  30. {
  31.    if (isMxGadget(theGadget))
  32.    {
  33.       struct MxGadgetMasks *theData = USERDATA(theWindow);
  34.       LONG Exclude = theGadget->MutualExclude;
  35.                              /* Groups this gadget excludes */
  36.       LONG Disable = 0;      /* Groups this gadget disables */
  37.       LONG Enable  = 0;      /* Groups this gadget enables  */
  38.  
  39.       if (theData != NULL && Exclude != 0)
  40.       {
  41.          if (MxFlagSet(theGadget,MXENABLEGADG))
  42.             Enable  = Exclude & theData->EnableMask;
  43.          if (MxFlagSet(theGadget,MXDISABLEGADG))
  44.             Disable = Exclude & theData->DisableMask;
  45.          Exclude &= ~(theData->EnableMask | theData->DisableMask);
  46.       }
  47.  
  48. /*
  49.  *  If the gadget already is selected, just mutual exclude other gadgets;
  50.  *  Otherwise, if a TOGGLE gadget has just been unselected, then undo
  51.  *    any disabling or enabling caused when it was selected;
  52.  *  Otherwise, we are selecting a previously unselected, non-TOOGLE
  53.  *    gadget, so select it, draw its imagery, and mutual exclude others.
  54.  */
  55.  
  56.       if (isSelected(theGadget))
  57.       {
  58.          ExcludeMxGadgets(theGadget,theWindow,theRequester,
  59.                           Exclude,Enable,Disable);
  60.       } else {
  61.          if (theGadget->Activation & TOGGLESELECT)
  62.          {
  63.             ExcludeMxGadgets(theGadget,theWindow,theRequester,
  64.                              0,Disable,Enable);
  65.          } else {
  66.             SetGadgFlag(theGadget,SELECTED);
  67.             DrawGadget(theGadget,theWindow,theRequester);
  68.             ExcludeMxGadgets(theGadget,theWindow,theRequester,
  69.                              Exclude,Enable,Disable);
  70.          }
  71.       }
  72.    }
  73. }
  74.  
  75. UnSelectGadget(theGadget,theWindow,theRequester)
  76. struct Gadget *theGadget;
  77. struct Window *theWindow;
  78. struct Requester *theRequester;
  79. {
  80.  
  81. /*
  82.  *  If the gadget is selected, then clear the selection flags; then, if it is
  83.  *  not disbaled, redraw it with unselected imagery.
  84.  */
  85.  
  86.    if (isAnySelected(theGadget))
  87.    {
  88.       ClearGadgFlag(theGadget,SELECTED);
  89.       ClearMxFlag(theGadget,MXSELECT);
  90.       if (isNotDisabled(theGadget))
  91.          DrawGadget(theGadget,theWindow,theRequester);
  92.    }
  93. }
  94.  
  95. MxOffGadget(theGadget,theWindow,theRequester)
  96. struct Gadget *theGadget;
  97. struct Window *theWindow;
  98. struct Requester *theRequester;
  99. {
  100.  
  101. /*
  102.  *  If the gadget currently is selected, save the status via the MXSELECT
  103.  *  flag so that when we enable the gadget again, we can re-select it.
  104.  *  Finally, "ghost" the gadget by turning it off.
  105.  */
  106.  
  107.    if (isSelected(theGadget) && isMxGadget(theGadget))
  108.    {
  109.       ClearGadgFlag(theGadget,SELECTED);
  110.       SetMxFlag(theGadget,MXSELECT);
  111.       DrawGadget(theGadget,theWindow,theRequester);
  112.    }
  113.    IsolateGadget(theGadget,theWindow,theRequester);
  114.    OffGadget(theGadget,theWindow,theRequester);
  115.    RestoreGadget(theGadget,theWindow,theRequester);
  116. }
  117.  
  118. MxOnGadget(theGadget,theWindow,theRequester)
  119. struct Gadget *theGadget;
  120. struct Window *theWindow;
  121. struct Requester *theRequester;
  122. {
  123.  
  124. /*
  125.  *  Turn the gadget on, and if it was previously marked as SELECTED
  126.  *  (i.e., we saved the fact that it was selected via the MXSELECT flag),
  127.  *  then select the gadget and draw the selected imagery.
  128.  */
  129.  
  130.    IsolateGadget(theGadget,theWindow,theRequester);
  131.    OnGadget(theGadget,theWindow,theRequester);
  132.    RestoreGadget(theGadget,theWindow,theRequester);
  133.    if (isMxGadget(theGadget) && isMxSelected(theGadget))
  134.    {
  135.       SetGadgFlag(theGadget,SELECTED);
  136.       ClearMxFlag(theGadget,MXSELECT);
  137.       DrawGadget(theGadget,theWindow,theRequester);
  138.    }
  139. }
  140.  
  141. struct Window *
  142. MxOpenWindow(NewWindow)
  143. struct NewWindow *NewWindow;
  144. {
  145.    struct Window *theWindow, *OpenWindow();
  146.    struct MxGadgetMasks *theData, *AllocMem();
  147.  
  148. /*
  149.  *  Open the window and allocate memory for the Enable/Diable masks for this
  150.  *  window.  Since we are using the UserData pointer, supply another one,
  151.  *  so users have something to use.
  152.  */
  153.  
  154.    if ((theWindow = OpenWindow(NewWindow)) != NULL)
  155.    {
  156.       theData = AllocMem(sizeof(struct MxGadgetMasks),0);
  157.       if (theData != NULL)
  158.       {
  159.          theData->DisableMask = 0;
  160.          theData->EnableMask  = 0;
  161.          theData->UserData = NULL;
  162.          theWindow->UserData = (BYTE *) theData;
  163.       }
  164.    }
  165.    return(theWindow);
  166. }
  167.  
  168. MxCloseWindow(theWindow)
  169. struct Window *theWindow;
  170. {
  171.  
  172. /*
  173.  *  Free the mask data memory, and then close the window.
  174.  */
  175.  
  176.    if (theWindow != NULL)
  177.    {
  178.       if (theWindow->UserData != NULL)
  179.          FreeMem(theWindow->UserData,sizeof(struct MxGadgetMasks));
  180.       CloseWindow(theWindow);
  181.    }
  182. }
  183.  
  184. SetMxGadgetMasks(theWindow,EnableMask,DisableMask)
  185. struct Window *theWindow;
  186. LONG EnableMask, DisableMask;
  187. {
  188.    struct MxGadgetMasks *theData = USERDATA(theWindow);
  189.  
  190.    if (theData != NULL)
  191.    {
  192.       theData->DisableMask = DisableMask;
  193.       theData->EnableMask  = EnableMask;
  194.    }
  195. }
  196.  
  197. LONG GetMxGadgetMasks(theWindow,EnableMask,DisableMask)
  198. struct Window *theWindow;
  199. LONG *EnableMask, *DisableMask;
  200. {
  201.    struct MxGadgetMasks *theData = USERDATA(theWindow);
  202.  
  203.    if (theData != NULL)
  204.    {
  205.       *DisableMask = theData->DisableMask;
  206.       *EnableMask  = theData->EnableMask;
  207.    } else {
  208.       *DisableMask = 0;
  209.       *EnableMask  = 0;
  210.    }
  211. }
  212.  
  213. DrawGadget(theGadget,theWindow,theRequester)
  214. struct Gadget *theGadget;
  215. struct Window *theWindow;
  216. struct Requester *theRequester;
  217. {
  218.    LONG NotSelected = GadgFlagNotSet(theGadget,SELECTED);
  219.  
  220. /*
  221.  *  If the gadget is not an IMAGE gadget (i.e., it uses complementation
  222.  *  to show that it is selected), then temporarily select it, so that we
  223.  *  are sure that complementation takes place.  Refresh the gadget:  for
  224.  *  IMAGE gadgets, the proper image is shown (selected or not), while for
  225.  *  non-IMAGE gadgets, this forces complementation (so that previously
  226.  *  selected gadgets become unselected, and vice versa).  Finally, if the
  227.  *  gadget was not selected, clear the selected flag, and refresh non-IMAGE
  228.  *  gadgets again, to be sure that the border and text are shown in the
  229.  *  proper colors.  Note that gadget borders and text should be rendered in
  230.  *  JAM1 mode, not COMPLEMENT mode.  If you need to use COMPLEMENT mode,
  231.  *  remove the second RefreshGadgets call.
  232.  */
  233.  
  234.    if (GadgFlagNotSet(theGadget,GADGHIMAGE))
  235.       SetGadgFlag(theGadget,SELECTED);
  236.    IsolateGadget(theGadget,theWindow,theRequester);
  237.    RefreshGadgets(theGadget,theWindow,theRequester);
  238.    if (NotSelected)
  239.    {
  240.       ClearGadgFlag(theGadget,SELECTED);
  241.       if (GadgFlagNotSet(theGadget,GADGHIMAGE))
  242.          RefreshGadgets(theGadget,theWindow,theRequester);
  243.    }
  244.    RestoreGadget(theGadget,theWindow,theRequester);
  245. }
  246.  
  247. static struct Gadget *FirstGadget = NULL;
  248. static struct Gadget *NextGadget  = NULL;
  249.  
  250. /*
  251.  *  When gadgets are mutually excluded, they are refreshed to show their
  252.  *  imagery properly selected or unselected.  Unfortunately, refreshing
  253.  *  the complete gadget list toggles the displayed status for gadgets
  254.  *  that use GADGHCOMP or GADGHBOX selection.  To avoid this, mutually
  255.  *  excluded gadgets are updated individually.  First they are isolated
  256.  *  by making the gadget the only one in the window or requester gadget
  257.  *  list (the original pointers are stored in the two variable listed
  258.  *  above), then refreshed.  Finally the gadget list is restored to its
  259.  *  original state using the saved pointers.  This avoids the unwanted
  260.  *  toggling of COMP and BOX gadgets, and removes the annoying flicker
  261.  *  produced when IMAGE gadgets are refreshed unnecessarily.
  262.  *
  263.  *  This is a little sneaky, but it should be relatively safe, since
  264.  *  it happens very quickly, and the integrity of the rest of the list is
  265.  *  not destroyed during the procedure.  An alternate approach would be to
  266.  *  mark all the COMP and BOX gadgets in the list as being not SELECTED,
  267.  *  then do the refresh; finally, restore the SELECT flag to the proper
  268.  *  gadgets again.  If you don't use COMP or BOX selection, then you can
  269.  *  remove the bodies of these two routines (just make them empty brackets).
  270.  */
  271.  
  272. IsolateGadget(theGadget,theWindow,theRequester)
  273. struct Gadget *theGadget;
  274. struct Window *theWindow;
  275. struct Requester *theRequester;
  276. {
  277.    NextGadget = theGadget->NextGadget;
  278.    if (isReqGadg(theGadget))
  279.    {
  280.       FirstGadget = theRequester->ReqGadget;
  281.       theRequester->ReqGadget = theGadget;
  282.    } else {
  283.       FirstGadget = theWindow->FirstGadget;
  284.       theWindow->FirstGadget = theGadget;
  285.    }
  286.    theGadget->NextGadget = NULL;
  287. }
  288.  
  289. RestoreGadget(theGadget,theWindow,theRequester)
  290. struct Gadget *theGadget;
  291. struct Window *theWindow;
  292. struct Requester *theRequester;
  293. {
  294.    theGadget->NextGadget = NextGadget;
  295.    if (isReqGadg(theGadget))
  296.       theRequester->ReqGadget = FirstGadget;
  297.    else
  298.       theWindow->FirstGadget = FirstGadget;
  299. }
  300.  
  301. ExcludeMxGadgets(theGadget,theWindow,theRequester,Exclude,Enable,Disable)
  302. struct Gadget *theGadget;
  303. struct Window *theWindow;
  304. struct Requester *theRequester;
  305. LONG Exclude, Enable, Disable;
  306. {
  307.    struct Gadget *CheckGadget = (isReqGadg(theGadget)) ?
  308.                                    theRequester->ReqGadget :
  309.                                    theWindow->FirstGadget;
  310.    LONG MutualExclude = Exclude | Enable | Disable;
  311.    LONG CheckExclude;
  312.  
  313. /*
  314.  *  Check each gadget in the window or requester list:
  315.  *  If it is excluded (or enabled or diabled) by the selected gadget,
  316.  *      and it is not the selected gadget then:
  317.  *    if it is selected and excluded then unselect it;
  318.  *    if it is an ON-OFF gadget (i.e., it can be enabled or disabled), then:
  319.  *      if it is disabled by the selected gadget and
  320.  *         it's not already disabled, then disable it;
  321.  *      if it is enabled by the selected gadget, and
  322.  *         it's currently disabled, then enable it.
  323.  */
  324.  
  325.    if (MutualExclude)
  326.    {
  327.       while (CheckGadget != NULL)
  328.       {
  329.          CheckExclude = CheckGadget->MutualExclude;
  330.          if ((MutualExclude & CheckExclude) &&
  331.             (CheckGadget != theGadget))
  332.          {
  333.             if (isAnySelected(CheckGadget) &&
  334.                (CheckExclude & Exclude))
  335.                   UnSelectGadget(CheckGadget,theWindow,theRequester);
  336.  
  337.             if (MxFlagSet(CheckGadget,MXGADGONOFF))
  338.             {
  339.                if ((CheckExclude & Disable) &&
  340.                   (isNotDisabled(CheckGadget)))
  341.                      MxOffGadget(CheckGadget,theWindow,theRequester);
  342.  
  343.                if ((CheckExclude & Enable) &&
  344.                   (isDisabled(CheckGadget)))
  345.                      MxOnGadget(CheckGadget,theWindow,theRequester);
  346.             }
  347.          }
  348.          CheckGadget = CheckGadget->NextGadget;
  349.       }
  350.    }
  351. }
  352.