home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Programming / C / OTL-MC7.DMS / in.adf / classsource.lha / ClassSource / BOOPSI / gadgets / checkbox.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-12  |  9.5 KB  |  408 lines

  1. #include <classes/BOOPSI/gadgets.h>
  2. #include <classes/BOOPSI/boopsilib.h>
  3.  
  4. #pragma -
  5. #include <pragma/utility_lib.h>
  6. #include <clib/alib_protos.h>
  7. #include <pragma/intuition_lib.h>
  8. #include <pragma/graphics_lib.h>
  9. #pragma +
  10. #include <graphics/gfxmacros.h>
  11. #include <string.h>
  12.  
  13. struct InstanceData {
  14.     struct TextAttr *tattr;
  15.     struct TextFont *font;
  16.     ULONG labelplace;
  17.     WORD leftborder;
  18.     WORD rightborder;
  19.     WORD topborder;
  20.     WORD bottomborder;
  21.     BOOL readonly;
  22.     UBYTE labelmark;
  23.     struct LabelText *label;
  24. };
  25.  
  26. CheckboxClass::CheckboxClass()
  27.     : BoopsiClass(sizeof(struct InstanceData),(ULONG (*)()) &dispatcher,GADGETCLASS,NULL)
  28. {
  29. }
  30.  
  31. ULONG CheckboxClass::dispatcher(Class *cl, Object *o, Msg msg)
  32. {
  33.     struct InstanceData *data;
  34.     ULONG retval = FALSE;
  35.     switch (msg->MethodID)
  36.     {
  37.         case OM_NEW:
  38.         {
  39.             Object *object;
  40.             if (object = (Object *) DoSuperMethodA(cl,o,msg))
  41.             {
  42.                 data = (struct InstanceData *) INST_DATA(cl,object);
  43.                 data->tattr = NULL;
  44.                 data->font = NULL;
  45.                 data->labelplace = CB_LabelRight;
  46.                 data->leftborder = 0;
  47.                 data->rightborder = 0;
  48.                 data->topborder = 0;
  49.                 data->bottomborder = 0;
  50.                 data->readonly = FALSE;
  51.                 data->labelmark = '_';
  52.                 TagItemCursorC tic(((struct opSet *) msg)->ops_AttrList);
  53.                 while (!tic.isDone()) {
  54.                     /* register */ ULONG ticData = tic.itemData();
  55.                     switch (tic.itemTag())
  56.                     {
  57.                         case CBA_Font:
  58.                             data->tattr = (struct TextAttr *) ticData;
  59.                             break;
  60.                         case CBA_LabelPlace:
  61.                             data->labelplace = (ULONG) ticData;
  62.                             break;
  63.                         case CBA_ReadOnly:
  64.                             data->readonly = (BOOL) ticData;
  65.                             break;
  66.                         case CBA_LabelMark:
  67.                             data->labelmark = (UBYTE) ticData;
  68.                             break;
  69.                         default:
  70.                             break;
  71.                     };
  72.                     tic.next();
  73.                 };
  74.                 if (data->tattr)
  75.                 {
  76.                     data->font = OpenFont(data->tattr);
  77.                 };
  78.                 data->label = AllocLText(
  79.                     (STRPTR) ((struct Gadget *) object)->GadgetText,
  80.                     data->tattr,1,0,JAM2,data->labelmark);
  81.                 calcBorders(cl,(struct Gadget *) object,data);
  82.                 retval = (ULONG) object;
  83.             };
  84.             break;
  85.         };
  86.         case OM_DISPOSE:
  87.         {
  88.             data = (struct InstanceData *) INST_DATA(cl,o);
  89.             if (data->font)
  90.                 CloseFont(data->font);
  91.             FreeLText(data->label);
  92.             retval = DoSuperMethodA(cl,o,msg);
  93.             break;
  94.         };
  95.         case OM_GET:
  96.         {
  97.             data = (struct InstanceData *) INST_DATA(cl,o);
  98.             switch (((struct opGet *) msg)->opg_AttrID)
  99.             {
  100.                 case GA_Left:
  101.                     *(((struct opGet *) msg)->opg_Storage) = ((struct Gadget *) o)->LeftEdge;
  102.                     retval = TRUE;
  103.                     break;
  104.                 case GA_Top:
  105.                     *(((struct opGet *) msg)->opg_Storage) = ((struct Gadget *) o)->TopEdge;
  106.                     retval = TRUE;
  107.                     break;
  108.                 case GA_Width:
  109.                     *(((struct opGet *) msg)->opg_Storage) = ((struct Gadget *) o)->Width;
  110.                     retval = TRUE;
  111.                     break;
  112.                 case GA_Height:
  113.                     *(((struct opGet *) msg)->opg_Storage) = ((struct Gadget *) o)->Height;
  114.                     retval = TRUE;
  115.                     break;
  116.                 case GA_Selected:
  117.                     *(((struct opGet *) msg)->opg_Storage) =
  118.                         (ULONG) (((struct Gadget *) o)->Flags & GFLG_SELECTED) != 0;
  119.                     break;
  120.                 case CBA_Font:
  121.                     *(((struct opGet *) msg)->opg_Storage) = (ULONG) data->tattr;
  122.                     retval = TRUE;
  123.                     break;
  124.                 case CBA_LabelPlace:
  125.                     *(((struct opGet *) msg)->opg_Storage) = (ULONG) data->labelplace;
  126.                     retval = TRUE;
  127.                     break;
  128.                 case CBA_LeftBorder:
  129.                     *(((struct opGet *) msg)->opg_Storage) = (ULONG) data->leftborder;
  130.                     retval = TRUE;
  131.                     break;
  132.                 case CBA_RightBorder:
  133.                     *(((struct opGet *) msg)->opg_Storage) = (ULONG) data->rightborder;
  134.                     retval = TRUE;
  135.                     break;
  136.                 case CBA_TopBorder:
  137.                     *(((struct opGet *) msg)->opg_Storage) = (ULONG) data->topborder;
  138.                     retval = TRUE;
  139.                     break;
  140.                 case CBA_BottomBorder:
  141.                     *(((struct opGet *) msg)->opg_Storage) = (ULONG) data->bottomborder;
  142.                     retval = TRUE;
  143.                     break;
  144.                 case CBA_AutoWidth:
  145.                     *(((struct opGet *) msg)->opg_Storage) =
  146.                         (ULONG) calcWidth(cl,(struct Gadget *) o, data);
  147.                     retval = TRUE;
  148.                     break;
  149.                 case CBA_AutoHeight:
  150.                     *(((struct opGet *) msg)->opg_Storage) =
  151.                         (ULONG) calcHeight(cl,(struct Gadget *) o, data);
  152.                     retval = TRUE;
  153.                     break;
  154.                 case CBA_ReadOnly:
  155.                     *(((struct opGet *) msg)->opg_Storage) = (ULONG) data->readonly;
  156.                     retval = TRUE;
  157.                     break;
  158.                 case CBA_LabelMark:
  159.                     *(((struct opGet *) msg)->opg_Storage) = (ULONG) data->labelmark;
  160.                     retval = TRUE;
  161.                     break;
  162.                 default:
  163.                     retval = DoSuperMethodA(cl,o,msg);
  164.                     break;
  165.             };
  166.             break;
  167.         };
  168.         case OM_SET:
  169.         {
  170.             data = (struct InstanceData *) INST_DATA(cl,o);
  171.             BOOL redrawIt = FALSE;
  172.             TagItemCursorC tic(((struct opSet *) msg)->ops_AttrList);
  173.             while (!tic.isDone()) {
  174.                 /* register */ ULONG ticData = tic.itemData();
  175.                 switch (tic.itemTag())
  176.                 {
  177.                     case GA_Selected:
  178.                         redrawIt = TRUE;
  179.                         break;
  180.                     case CBA_Font:
  181.                         data->tattr = (struct TextAttr *) ticData;
  182.                         if (data->font)
  183.                         {
  184.                             CloseFont(data->font);
  185.                             data->font = NULL;
  186.                         };
  187.                         if (data->tattr)
  188.                             data->font = OpenFont(data->tattr);
  189.                         ChangeLTextFont(data->label,data->tattr);
  190.                         calcBorders(cl,(struct Gadget *) o, data);
  191.                         break;
  192.                     case CBA_ReadOnly:
  193.                         data->readonly = (BOOL) ticData;
  194.                         redrawIt = TRUE;
  195.                         break;
  196.                     default:
  197.                         break;
  198.                 };
  199.                 tic.next();
  200.             };
  201.             retval = DoSuperMethodA(cl,o,msg);
  202.             if (redrawIt)
  203.             {
  204.                 render(cl,(struct Gadget *) o,
  205.                     (struct gpRender *) msg,data);
  206.             };
  207.             break;
  208.         };
  209.         case GM_RENDER:
  210.         {
  211.             data = (struct InstanceData *) INST_DATA(cl,o);
  212.             retval = render(cl,(struct Gadget *) o,
  213.                 (struct gpRender *) msg,data);
  214.             break;
  215.         };
  216.         case GM_HITTEST:
  217.         {
  218.             retval = GMR_GADGETHIT;
  219.             break;
  220.         };
  221.         case GM_GOACTIVE:
  222.         {
  223.             data = (struct InstanceData *) INST_DATA(cl,o);
  224.             if (((struct gpInput *) msg)->gpi_IEvent && !data->readonly)
  225.             {
  226.                 ((struct Gadget *) o)->Flags ^= GFLG_SELECTED;
  227.                 render(cl,(struct Gadget *) o,
  228.                     (struct gpRender *) msg,data);
  229.                 retval = GMR_MEACTIVE;
  230.             }
  231.             else
  232.                 retval = GMR_NOREUSE;
  233.             break;
  234.         };
  235.         case GM_GOINACTIVE:
  236.         {
  237.             data = (struct InstanceData *) INST_DATA(cl,o);
  238.             render(cl,(struct Gadget *) o,
  239.                 (struct gpRender *) msg,data);
  240.             break;
  241.         };
  242.         case GM_HANDLEINPUT:
  243.         {
  244.             data = (struct InstanceData *) INST_DATA(cl,o);
  245.             struct gpInput *gpi = (struct gpInput *) msg;
  246.             struct InputEvent *ie = gpi->gpi_IEvent;
  247.             switch (ie->ie_Class)
  248.             {
  249.                 case IECLASS_RAWMOUSE:
  250.                 {
  251.                     switch (ie->ie_Code)
  252.                     {
  253.                         case SELECTUP:
  254.                             retval = GMR_NOREUSE | GMR_VERIFY;
  255.                             break;
  256.                         case MENUDOWN:
  257.                             retval = GMR_REUSE;
  258.                             break;
  259.                         default:
  260.                             retval = GMR_MEACTIVE;
  261.                             break;
  262.                     };
  263.                     break;
  264.                 };
  265.                 default:
  266.                     retval = GMR_MEACTIVE;
  267.                     break;
  268.             };
  269.             break;
  270.         };
  271.         default:
  272.         {
  273.             retval = DoSuperMethodA(cl,o,msg);
  274.             break;
  275.         };
  276.     };
  277.     return retval;
  278. }
  279.  
  280. ULONG CheckboxClass::render(Class *cl, struct Gadget *g,
  281.     struct gpRender *msg, struct InstanceData *data)
  282. {
  283.     static UWORD ditherData[] = { 0x1111,0x4444 };
  284.  
  285.     struct RastPort *rp;
  286.     struct GadgetInfo *ginfo;
  287.     if (msg->MethodID == OM_SET || msg->MethodID == OM_UPDATE)
  288.         ginfo = ((struct opSet *) msg)->ops_GInfo
  289.     else
  290.         ginfo = msg->gpr_GInfo;
  291.     if (!ginfo)
  292.         return TRUE;
  293.     UWORD *pens = ginfo->gi_DrInfo->dri_Pens;
  294.     if (msg->MethodID == GM_RENDER)
  295.         rp = msg->gpr_RPort
  296.     else
  297.         rp = ObtainGIRPort(ginfo);
  298.     if (rp)
  299.     {
  300.         Object *checker = (Object *) NewObject(NULL,SYSICLASS,
  301.             IA_Left,0,
  302.             IA_Top,0,
  303.             IA_Width,g->Width,
  304.             IA_Height,g->Height,
  305.             SYSIA_DrawInfo,ginfo->gi_DrInfo,
  306.             SYSIA_ReferenceFont, data->font,
  307.             SYSIA_Size, SYSISIZE_HIRES,
  308.             SYSIA_Which, CHECKIMAGE,
  309.             TAG_END);
  310.         if (checker)
  311.         {
  312.             DrawImageState(rp,(struct Image *) checker,g->LeftEdge,g->TopEdge,
  313.                 g->Flags & GFLG_SELECTED ? IDS_SELECTED : IDS_NORMAL,
  314.                 ginfo->gi_DrInfo);
  315.             DisposeObject(checker);
  316.         };
  317.         if (g->Flags & GFLG_DISABLED)
  318.         {
  319.             SetDrMd(rp,JAM1);
  320.             SetAPen(rp,pens[TEXTPEN]);
  321.             SetAfPt(rp,ditherData,1);
  322.             RectFill(rp,g->LeftEdge, g->TopEdge,
  323.                 g->LeftEdge + g->Width - 1, g->TopEdge + g->Height - 1);
  324.             SetAfPt(rp,NULL,0);
  325.         };
  326.         if (data->font && g->GadgetText)
  327.         {
  328.             ChangeLTextPens(data->label,pens[TEXTPEN],pens[BACKGROUNDPEN],JAM2);
  329.             switch (data->labelplace)
  330.             {
  331.                 case CB_LabelLeft:
  332.                     PrintLText(rp,data->label,
  333.                         g->LeftEdge - data->leftborder, g->TopEdge,
  334.                         data->leftborder, g->Height,
  335.                         STADJUST_Left);
  336.                     break;
  337.                 case CB_LabelRight:
  338.                     PrintLText(rp,data->label,
  339.                         g->LeftEdge + g->Width, g->TopEdge,
  340.                         data->rightborder, g->Height,
  341.                         STADJUST_Right);
  342.                     break;
  343.             };
  344.         };
  345.         if (msg->MethodID != GM_RENDER)
  346.             ReleaseGIRPort(rp);
  347.         return TRUE;
  348.     };
  349.     return FALSE;
  350. }
  351.  
  352. VOID CheckboxClass::calcBorders(Class *cl, struct Gadget *g,
  353.     struct InstanceData *data)
  354. {
  355.     if (data->tattr && g->GadgetText)
  356.     {
  357.         LONG labelwidth = MeasureLText(data->label);
  358.         data->leftborder = 0;
  359.         data->rightborder = 0;
  360.         data->topborder = 0;
  361.         data->bottomborder = 0;
  362.         switch (data->labelplace)
  363.         {
  364.             case CB_LabelLeft:
  365.                 data->leftborder = labelwidth + 4;
  366.                 break;
  367.             case CB_LabelRight:
  368.                 data->rightborder = labelwidth + 4;
  369.                 break;
  370.             default:
  371.                 break;
  372.         };
  373.     };
  374. }
  375.  
  376. WORD CheckboxClass::calcWidth(Class *cl, struct Gadget *g,
  377.     struct InstanceData *data)
  378. {
  379.     if (data->tattr)
  380.     {
  381.         WORD h = data->tattr->ta_YSize;
  382.         if (h < 11)
  383.             h = 11;
  384.         return (h * 26) / 11;
  385.     };
  386.     return 26;
  387. }
  388.  
  389. WORD CheckboxClass::calcHeight(Class *cl, struct Gadget *g,
  390.     struct InstanceData *data)
  391. {
  392.     WORD h = 11;
  393.     if (data->tattr)
  394.     {
  395.         h = data->tattr->ta_YSize;
  396.         if (h < 11)
  397.             h = 11;
  398.     };
  399.     return h;
  400. }
  401.  
  402. // *************************************************************
  403.  
  404. CheckboxClass BCheckboxC::cbc;
  405.  
  406. // *************************************************************
  407.  
  408.