home *** CD-ROM | disk | FTP | other *** search
/ Aminet 33 / Aminet 33 - October 1999.iso / Aminet / dev / gui / ClassFree_src.lha / ClassFree_src / CFscrollerclass / scrollerclass.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-11-08  |  11.4 KB  |  414 lines

  1. /* Sample class  for StormC*/
  2.  
  3. #include <clib/alib_protos.h>
  4. #include <proto/intuition.h>
  5. #include <proto/utility.h>
  6. #include <exec/libraries.h>
  7. #include <intuition/classes.h>
  8. #include <intuition/icclass.h>
  9. #include <dos/dos.h>
  10. #include "class.h"
  11. #include "CFscroller.h"
  12. #include "CFbutton.h"
  13. #ifdef DEBUG
  14.  #include "debug_protos.h"
  15.  extern APTR console;
  16. #endif
  17.  
  18. Class *initclass(struct classbase *base)
  19. {
  20.   Class *cl;
  21.  
  22.   if(cl = MakeClass(CFscrollerClassName,GADGETCLASS,NULL,
  23.         sizeof(struct objectdata),NULL))
  24.   {
  25.     cl->cl_Dispatcher.h_Entry = hookEntry;
  26.     cl->cl_Dispatcher.h_SubEntry = dispatcher;
  27.     AddClass(cl);
  28.   }
  29.   base->cl = cl;
  30.  
  31.   return(cl);
  32. }
  33.  
  34. BOOL removeclass(struct classbase *base)
  35. {
  36.   BOOL result;
  37.  
  38.   if(result = FreeClass(base->cl)) base->cl = NULL;
  39.  
  40.   return(result);
  41. }
  42.  
  43. ULONG dispatcher(Class *cl,Object *o,Msg msg)
  44. {
  45.   switch(msg->MethodID)
  46.   {
  47.     case OM_NEW:
  48.       return(newobject(cl,o,msg));
  49.     case OM_DISPOSE:
  50.       return(dispose(cl,o));
  51.     case OM_SET:
  52.       return(setattrs(cl,o,msg));
  53.     case OM_UPDATE:
  54.       return(update(cl,o,msg));
  55.     case GM_HITTEST:
  56.       return(hittest(cl,o,msg));
  57.     case GM_GOACTIVE:
  58. //      return(handleinput(cl,o,msg));
  59.     case GM_HANDLEINPUT:
  60.       return(handleinput(cl,o,msg));
  61.     case GM_GOINACTIVE:
  62.       return(goinactive(cl,o,msg));
  63.     case GM_RENDER:
  64.       return(render(cl,o,msg));
  65.     default:
  66.       return(DoSuperMethodA(cl,o,msg));
  67.   }
  68. }
  69.  
  70. ULONG newobject(Class *cl,Object *o,Msg msg)
  71. {
  72.   struct TagItem *attrs = ((struct opSet *)msg)->ops_AttrList;
  73.   struct Gadget *scr;
  74.   struct Image *decimg,*incimg;
  75.   struct objectdata *dt;
  76.   struct DrawInfo *dri;
  77.   ULONG size,fdm,dec,inc,total,visible,top;
  78.   WORD x,y,oldfill;
  79.  
  80.   if(scr = (struct Gadget *)DoSuperMethodA(cl,o,msg))
  81.   {
  82.     if(!(dri = (struct DrawInfo *)GetTagData(GA_DrawInfo,NULL,attrs)))
  83.     {
  84.       DoSuperMethod((Class *)o,(Object *)scr,OM_DISPOSE); /* o contains true  */
  85.       return(NULL);                     /* class for OM_NEW */
  86.     }
  87.     dt->rep = 0;
  88.     size = GetTagData(CFSC_Size,SIZE_MEDRES,attrs);
  89.     fdm = GetTagData(CFSC_Freedom,FREEVERT,attrs);
  90.     total = GetTagData(PGA_Total,1,attrs);
  91.     visible = GetTagData(PGA_Visible,1,attrs);
  92.     top = GetTagData(PGA_Top,0,attrs);
  93.     if(fdm == FREEVERT)
  94.     {
  95.       dec = UPIMAGE;
  96.       inc = DOWNIMAGE;
  97.     }
  98.     else
  99.     {
  100.       dec = LEFTIMAGE;
  101.       inc = RIGHTIMAGE;
  102.     }
  103.     dt = INST_DATA(((Class *)o),scr);
  104.     /* Change fill color */
  105.     oldfill = dri->dri_Pens[FILLPEN];
  106.     dri->dri_Pens[FILLPEN] = 0;
  107.     decimg = (struct Image *)NewObject(NULL,SYSICLASS,
  108.             IA_Left, 0, IA_Top, 0,
  109.             SYSIA_Which, dec,
  110.             SYSIA_DrawInfo, dri,
  111.             SYSIA_Size, size,
  112.             TAG_DONE);
  113.     incimg = (struct Image *)NewObject(NULL,SYSICLASS,
  114.             IA_Left, 0, IA_Top, 0,
  115.             SYSIA_Which, inc,
  116.             SYSIA_DrawInfo, dri,
  117.             SYSIA_Size, size,
  118.             TAG_DONE);
  119.     dri->dri_Pens[FILLPEN] = oldfill;
  120.     if(decimg&&incimg)
  121.     {
  122.       if(fdm == FREEVERT)
  123.       {
  124.         scr->Width = decimg->Width;
  125.         x = scr->Width;
  126.         y = scr->Height-decimg->Height*2;
  127.       }
  128.       else
  129.       {
  130.         x = scr->Width-decimg->Width*2;
  131.         scr->Height = decimg->Height;
  132.         y = scr->Height;
  133.       }
  134.       dt->pframe = (struct Image *)NewObject(NULL,FRAMEICLASS,
  135.             IA_Left, scr->LeftEdge, IA_Top, scr->TopEdge,
  136.             IA_Width, x, IA_Height, y,
  137.             IA_FrameType, FRAME_BUTTON,
  138.             TAG_DONE);
  139.       dt->prop = NewObject(NULL,PROPGCLASS,
  140.             GA_Left, scr->LeftEdge+4, GA_Top, scr->TopEdge+2,
  141.             GA_Width, x-8, GA_Height, y-4,
  142.             PGA_Freedom, fdm, PGA_NewLook, TRUE, PGA_Borderless,TRUE,
  143.             PGA_Total, total, PGA_Visible, visible, PGA_Top, top,
  144.             ICA_TARGET, scr,
  145.             GA_ID, 0,
  146.             TAG_DONE);
  147.       if(dt->pframe&&dt->prop)
  148.       {
  149.         if(fdm == FREEVERT) x = 0;
  150.         else y = 0;
  151.         dt->decbtn = NewObject(NULL,CFbuttonClassName,
  152.             GA_Left, scr->LeftEdge+x, GA_Top, scr->TopEdge+y,
  153.             GA_Width, decimg->Width, GA_Height, decimg->Height,
  154.             GA_Image, decimg, GA_Border, FALSE, GA_Highlight, FALSE,
  155.             CFBU_Layout, LAYOUT_IMGREL,
  156.             GA_ID, DECBTN,
  157.             ICA_TARGET, scr,
  158.             TAG_DONE);
  159.         if(fdm == FREEVERT) y += decimg->Height;
  160.         else x += decimg->Width;
  161.         dt->incbtn = NewObject(NULL,CFbuttonClassName,
  162.             GA_Left, scr->LeftEdge+x, GA_Top, scr->TopEdge+y,
  163.             GA_Width, incimg->Width, GA_Height, incimg->Height,
  164.             GA_Image, incimg, GA_Border, FALSE, GA_Highlight, FALSE,
  165.             CFBU_Layout, LAYOUT_IMGREL,
  166.             GA_ID, INCBTN,
  167.             ICA_TARGET, scr,
  168.             TAG_DONE);
  169.         if(dt->decbtn&&dt->incbtn)
  170.         {
  171.           return((ULONG)scr);
  172.         }
  173.         DisposeObject((Object *)dt->decbtn);
  174.         dt->decbtn = NULL;
  175.         DisposeObject((Object *)dt->incbtn);
  176.         dt->incbtn = NULL;
  177.       } /* if(dt->pframe&&dt->prop) */
  178.       DisposeObject((Object *)dt->pframe);
  179.       dt->pframe = NULL;
  180.       DisposeObject((Object *)dt->prop);
  181.       dt->prop = NULL;
  182.     } /* if(decimg&&incimg) */
  183.     DisposeObject((Object *)decimg);
  184.     DisposeObject((Object *)incimg);
  185.     DoMethod((Object *)scr,OM_DISPOSE);
  186.   }
  187.   return(NULL);
  188. }
  189.  
  190. ULONG dispose(Class *cl,Object *o)
  191. {
  192.   struct objectdata *dt = INST_DATA(cl,o);
  193.   ULONG decimg = NULL,incimg = NULL;
  194.  
  195.   if(dt->decbtn)
  196.   {
  197.     if(dt->decbtn->GadgetRender) DisposeObject((Object *)dt->decbtn->GadgetRender);
  198.     DisposeObject((Object *)dt->decbtn);
  199.   }
  200.   if(dt->incbtn)
  201.   {
  202.     if(dt->incbtn->GadgetRender) DisposeObject((Object *)dt->incbtn->GadgetRender);
  203.     DisposeObject((Object *)dt->incbtn);
  204.   }
  205.   DisposeObject((Object *)dt->pframe);
  206.   DisposeObject((Object *)dt->prop);
  207.  
  208.   DoSuperMethod(cl,o,OM_DISPOSE);
  209.   return(NULL);
  210. }
  211.  
  212. ULONG setattrs(Class *cl,Object *o,Msg msg)
  213. {
  214.   struct opSet *set = (struct opSet *)msg;
  215.   struct Gadget *scr = (struct Gadget *)o;
  216.   struct objectdata *dt = (struct objectdata *)INST_DATA(cl,o);
  217.   struct TagItem *attrs = set->ops_AttrList;
  218.   Tag filter[] = {PGA_Top,PGA_Visible,PGA_Total,TAG_DONE};
  219.  
  220.   DoSuperMethodA(cl,o,msg);
  221.   FilterTagItems(attrs,filter,TAGFILTER_AND);
  222.   DoMethodA((Object *)dt->prop,msg);
  223.  
  224.   dt->pframe->LeftEdge = scr->LeftEdge;
  225.   dt->pframe->TopEdge = scr->TopEdge;
  226.   dt->prop->LeftEdge = scr->LeftEdge+4;
  227.   dt->prop->TopEdge = scr->TopEdge+2;
  228.   if(dt->decbtn->LeftEdge == dt->incbtn->LeftEdge)
  229.   {
  230.     dt->decbtn->LeftEdge = scr->LeftEdge;
  231.     dt->incbtn->LeftEdge = scr->LeftEdge;
  232.     dt->decbtn->TopEdge = scr->TopEdge+dt->pframe->Height;
  233.     dt->incbtn->TopEdge = dt->decbtn->TopEdge+dt->decbtn->Height;
  234.   }
  235.   else
  236.   {
  237.     dt->decbtn->TopEdge = scr->TopEdge;
  238.     dt->incbtn->TopEdge = scr->TopEdge;
  239.     dt->decbtn->LeftEdge = scr->LeftEdge+dt->pframe->Width;
  240.     dt->incbtn->LeftEdge = dt->decbtn->LeftEdge+dt->decbtn->Width;
  241.   }
  242.  
  243.   return(NULL);
  244. }
  245.  
  246.  
  247. ULONG update(Class *cl,Object *o,Msg msg)
  248. {
  249.   struct opUpdate *updin = (struct opUpdate *)msg;
  250.   struct objectdata *dt = (struct objectdata *)INST_DATA(cl,o);
  251.   struct Gadget *scr = (struct Gadget *)o;
  252.   struct opUpdate upd;
  253.   struct TagItem tag[5];
  254.   ULONG id,top,newtop;
  255.  
  256.   id = GetTagData(GA_ID,0,updin->opu_AttrList);
  257.   DoMethod((Object *)dt->prop,OM_GET,PGA_Top,&top);
  258.   /* An update message is used for both OM_SET and OM_NOTIFY
  259.      since the messages are so much alike. */
  260.   upd.MethodID = OM_SET;
  261.   upd.opu_AttrList = tag;
  262.   upd.opu_GInfo = updin->opu_GInfo;
  263.   upd.opu_Flags = updin->opu_Flags;
  264.   /*
  265.    Only enter this if its a button update and an interrim message
  266.    Problem: First update message must emulate the gadgetdown message
  267.    */
  268.   if(id>0&&updin->opu_Flags&OPUF_INTERIM)
  269.   {
  270.     /* Delay between first and subsequent updates */
  271.     if(dt->rep==0||dt->rep>4)
  272.     {
  273.       /* Adjust propgadget */
  274.       if(id==DECBTN) newtop = top-1;
  275.       if(id==INCBTN) newtop = top+1;
  276.       tag[0].ti_Tag = PGA_Top; tag[0].ti_Data = newtop;
  277.       tag[1].ti_Tag = TAG_DONE;
  278.       /* Prevent backwards overrun, forwards overrun is prevented
  279.         by propgadget */
  280.       if(newtop!=-1) DoMethodA((Object *)dt->prop,(Msg)&upd);
  281.       /* Initial check to prevent notification messages in case of overrun */
  282.       DoMethod((Object *)dt->prop,OM_GET,PGA_Top,&top);
  283.       /* Delay (only nedded for dt->rep==0) */
  284.       dt->rep++;
  285.     }
  286.     else
  287.     {
  288.       /* Delay in progress */
  289.       dt->rep++;
  290.       return(0);
  291.     }
  292.   }
  293.   /* Only enter if interim message or message from propg */
  294.   if(updin->opu_Flags&OPUF_INTERIM||id==0)
  295.   {
  296.     /* Prevent notification in case of overrun */
  297.     if(id>0&&top!=newtop) return(0);
  298.     /* Notify */
  299.     upd.MethodID = OM_NOTIFY;
  300.     tag[0].ti_Tag = PGA_Top; tag[0].ti_Data = top;
  301.     tag[1].ti_Tag = GA_ID; tag[1].ti_Data = scr->GadgetID;
  302.     tag[2].ti_Tag = TAG_DONE;
  303.     DoMethodA(o,(Msg)&upd);
  304.   }
  305.   return(0);
  306. }
  307.  
  308.  
  309. ULONG hittest(Class *cl,Object *o,Msg msg)
  310. {
  311.   struct gpHitTest *test = (struct gpHitTest *)msg;
  312.   struct Gadget *scr = (struct Gadget *)o;
  313.   struct objectdata *dt = (struct objectdata *)INST_DATA(cl,o);
  314.   WORD x = test->gpht_Mouse.X ,y = test->gpht_Mouse.Y ,gx,gy;
  315.  
  316.   gx = dt->prop->LeftEdge-scr->LeftEdge;
  317.   gy = dt->prop->TopEdge-scr->TopEdge;
  318.   if(x>=gx&&x<=gx+dt->prop->Width&&y>=gy&&y<=gy+dt->prop->Height)
  319.   {
  320.     /* Further tests should be aplied for more complicated gadgets */
  321.     dt->act = (Object *)dt->prop;
  322.     return(GMR_GADGETHIT);
  323.   }
  324.   gx = dt->decbtn->LeftEdge-scr->LeftEdge;
  325.   gy = dt->decbtn->TopEdge-scr->TopEdge;
  326.   if(x>=gx&&x<=gx+dt->decbtn->Width&&y>=gy&&y<=gy+dt->decbtn->Height)
  327.   {
  328.     dt->act = (Object *)dt->decbtn;
  329.     return(GMR_GADGETHIT);
  330.   }
  331.   gx = dt->incbtn->LeftEdge-scr->LeftEdge;
  332.   gy = dt->incbtn->TopEdge-scr->TopEdge;
  333.   if(x>=gx&&x<=gx+dt->incbtn->Width&&y>=gy&&y<=gy+dt->incbtn->Height)
  334.   {
  335.     dt->act = (Object *)dt->incbtn;
  336.     return(GMR_GADGETHIT);
  337.   }
  338.   return(0L);
  339. }
  340.  
  341. ULONG goactive(Class *cl,Object *o,Msg msg)
  342. {
  343.   struct objectdata *dt = (struct objectdata *)INST_DATA(cl,o);
  344.   struct gpInput *in = (struct gpInput *)msg;
  345.   struct Gadget *act = (struct Gadget *)dt->act, *scr = (struct Gadget *)o;
  346.   ULONG result;
  347.   in->gpi_Mouse.X -= act->LeftEdge-scr->LeftEdge;
  348.   in->gpi_Mouse.Y -= act->TopEdge-scr->TopEdge;
  349.   result = DoMethodA(dt->act,msg);
  350.  
  351.   return(result);
  352. }
  353.  
  354. ULONG handleinput(Class *cl,Object *o,Msg msg)
  355. {
  356.   struct objectdata *dt = (struct objectdata *)INST_DATA(cl,o);
  357.   struct gpInput *in = (struct gpInput *)msg;
  358.   struct Gadget *act = (struct Gadget *)dt->act, *scr = (struct Gadget *)o;
  359.   ULONG result,top;
  360.  
  361.   in->gpi_Mouse.X -= act->LeftEdge-scr->LeftEdge;
  362.   in->gpi_Mouse.Y -= act->TopEdge-scr->TopEdge;
  363.   result = DoMethodA(dt->act,msg);
  364.   if(result)
  365.   {
  366.     if(scr->Activation&GACT_RELVERIFY)
  367.     {
  368.       result |= GMR_VERIFY;
  369.       DoMethod((Object *)dt->prop,OM_GET,PGA_Top,&top);
  370.       *(in->gpi_Termination) = (LONG)top;
  371.     }
  372.     else
  373.     {
  374.       result &= ~GMR_VERIFY;
  375.     }
  376.   }
  377.   return(result);
  378. }
  379.  
  380.  
  381. ULONG goinactive(Class *cl,Object *o,Msg msg)
  382. {
  383.   struct objectdata *dt = (struct objectdata *)INST_DATA(cl,o);
  384.   ULONG result;
  385.  
  386.   #ifdef DEBUG
  387.     DLprintf(console,"Goinactive request..\n");
  388.   #endif
  389.   result = DoMethodA(dt->act,msg);
  390.   dt->act = NULL;
  391.   dt->rep = 0;
  392.   return(result);
  393. }
  394.  
  395.  
  396. ULONG render(Class *cl,Object *o,Msg msg)
  397. {
  398.   struct gpRender *rend = (struct gpRender *)msg;
  399.   struct objectdata *dt = INST_DATA(cl,o);
  400.   struct impDraw draw;
  401.  
  402.   draw.MethodID = IM_DRAW;
  403.   draw.imp_RPort = rend->gpr_RPort;
  404.   draw.imp_Offset.X = 0; draw.imp_Offset.Y = 0;
  405.   draw.imp_State = IDS_NORMAL;
  406.   draw.imp_DrInfo = rend->gpr_GInfo->gi_DrInfo;
  407.  
  408.   DoMethodA((Object *)dt->pframe,(Msg)&draw);
  409.   DoMethodA((Object *)dt->prop,msg);
  410.   DoMethodA((Object *)dt->decbtn,msg);
  411.   DoMethodA((Object *)dt->incbtn,msg);
  412.  
  413.   return(1);
  414. }