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

  1. #include <classes/BOOPSI/gadgets.h>
  2. #include <classes/BOOPSI/boopsilib.h>
  3.  
  4. #include <intuition/icclass.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. #define ACTIVE_None      0
  15. #define ACTIVE_List      1
  16. #define ACTIVE_VScroller 2
  17. #define ACTIVE_HScroller 3
  18.  
  19. struct InstanceData {
  20.     Object *list;
  21.     Object *vscroller;
  22.     Object *hscroller;
  23.     BOOL vertscroller;
  24.     BOOL horizscroller;
  25.     ULONG activePart;
  26.     Object *frame;
  27. };
  28.  
  29. ListviewClass::ListviewClass()
  30.     : BoopsiClass(sizeof(struct InstanceData),(ULONG (*)()) &dispatcher,GADGETCLASS,NULL)
  31. {
  32. }
  33.  
  34. static struct TagItem vert2list[] = {
  35.     { ASCA_Top, LSA_Top },
  36.     { TAG_END}};
  37. static struct TagItem horiz2list[] = {
  38.     { ASCA_Top, LSA_HorizLeft },
  39.     { TAG_END}};
  40. static struct TagItem list2vert[] = {
  41.     { LSA_Top, ASCA_Top },
  42.     { LSA_Visible, ASCA_Visible },
  43.     { LSA_Total, ASCA_Total },
  44.     { TAG_END}};
  45. static struct TagItem list2horiz[] = {
  46.     { LSA_HorizLeft, ASCA_Top },
  47.     { LSA_HorizWidth, ASCA_Visible },
  48.     { LSA_HorizTotal, ASCA_Total },
  49.     { TAG_END}};
  50.  
  51. ULONG ListviewClass::dispatcher(Class *cl, Object *o, Msg msg)
  52. {
  53.     struct InstanceData *data;
  54.     ULONG retval = FALSE;
  55.     switch (msg->MethodID)
  56.     {
  57.         case OM_NEW:
  58.         {
  59.             Object *object;
  60.             if (object = (Object *) DoSuperMethodA(cl,o,msg))
  61.             {
  62.                 data = (struct InstanceData *) INST_DATA(cl,object);
  63.                 data->vscroller = NULL;
  64.                 data->hscroller = NULL;
  65.                 data->vertscroller = TRUE;
  66.                 data->horizscroller = TRUE;
  67.                 data->activePart = ACTIVE_None;
  68.                 data->frame = NULL;
  69.                 BOOL privframe = TRUE;
  70.                 BOOL readonly = FALSE;
  71.                 TagItemCursorC tic(((struct opSet *) msg)->ops_AttrList);
  72.                 while (!tic.isDone()) {
  73.                     /* register */ ULONG ticData = tic.itemData();
  74.                     switch (tic.itemTag())
  75.                     {
  76.                         case LVA_VertScroller:
  77.                             data->vertscroller = (BOOL) ticData;
  78.                             break;
  79.                         case LVA_HorizScroller:
  80.                             data->horizscroller = (BOOL) ticData;
  81.                             break;
  82.                         case LSA_Frame:
  83.                             privframe = (ticData == NULL);
  84.                             break;
  85.                         case LSA_ReadOnly:
  86.                             readonly = (BOOL) ticData;
  87.                             break;
  88.                         default:
  89.                             break;
  90.                     };
  91.                     tic.next();
  92.                 };
  93.                 if (privframe)
  94.                 {
  95.                     data->frame = (Object *) NewObject(NULL,FRAMEICLASS,
  96.                         IA_EdgesOnly,TRUE,
  97.                         IA_Recessed,readonly,
  98.                         TAG_END);
  99.                 };
  100.                 WORD right = 0;
  101.                 WORD bottom = 0;
  102.                 if (data->horizscroller)
  103.                 {
  104.                     bottom = 10;
  105.                 };
  106.                 if (data->vertscroller)
  107.                 {
  108.                     right = 18;
  109.                     data->vscroller = (Object *) NewObject(ListviewClass::scrollerclass(),NULL,
  110.                         GA_Top,((struct Gadget *) object)->TopEdge,
  111.                         GA_Left,((struct Gadget *) object)->LeftEdge +
  112.                             ((struct Gadget *) object)->Width - right,
  113.                         GA_Width,right,
  114.                         GA_Height,((struct Gadget *) object)->Height - bottom,
  115.                         ASCA_Arrows,TRUE,
  116.                         ASCA_Freedom,FREEVERT,
  117.                         ICA_MAP, vert2list,
  118.                         TAG_END);
  119.                 };
  120.                 if (data->horizscroller)
  121.                 {
  122.                     data->hscroller = (Object *) NewObject(ListviewClass::scrollerclass(),NULL,
  123.                         GA_Top,((struct Gadget *) object)->TopEdge +
  124.                             ((struct Gadget *) object)->Height - bottom,
  125.                         GA_Left,((struct Gadget *) object)->LeftEdge,
  126.                         GA_Width,((struct Gadget *) object)->Width - right,
  127.                         GA_Height,bottom,
  128.                         ASCA_Arrows,TRUE,
  129.                         ASCA_Freedom,FREEHORIZ,
  130.                         ICA_MAP, horiz2list,
  131.                         TAG_END);
  132.                 };
  133.                 data->list = (Object *) NewObject(ListviewClass::listclass(),NULL,
  134.                     LSA_Frame,data->frame,
  135.                     TAG_MORE,((struct opSet *) msg)->ops_AttrList);
  136.                 if (data->list)
  137.                 {
  138.                     SetAttrs(data->list,
  139.                         GA_Width,((struct Gadget *) object)->Width - right,
  140.                         GA_Height,((struct Gadget *) object)->Height - bottom,
  141.                         ICA_TARGET, data->vscroller,
  142.                         ICA_MAP, list2vert,
  143.                         LSA_HorizTarget, data->hscroller,
  144.                         LSA_HorizMap, list2horiz,
  145.                         TAG_END);
  146.                 };
  147.                 if (data->vscroller)
  148.                 {
  149.                     SetAttrs(data->vscroller,
  150.                         ICA_TARGET, data->list,
  151.                         TAG_END);
  152.                 };
  153.                 if (data->hscroller)
  154.                 {
  155.                     SetAttrs(data->hscroller,
  156.                         ICA_TARGET, data->list,
  157.                         TAG_END);
  158.                 };
  159.                 retval = (ULONG) object;
  160.             };
  161.             break;
  162.         };
  163.         case OM_DISPOSE:
  164.         {
  165.             data = (struct InstanceData *) INST_DATA(cl,o);
  166.             if (data->list)
  167.                 DisposeObject(data->list);
  168.             if (data->vscroller)
  169.                 DisposeObject(data->vscroller);
  170.             if (data->hscroller)
  171.                 DisposeObject(data->hscroller);
  172.             if (data->frame)
  173.                 DisposeObject(data->frame);
  174.             retval = DoSuperMethodA(cl,o,msg);
  175.             break;
  176.         };
  177.         case OM_GET:
  178.         {
  179.             data = (struct InstanceData *) INST_DATA(cl,o);
  180.             switch (((struct opGet *) msg)->opg_AttrID)
  181.             {
  182.                 case GA_Left:
  183.                     *(((struct opGet *) msg)->opg_Storage) = ((struct Gadget *) o)->LeftEdge;
  184.                     retval = TRUE;
  185.                     break;
  186.                 case GA_Top:
  187.                     *(((struct opGet *) msg)->opg_Storage) = ((struct Gadget *) o)->TopEdge;
  188.                     retval = TRUE;
  189.                     break;
  190.                 case GA_Width:
  191.                     *(((struct opGet *) msg)->opg_Storage) = ((struct Gadget *) o)->Width;
  192.                     retval = TRUE;
  193.                     break;
  194.                 case GA_Height:
  195.                     *(((struct opGet *) msg)->opg_Storage) = ((struct Gadget *) o)->Height;
  196.                     retval = TRUE;
  197.                     break;
  198.                 case LVA_VertScroller:
  199.                     *(((struct opGet *) msg)->opg_Storage) = (ULONG) data->vertscroller;
  200.                     retval = TRUE;
  201.                     break;
  202.                 case LVA_HorizScroller:
  203.                     *(((struct opGet *) msg)->opg_Storage) = (ULONG) data->horizscroller;
  204.                     retval = TRUE;
  205.                     break;
  206.                 default:
  207.                     if (!(retval = DoSuperMethodA(cl,o,msg)))
  208.                     {
  209.                         if (data->list)
  210.                             retval = DoMethodA(data->list,(Msg) msg);
  211.                     };
  212.                     break;
  213.             };
  214.             break;
  215.         };
  216.         case OM_SET:
  217.         {
  218.             data = (struct InstanceData *) INST_DATA(cl,o);
  219.             BOOL recalcIt = FALSE;
  220.             TagItemCursorC tic(((struct opSet *) msg)->ops_AttrList);
  221.             while (!tic.isDone()) {
  222.                 /* register */ ULONG ticData = tic.itemData();
  223.                 switch (tic.itemTag())
  224.                 {
  225.                     case GA_Top:
  226.                         recalcIt = TRUE;
  227.                         break;
  228.                     case GA_Left:
  229.                         recalcIt = TRUE;
  230.                         break;
  231.                     case GA_Width:
  232.                         recalcIt = TRUE;
  233.                         break;
  234.                     case GA_Height:
  235.                         recalcIt = TRUE;
  236.                         break;
  237.                     case LSA_ReadOnly:
  238.                         if (data->frame)
  239.                         {
  240.                             SetAttrs(data->frame,
  241.                                 IA_Recessed,ticData,
  242.                                 TAG_END);
  243.                         };
  244.                         break;
  245.                     default:
  246.                         break;
  247.                 };
  248.                 tic.next();
  249.             };
  250.             retval = DoSuperMethodA(cl,o,msg);
  251.             if (recalcIt)
  252.             {
  253.                 WORD right = 0;
  254.                 WORD bottom = 0;
  255.                 if (data->hscroller)
  256.                 {
  257.                     bottom = 10;
  258.                 };
  259.                 if (data->vscroller)
  260.                 {
  261.                     right = 18;
  262.                     SetGInfoAttrs(data->vscroller,((struct opSet *) msg)->ops_GInfo,
  263.                         GA_Top,((struct Gadget *) o)->TopEdge,
  264.                         GA_Left,((struct Gadget *) o)->LeftEdge +
  265.                             ((struct Gadget *) o)->Width - right,
  266.                         GA_Width,right,
  267.                         GA_Height,((struct Gadget *) o)->Height - bottom,
  268.                         TAG_END);
  269.                 };
  270.                 if (data->hscroller)
  271.                 {
  272.                     SetGInfoAttrs(data->hscroller,((struct opSet *) msg)->ops_GInfo,
  273.                         GA_Top,((struct Gadget *) o)->TopEdge +
  274.                             ((struct Gadget *) o)->Height - bottom,
  275.                         GA_Left,((struct Gadget *) o)->LeftEdge,
  276.                         GA_Width,((struct Gadget *) o)->Width - right,
  277.                         GA_Height,bottom,
  278.                         TAG_END);
  279.                 };
  280.                 if (data->list)
  281.                 {
  282.                     DoMethodA(data->list,(Msg) msg);
  283.                     SetGInfoAttrs(data->list,((struct opSet *) msg)->ops_GInfo,
  284.                         GA_Top,((struct Gadget *) o)->TopEdge,
  285.                         GA_Left,((struct Gadget *) o)->LeftEdge,
  286.                         GA_Width,((struct Gadget *) o)->Width - right,
  287.                         GA_Height,((struct Gadget *) o)->Height - bottom,
  288.                         TAG_END);
  289.                 };
  290.             }
  291.             else {
  292.                 if (data->list)
  293.                 {
  294.                     DoMethodA(data->list,(Msg) msg);
  295.                 };
  296.             };
  297.             break;
  298.         };
  299.         case GM_RENDER:
  300.         {
  301.             data = (struct InstanceData *) INST_DATA(cl,o);
  302.             retval = render(cl,(struct Gadget *) o,
  303.                 (struct gpRender *) msg,data);
  304.             break;
  305.         };
  306.         case GM_HITTEST:
  307.         {
  308.             retval = GMR_GADGETHIT;
  309.             break;
  310.         };
  311.         case GM_GOACTIVE:
  312.         {
  313.             data = (struct InstanceData *) INST_DATA(cl,o);
  314.             struct gpInput *gpi = (struct gpInput *) msg;
  315.             if (data->list && gpi->gpi_Mouse.X >= 0 &&
  316.                 gpi->gpi_Mouse.X < ((struct Gadget *) data->list)->Width &&
  317.                 gpi->gpi_Mouse.Y >= 0 &&
  318.                 gpi->gpi_Mouse.Y < ((struct Gadget *) data->list)->Height)
  319.             {
  320.                 ((struct Gadget *) o)->Flags |= GFLG_SELECTED;
  321.                 data->activePart = ACTIVE_List;
  322.                 retval = DoMethodA(data->list,(Msg) msg);
  323.             }
  324.             else if (data->vscroller &&
  325.                 gpi->gpi_Mouse.X >= ((struct Gadget *) o)->Width - ((struct Gadget *) data->vscroller)->Width &&
  326.                 gpi->gpi_Mouse.X < ((struct Gadget *) o)->Width &&
  327.                 gpi->gpi_Mouse.Y >= 0 &&
  328.                 gpi->gpi_Mouse.Y < ((struct Gadget *) data->vscroller)->Height)
  329.             {
  330.                 ((struct Gadget *) o)->Flags |= GFLG_SELECTED;
  331.                 data->activePart = ACTIVE_VScroller;
  332.                 gpi->gpi_Mouse.X -= ((struct Gadget *) o)->Width -
  333.                     ((struct Gadget *) data->vscroller)->Width;
  334.                 retval = DoMethodA(data->vscroller,(Msg) msg);
  335.             }
  336.             else if (data->hscroller && gpi->gpi_Mouse.X >= 0 &&
  337.                 gpi->gpi_Mouse.X < ((struct Gadget *) data->hscroller)->Width &&
  338.                 gpi->gpi_Mouse.Y >= ((struct Gadget *) o)->Height - ((struct Gadget *) data->hscroller)->Height &&
  339.                 gpi->gpi_Mouse.Y < ((struct Gadget *) o)->Height)
  340.             {
  341.                 ((struct Gadget *) o)->Flags |= GFLG_SELECTED;
  342.                 data->activePart = ACTIVE_HScroller;
  343.                 gpi->gpi_Mouse.Y -= ((struct Gadget *) o)->Height -
  344.                     ((struct Gadget *) data->hscroller)->Height;
  345.                 retval = DoMethodA(data->hscroller,(Msg) msg);
  346.             }
  347.             else
  348.                 retval = GMR_NOREUSE;
  349.             break;
  350.         };
  351.         case GM_GOINACTIVE:
  352.         {
  353.             data = (struct InstanceData *) INST_DATA(cl,o);
  354.             ((struct Gadget *) o)->Flags &= ~GFLG_SELECTED;
  355.             switch (data->activePart)
  356.             {
  357.                 case ACTIVE_List:
  358.                     retval = DoMethodA(data->list,(Msg) msg);
  359.                     break;
  360.                 case ACTIVE_VScroller:
  361.                     retval = DoMethodA(data->vscroller,(Msg) msg);
  362.                     break;
  363.                 case ACTIVE_HScroller:
  364.                     retval = DoMethodA(data->hscroller,(Msg) msg);
  365.                     break;
  366.             };
  367.             data->activePart = ACTIVE_None;
  368.             break;
  369.         };
  370.         case GM_HANDLEINPUT:
  371.         {
  372.             data = (struct InstanceData *) INST_DATA(cl,o);
  373.             struct gpInput *gpi = (struct gpInput *) msg;
  374.             switch (data->activePart)
  375.             {
  376.                 case ACTIVE_List:
  377.                     retval = DoMethodA(data->list,(Msg) msg);
  378.                     break;
  379.                 case ACTIVE_VScroller:
  380.                     gpi->gpi_Mouse.X -= ((struct Gadget *) o)->Width -
  381.                         ((struct Gadget *) data->vscroller)->Width;
  382.                     retval = DoMethodA(data->vscroller,(Msg) msg);
  383.                     break;
  384.                 case ACTIVE_HScroller:
  385.                     gpi->gpi_Mouse.Y -= ((struct Gadget *) o)->Height -
  386.                         ((struct Gadget *) data->hscroller)->Height;
  387.                     retval = DoMethodA(data->hscroller,(Msg) msg);
  388.                     break;
  389.             };
  390.             break;
  391.         };
  392.         default:
  393.         {
  394.             retval = DoSuperMethodA(cl,o,msg);
  395.             break;
  396.         };
  397.     };
  398.     return retval;
  399. }
  400.  
  401. ULONG ListviewClass::render(Class *cl, struct Gadget *g,
  402.     struct gpRender *msg, struct InstanceData *data)
  403. {
  404.     struct RastPort *rp;
  405.     struct GadgetInfo *ginfo;
  406.     if (msg->MethodID == OM_SET || msg->MethodID == OM_UPDATE)
  407.         ginfo = ((struct opSet *) msg)->ops_GInfo
  408.     else
  409.         ginfo = msg->gpr_GInfo;
  410.     if (!ginfo)
  411.         return TRUE;
  412.     UWORD *pens = ginfo->gi_DrInfo->dri_Pens;
  413.     if (msg->MethodID == GM_RENDER)
  414.         rp = msg->gpr_RPort
  415.     else
  416.         rp = ObtainGIRPort(ginfo);
  417.     if (rp)
  418.     {
  419.         if (data->activePart == ACTIVE_None || data->activePart == ACTIVE_List)
  420.         {
  421.             if (data->list)
  422.                 DoMethodA(data->list,(Msg) msg);
  423.         };
  424.         if (data->activePart == ACTIVE_None || data->activePart == ACTIVE_VScroller)
  425.         {
  426.             if (data->vscroller)
  427.                 DoMethodA(data->vscroller,(Msg) msg);
  428.         };
  429.         if (data->activePart == ACTIVE_None || data->activePart == ACTIVE_HScroller)
  430.         {
  431.             if (data->hscroller)
  432.                 DoMethodA(data->hscroller,(Msg) msg);
  433.         };
  434.         if (msg->MethodID != GM_RENDER)
  435.             ReleaseGIRPort(rp);
  436.         return TRUE;
  437.     };
  438.     return FALSE;
  439. }
  440.  
  441. ListClass ListviewClass::lic;
  442. ArrowScrollerClass ListviewClass::asc;
  443.  
  444. // *************************************************************
  445.  
  446. ListviewClass BListviewC::lc;
  447.  
  448. // *************************************************************
  449.  
  450.