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

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