home *** CD-ROM | disk | FTP | other *** search
/ Aminet 33 / Aminet 33 - October 1999.iso / Aminet / dev / gui / ClassFree_src.lha / ClassFree_src / CFlistclass / class.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-11-08  |  9.1 KB  |  341 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/gadgetclass.h>
  9. #include <intuition/imageclass.h>
  10. #include <dos/dos.h>
  11. #include "class.h"
  12. #include "CFlist.h"
  13. #include "CFtexti.h"
  14. #ifdef DEBUG
  15.  #include "debug_protos.h"
  16.  extern APTR console;
  17. #endif
  18.  
  19. Class *initclass(struct classbase *base)
  20. {
  21.   Class *cl;
  22.  
  23.   if(cl = MakeClass(CFlistClassName,GADGETCLASS,NULL,
  24.         sizeof(struct objectdata),NULL))
  25.   {
  26.     cl->cl_Dispatcher.h_Entry = hookEntry;
  27.     cl->cl_Dispatcher.h_SubEntry = dispatcher;
  28.     AddClass(cl);
  29.   }
  30.   base->cl = cl;
  31.  
  32.   return(cl);
  33. }
  34.  
  35. BOOL removeclass(struct classbase *base)
  36. {
  37.   BOOL result;
  38.  
  39.   if(result = FreeClass(base->cl)) base->cl = NULL;
  40.  
  41.   return(result);
  42. }
  43.  
  44. ULONG dispatcher(Class *cl,Object *o,Msg msg)
  45. {
  46.   switch(msg->MethodID)
  47.   {
  48.     case OM_NEW:
  49.       return(newobject(cl,o,msg));
  50.     case OM_DISPOSE:
  51.       return(dispose(cl,o));
  52.     case OM_GET:
  53.       return(getattrs(cl,o,msg));
  54.     case OM_SET:
  55.     case OM_UPDATE:
  56.       return(setattrs(cl,o,msg));
  57.     case GM_HITTEST:
  58.       return(GMR_GADGETHIT);
  59.     case GM_GOACTIVE:
  60.       return(GMR_MEACTIVE);//activate(cl,o,msg));
  61.     case GM_HANDLEINPUT:
  62.       return(handleinput(cl,o,msg));
  63.     case GM_GOINACTIVE:
  64.       return(NULL);//return(inactivate(cl,o,msg));
  65.     case GM_RENDER:
  66.       return(render(cl,o,msg));
  67.     default:
  68.       return(DoSuperMethodA(cl,o,msg));
  69.   }
  70. }
  71.  
  72. ULONG newobject(Class *cl,Object *o,Msg msg)
  73. {
  74.   struct TagItem *intags = ((struct opSet *)msg)->ops_AttrList;
  75.   struct Gadget *lst;
  76.   struct Node *nd;
  77.   ULONG bor;
  78.   Tag filter[] = {GA_Highlight,GA_Border,TAG_DONE};
  79.  
  80.   bor = GetTagData(GA_Border,TRUE,intags);
  81.   FilterTagItems(intags,filter,TAGFILTER_NOT);
  82.   if(lst = (struct Gadget *)DoSuperMethodA(cl,o,msg))
  83.   {
  84.     struct objectdata *dt = (struct objectdata *)INST_DATA(cl,lst);
  85.  
  86.     dt->lcnt = 0;
  87.     /* List always sends IDCMP_GADGETUP */
  88.     lst->Activation |= GACT_RELVERIFY;
  89.     if(dt->labels = (struct List *)GetTagData(CFL_Labels,NULL,intags))
  90.     {
  91.       nd = dt->labels->lh_Head;
  92.       do
  93.       {
  94.         dt->lcnt++;
  95.         nd = nd->ln_Succ;
  96.       }
  97.       while(nd->ln_Succ);
  98.     }
  99.     dt->top = GetTagData(CFL_Top,NULL,intags);
  100.     dt->sel = GetTagData(CFL_Selected,~0L,intags);
  101.     if(!(dt->labimg = (struct Image *)NewObject(NULL,CFtextiClassName,
  102.             IA_Left, lst->LeftEdge+2, IA_Top, lst->TopEdge+2,
  103.             IA_Width, lst->Width-4,
  104.             IA_Data, NULL,
  105.             TAG_DONE))) goto error;
  106.     dt->labimg->NextImage = NULL;
  107.     if(GetTagData(CFL_ReadOnly,FALSE,intags)) dt->flags = LIST_READONLY;
  108.     if(bor)
  109.     {
  110.       if(!(dt->border = (struct Image *)NewObject(NULL,FRAMEICLASS,
  111.               IA_Left, lst->LeftEdge, IA_Top, lst->TopEdge,
  112.               IA_Width, lst->Width, IA_Height, lst->Height,
  113.               IA_FrameType, FRAME_BUTTON,
  114.               IA_EdgesOnly, TRUE,
  115.               TAG_DONE))) goto error;
  116.     }
  117.     else dt->border = NULL;
  118.     return((ULONG)lst);
  119.   }
  120.   error:
  121.   DoMethod((Object *)lst,OM_DISPOSE);
  122.   return(NULL);
  123. }
  124.  
  125. ULONG dispose(Class *cl,Object *o)
  126. {
  127.   struct objectdata *dt = (struct objectdata *)INST_DATA(cl,o);
  128.  
  129.   if(dt->border) DisposeObject((Object *)dt->border);
  130.   if(dt->labimg) DisposeObject((Object *)dt->labimg);
  131.   DoSuperMethod(cl,o,OM_DISPOSE);
  132.   return(NULL);
  133. }
  134.  
  135. ULONG getattrs(Class *cl,Object *o,Msg msg)
  136. {
  137.   struct opGet *get = (struct opGet *)msg;
  138.   struct objectdata *dt = (struct objectdata *)INST_DATA(cl,o);
  139.  
  140.   if(get->opg_AttrID == CFL_Visible)
  141.   {
  142.     *(get->opg_Storage) = dt->vis;
  143.     return((ULONG)dt->vis);
  144.   }
  145.   return(DoSuperMethodA(cl,o,msg));
  146. }
  147.  
  148. ULONG setattrs(Class *cl,Object *o,Msg msg)
  149. {
  150.   struct opSet *set = (struct opSet *)msg,imgset;
  151.   struct TagItem *attrs = set->ops_AttrList,*attr,tag[5];
  152.   struct objectdata *dt = (struct objectdata *)INST_DATA(cl,o);
  153.   ULONG count = 0;
  154.  
  155.   if(attr = FindTagItem(GA_Left,attrs))
  156.   {
  157.     tag[count].ti_Tag = IA_Left; tag[count].ti_Data = attr->ti_Data;
  158.     count++;
  159.   }
  160.   if(attr = FindTagItem(GA_Top,attrs))
  161.   {
  162.     tag[count].ti_Tag = IA_Top; tag[count].ti_Data = attr->ti_Data;
  163.     count++;
  164.   }
  165.   if(count)
  166.   {
  167.     tag[count].ti_Tag = TAG_DONE;
  168.     imgset.MethodID = OM_SET;
  169.     imgset.ops_AttrList = tag;
  170.     imgset.ops_GInfo = NULL;
  171.     DoMethodA((Object *)dt->border,(Msg)&imgset);
  172.     count = 0;
  173.     if(tag[count].ti_Tag == IA_Left) tag[count++].ti_Data += 2;
  174.     if(tag[count].ti_Tag == IA_Top) tag[count++].ti_Data += 2;
  175.     DoMethodA((Object *)dt->labimg,(Msg)&imgset);
  176.   }
  177.   if(attr = FindTagItem(CFL_Top,attrs))
  178.   {
  179.     struct opUpdate *upd = (struct opUpdate *)msg;
  180.     struct gpRender rend;
  181.  
  182.     dt->top = attr->ti_Data;
  183.     if(set->MethodID==OM_UPDATE&&upd->opu_Flags&OPUF_INTERIM)
  184.     {
  185.       rend.MethodID = GM_RENDER;
  186.       rend.gpr_GInfo = set->ops_GInfo;
  187.       rend.gpr_RPort = ObtainGIRPort(set->ops_GInfo);
  188.       rend.gpr_Redraw = GREDRAW_REDRAW;
  189.       DoMethodA(o,(Msg)&rend);
  190.       ReleaseGIRPort(rend.gpr_RPort);
  191.     }
  192.   }
  193.   return(DoSuperMethodA(cl,o,msg));
  194. }
  195.  
  196.  
  197. ULONG activate(Class *cl,Object *o,Msg msg)
  198. {
  199.   return(GMR_MEACTIVE);
  200. }
  201.  
  202. ULONG handleinput(Class *cl,Object *o,Msg msg)
  203. {
  204.   struct gpInput *input = (struct gpInput *)msg;
  205.   struct objectdata *dt = (struct objectdata *)INST_DATA(cl,o);
  206.   struct Gadget *lst = (struct Gadget *)o;
  207.   struct gpRender rend;
  208.   WORD my = input->gpi_Mouse.Y,rely = my-2,pos;
  209.  
  210.   if(input->gpi_IEvent->ie_Class == IECLASS_RAWMOUSE)
  211.   {
  212.     if(rely<0) rely = 0;
  213.     if(rely>=dt->labimg->Height*dt->vis) rely = dt->labimg->Height*dt->vis-1;
  214.     pos = rely/dt->labimg->Height+dt->top;
  215.     if(pos!=dt->sel)
  216.     {
  217.       dt->nsel = pos;
  218.       dt->flags |= LIST_CHANGED;
  219.       rend.MethodID = GM_RENDER;
  220.       rend.gpr_GInfo = input->gpi_GInfo;
  221.       rend.gpr_RPort = ObtainGIRPort(input->gpi_GInfo);
  222.       rend.gpr_Redraw = GREDRAW_UPDATE;
  223.       DoMethodA(o,(Msg)&rend);
  224.       ReleaseGIRPort(rend.gpr_RPort);
  225.     }
  226.     if(input->gpi_IEvent->ie_Code == SELECTUP)
  227.     {
  228.       if(dt->flags&LIST_CHANGED)
  229.       {
  230.         *(input->gpi_Termination) = dt->sel;
  231.         dt->flags &=~LIST_CHANGED;
  232.         return(GMR_NOREUSE|GMR_VERIFY);
  233.       }
  234.       else return(GMR_NOREUSE);
  235.     }
  236.   }
  237.   return(GMR_MEACTIVE);
  238. }
  239.  
  240. ULONG inactivate(Class *cl,Object *o,Msg msg)
  241. {
  242.   return(NULL);
  243. }
  244.  
  245. ULONG render(Class *cl,Object *o,Msg msg)
  246. {
  247.   struct objectdata *dt = (struct objectdata *)INST_DATA(cl,o);
  248.   struct gpRender *rend = (struct gpRender *)msg;
  249.   struct impDraw draw;
  250.   struct opSet set;
  251.   struct TagItem tag[5];
  252.   struct Gadget *lst = (struct Gadget *)o;
  253.   struct Node *node;
  254.   ULONG index = 0;
  255.  
  256.   draw.MethodID = IM_DRAW;
  257.   draw.imp_RPort = rend->gpr_RPort;
  258.   draw.imp_Offset.X = 0; draw.imp_Offset.Y = 0;
  259.   draw.imp_DrInfo = rend->gpr_GInfo->gi_DrInfo;
  260.   set.MethodID = OM_SET;
  261.   set.ops_GInfo = NULL;
  262.   set.ops_AttrList = tag;
  263.   tag[0].ti_Tag = IA_Data; tag[0].ti_Data = NULL;
  264.   tag[1].ti_Tag = TAG_DONE;
  265.   if(rend->gpr_Redraw==GREDRAW_REDRAW)
  266.   {
  267.     /* First redraw border */
  268.     if(dt->flags&LIST_READONLY) draw.imp_State = IDS_SELECTED;
  269.     else draw.imp_State = IDS_NORMAL;
  270.     DoMethodA((Object *)dt->border,(Msg)&draw);
  271.     /* Set and draw labimg to initialize it's Height attribute */
  272.     DoMethodA((Object *)dt->labimg,(Msg)&set);
  273.     DoMethodA((Object *)dt->labimg,(Msg)&draw);
  274.     /* Calculate max number of visible labels */
  275.     dt->vis = (lst->Height-4)/dt->labimg->Height;
  276.     /* Unattractive but effective way to adjust top value */
  277.     while(dt->lcnt-dt->top<dt->vis&&dt->top>0) dt->top--;
  278.     /* Find first label node */
  279.     node = dt->labels->lh_Head;
  280.     index = 0;
  281.     while(index++<dt->top) node = node->ln_Succ;
  282.     /* Draw all labels */
  283.     index = 0;
  284.     do
  285.     {
  286.       tag[0].ti_Data = (ULONG)node->ln_Name;
  287.       DoMethodA((Object *)dt->labimg,(Msg)&set);
  288.       if(index+dt->top==dt->sel) draw.imp_State = IDS_SELECTED;
  289.       else draw.imp_State = IDS_NORMAL;
  290.       DoMethodA((Object *)dt->labimg,(Msg)&draw);
  291.       draw.imp_Offset.Y += dt->labimg->Height;
  292.       index++;
  293.       node = node->ln_Succ;
  294.     }
  295.     while(node->ln_Succ&&index<dt->vis);
  296.     /* Adjust number of visible labels so handleinput dowsn't draw empty labels */
  297.     if(index<dt->vis) dt->vis = index;
  298.   }
  299.   else
  300.   {
  301. #ifdef DEBUG
  302.   DLprintf(console,"Render update\n");
  303. #endif
  304.     /* Because of set/update dt->sel can be outside visible area
  305.        and should not be drawn */
  306.     if(dt->sel-dt->top>=0&&dt->sel-dt->top<dt->vis)
  307.     {
  308.       /* Find and set label text */
  309.       index = 0;
  310.       node = dt->labels->lh_Head;
  311.       while(index++<dt->sel) node = node->ln_Succ;
  312.       tag[0].ti_Data = (ULONG)node->ln_Name;
  313.       DoMethodA((Object *)dt->labimg,(Msg)&set);
  314.       /* Draw old select label */
  315.       draw.imp_Offset.Y = (dt->sel-dt->top)*dt->labimg->Height;
  316.       draw.imp_State = IDS_NORMAL;
  317.       DoMethodA((Object *)dt->labimg,(Msg)&draw);
  318.     }
  319.     /* Find and set label text */
  320.     index = 0;
  321.     node = dt->labels->lh_Head;
  322.     while(index++<dt->nsel) node = node->ln_Succ;
  323.     tag[0].ti_Data = (ULONG)node->ln_Name;
  324.     DoMethodA((Object *)dt->labimg,(Msg)&set);
  325.     /* Draw new select label */
  326.     draw.imp_Offset.Y = (dt->nsel-dt->top)*dt->labimg->Height;
  327.     draw.imp_State = IDS_SELECTED;
  328.     DoMethodA((Object *)dt->labimg,(Msg)&draw);
  329.     dt->sel = dt->nsel; dt->nsel = NULL;
  330.   }
  331.   return(1);
  332. }
  333.  
  334.  
  335.  
  336.  
  337.  
  338.  
  339.  
  340.  
  341.