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

  1. #include <classes/BOOPSI/gadgets.h>
  2.  
  3. #pragma -
  4. #include <pragma/utility_lib.h>
  5. #include <clib/alib_protos.h>
  6. #include <pragma/intuition_lib.h>
  7. #include <pragma/graphics_lib.h>
  8. #include <pragma/layers_lib.h>
  9. #pragma +
  10.  
  11. static WORD Level2Gfx(UWORD lv, WORD l, WORD w)
  12. {
  13.     return ((((ULONG) w) * lv) / 65536) + l;
  14. }
  15.  
  16. static UWORD Gfx2Level(WORD g, WORD l, WORD w)
  17. {
  18.     if (w)
  19.         return (((ULONG) (g - l)) * 65536) / w;
  20.     return 0;
  21. }
  22.  
  23. struct InstanceData {
  24.     UWORD level;
  25.     BOOL horiz;
  26.     WORD gfxlevel;
  27.     WORD dist;
  28.     BOOL autoredraw;
  29.     WORD leftMargin;
  30.     WORD rightMargin;
  31. };
  32.  
  33. SplitviewClass::SplitviewClass()
  34.     : BoopsiClass(sizeof(struct InstanceData),(ULONG (*)()) &dispatcher,GADGETCLASS,NULL)
  35. {
  36. }
  37.  
  38. ULONG SplitviewClass::dispatcher(Class *cl, Object *o, Msg msg)
  39. {
  40.     struct InstanceData *data;
  41.     ULONG retval = FALSE;
  42.     switch (msg->MethodID)
  43.     {
  44.         case OM_NEW:
  45.         {
  46.             Object *object;
  47.             if (object = (Object *) DoSuperMethodA(cl,o,msg))
  48.             {
  49.                 data = (struct InstanceData *) INST_DATA(cl,object);
  50.                 data->level = 32768;
  51.                 data->horiz = FALSE;
  52.                 data->autoredraw = FALSE;
  53.                 data->leftMargin = 0;
  54.                 data->rightMargin = 1;
  55.                 TagItemCursorC tic(((struct opSet *) msg)->ops_AttrList);
  56.                 while (!tic.isDone()) {
  57.                     /* register */ ULONG ticData = tic.itemData();
  58.                     switch (tic.itemTag())
  59.                     {
  60.                         case SVA_Level:
  61.                             data->level = (UWORD) ticData;
  62.                             break;
  63.                         case SVA_Horiz:
  64.                             data->horiz = (BOOL) ticData;
  65.                             break;
  66.                         case SVA_AutoRedraw:
  67.                             data->autoredraw = (BOOL) ticData;
  68.                             break;
  69.                         case SVA_LUMargin:
  70.                             data->leftMargin = (WORD) ticData;
  71.                             break;
  72.                         case SVA_RBMargin:
  73.                             data->rightMargin = (WORD) ticData;
  74.                             break;
  75.                         default:
  76.                             break;
  77.                     };
  78.                     tic.next();
  79.                 };
  80.                 retval = (ULONG) object;
  81.             };
  82.             break;
  83.         };
  84.         case OM_DISPOSE:
  85.         {
  86.             data = (struct InstanceData *) INST_DATA(cl,o);
  87.             retval = DoSuperMethodA(cl,o,msg);
  88.             break;
  89.         };
  90.         case OM_GET:
  91.         {
  92.             data = (struct InstanceData *) INST_DATA(cl,o);
  93.             switch (((struct opGet *) msg)->opg_AttrID)
  94.             {
  95.                 case GA_Left:
  96.                     *(((struct opGet *) msg)->opg_Storage) = ((struct Gadget *) o)->LeftEdge;
  97.                     retval = TRUE;
  98.                     break;
  99.                 case GA_Top:
  100.                     *(((struct opGet *) msg)->opg_Storage) = ((struct Gadget *) o)->TopEdge;
  101.                     retval = TRUE;
  102.                     break;
  103.                 case GA_Width:
  104.                     *(((struct opGet *) msg)->opg_Storage) = ((struct Gadget *) o)->Width;
  105.                     retval = TRUE;
  106.                     break;
  107.                 case GA_Height:
  108.                     *(((struct opGet *) msg)->opg_Storage) = ((struct Gadget *) o)->Height;
  109.                     retval = TRUE;
  110.                     break;
  111.                 case SVA_Level:
  112.                     *(((struct opGet *) msg)->opg_Storage) = data->level;
  113.                     retval = TRUE;
  114.                     break;
  115.                 case SVA_LUSize:
  116.                     if (data->horiz)
  117.                         *(((struct opGet *) msg)->opg_Storage) = Level2Gfx(data->level, 0, ((struct Gadget *) o)->Height) - 1
  118.                     else
  119.                         *(((struct opGet *) msg)->opg_Storage) = Level2Gfx(data->level, 0, ((struct Gadget *) o)->Width) - 1;
  120.                     retval = TRUE;
  121.                     break;
  122.                 case SVA_RBSize:
  123.                     if (data->horiz)
  124.                         *(((struct opGet *) msg)->opg_Storage) = ((struct Gadget *) o)->Height - Level2Gfx(data->level, 0, ((struct Gadget *) o)->Height) - 2
  125.                     else
  126.                         *(((struct opGet *) msg)->opg_Storage) = ((struct Gadget *) o)->Width - Level2Gfx(data->level, 0, ((struct Gadget *) o)->Width) - 2;
  127.                     retval = TRUE;
  128.                     break;
  129.                 case SVA_RBPosition:
  130.                     if (data->horiz)
  131.                         *(((struct opGet *) msg)->opg_Storage) = Level2Gfx(data->level, 0, ((struct Gadget *) o)->Height) + 2
  132.                     else
  133.                         *(((struct opGet *) msg)->opg_Storage) = Level2Gfx(data->level, 0, ((struct Gadget *) o)->Width) + 2;
  134.                     retval = TRUE;
  135.                     break;
  136.                 case SVA_LUMargin:
  137.                     *(((struct opGet *) msg)->opg_Storage) = data->leftMargin;
  138.                     retval = TRUE;
  139.                     break;
  140.                 case SVA_RBMargin:
  141.                     *(((struct opGet *) msg)->opg_Storage) = data->rightMargin;
  142.                     retval = TRUE;
  143.                     break;
  144.                 default:
  145.                     retval = DoSuperMethodA(cl,o,msg);
  146.                     break;
  147.             };
  148.             break;
  149.         };
  150.         case OM_SET:
  151.         {
  152.             data = (struct InstanceData *) INST_DATA(cl,o);
  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 SVA_Level:
  159.                         data->level = (UWORD) ticData;
  160.                         break;
  161.                     case SVA_LUMargin:
  162.                         data->leftMargin = (WORD) ticData;
  163.                         break;
  164.                     case SVA_RBMargin:
  165.                         data->rightMargin = (WORD) ticData;
  166.                         break;
  167.                     default:
  168.                         break;
  169.                 };
  170.                 tic.next();
  171.             };
  172.             retval = DoSuperMethodA(cl,o,msg);
  173.             break;
  174.         };
  175.         case GM_RENDER:
  176.         {
  177.             data = (struct InstanceData *) INST_DATA(cl,o);
  178.             retval = render(cl,(struct Gadget *) o,
  179.                 (struct gpRender *) msg,data);
  180.             break;
  181.         };
  182.         case GM_HITTEST:
  183.         {
  184.             data = (struct InstanceData *) INST_DATA(cl,o);
  185.             struct Gadget *g = (struct Gadget *) o;
  186.             struct gpHitTest *m = (struct gpHitTest *) msg;
  187.             if (data->horiz)
  188.             {
  189.                 WORD gfxlevel = Level2Gfx(data->level, 0, g->Height);
  190.                 if (m->gpht_Mouse.Y >= gfxlevel &&
  191.                         m->gpht_Mouse.Y <= gfxlevel+1)
  192.                     retval = GMR_GADGETHIT
  193.                 else
  194.                     retval = 0;
  195.             }
  196.             else {
  197.                 WORD gfxlevel = Level2Gfx(data->level, 0, g->Width);
  198.                 if (m->gpht_Mouse.X >= gfxlevel &&
  199.                         m->gpht_Mouse.X <= gfxlevel+1)
  200.                 {
  201.                     retval = GMR_GADGETHIT;
  202.                 }
  203.                 else
  204.                     retval = 0;
  205.             };
  206.             break;
  207.         };
  208.         case GM_GOACTIVE:
  209.         {
  210.             data = (struct InstanceData *) INST_DATA(cl,o);
  211.             if (((struct gpInput *) msg)->gpi_IEvent)
  212.             {
  213.                 ((struct Gadget *) msg)->Flags |= GFLG_SELECTED;
  214.                 if (data->horiz)
  215.                 {
  216.                     data->gfxlevel = Level2Gfx(data->level,
  217.                         0, ((struct Gadget *) o)->Height);
  218.                     data->dist = data->gfxlevel - ((struct gpInput *) msg)->gpi_Mouse.Y;
  219.                 }
  220.                 else {
  221.                     data->gfxlevel = Level2Gfx(data->level,
  222.                         0, ((struct Gadget *) o)->Width);
  223.                     data->dist = data->gfxlevel - ((struct gpInput *) msg)->gpi_Mouse.X;
  224.                 };
  225.                 render(cl,(struct Gadget *) o,
  226.                     (struct gpRender *) msg,data,TRUE);
  227.                 struct GadgetInfo *ginfo = ((struct gpInput *) msg)->gpi_GInfo;
  228.                 LockLayers(&ginfo->gi_Screen->LayerInfo);
  229.                 LockLayerInfo(&ginfo->gi_Screen->LayerInfo);
  230.                 renderXor(cl,(struct Gadget *) o,
  231.                     (struct gpRender *) msg,data);
  232.                 retval = GMR_MEACTIVE;
  233.             }
  234.             else
  235.                 retval = GMR_NOREUSE;
  236.             break;
  237.         };
  238.         case GM_GOINACTIVE:
  239.         {
  240.             data = (struct InstanceData *) INST_DATA(cl,o);
  241.             renderXor(cl,(struct Gadget *) o,
  242.                 (struct gpRender *) msg,data);
  243.             UnlockLayerInfo(&((struct gpGoInactive *) msg)->
  244.                 gpgi_GInfo->gi_Screen->LayerInfo);
  245.             UnlockLayers(&((struct gpGoInactive *) msg)->
  246.                 gpgi_GInfo->gi_Screen->LayerInfo);
  247.             ((struct Gadget *) o)->Flags &= ~GFLG_SELECTED;
  248.             clear(cl,(struct Gadget *) o,
  249.                 (struct gpRender *) msg,data);
  250.             if (data->horiz)
  251.             {
  252.                 data->level = Gfx2Level(data->gfxlevel,
  253.                     0, ((struct Gadget *) o)->Height);
  254.             }
  255.             else {
  256.                 data->level = Gfx2Level(data->gfxlevel,
  257.                     0, ((struct Gadget *) o)->Width);
  258.             };
  259.             if (data->autoredraw)
  260.                 render(cl,(struct Gadget *) o,
  261.                     (struct gpRender *) msg,data);
  262.             break;
  263.         };
  264.         case GM_HANDLEINPUT:
  265.         {
  266.             data = (struct InstanceData *) INST_DATA(cl,o);
  267.             struct gpInput *gpi = (struct gpInput *) msg;
  268.             struct InputEvent *ie = gpi->gpi_IEvent;
  269.             BOOL mouseOverGadget = ((gpi->gpi_Mouse.X >= 0) &&
  270.                     (gpi->gpi_Mouse.X < ((struct Gadget *) o)->Width) &&
  271.                     (gpi->gpi_Mouse.Y >= 0) &&
  272.                     (gpi->gpi_Mouse.Y < ((struct Gadget *) o)->Height));
  273.             switch (ie->ie_Class)
  274.             {
  275.                 case IECLASS_RAWMOUSE:
  276.                 {
  277.                     WORD nlevel;
  278.                     if (data->horiz)
  279.                     {
  280.                         WORD y;
  281.                         if (gpi->gpi_Mouse.Y < data->leftMargin)
  282.                             y = data->leftMargin
  283.                         else if (gpi->gpi_Mouse.Y >= ((struct Gadget *) o)->Height - data->rightMargin)
  284.                             y = ((struct Gadget *) o)->Height - data->rightMargin
  285.                         else
  286.                             y = gpi->gpi_Mouse.Y;
  287.                         nlevel = y + data->dist;
  288.                     }
  289.                     else {
  290.                         WORD x;
  291.                         if (gpi->gpi_Mouse.X < data->leftMargin)
  292.                             x = data->leftMargin
  293.                         else if (gpi->gpi_Mouse.X >= ((struct Gadget *) o)->Width - data->rightMargin)
  294.                             x = ((struct Gadget *) o)->Width - data->rightMargin
  295.                         else
  296.                             x = gpi->gpi_Mouse.X;
  297.                         nlevel = x + data->dist;
  298.                     };
  299.                     if (data->gfxlevel != nlevel)
  300.                     {
  301.                         renderXor(cl,(struct Gadget *) o,
  302.                             (struct gpRender *) msg,data);
  303.                         data->gfxlevel = nlevel;
  304.                         renderXor(cl,(struct Gadget *) o,
  305.                             (struct gpRender *) msg,data);
  306.                     };
  307.                     switch (ie->ie_Code)
  308.                     {
  309.                         case SELECTUP:
  310.                             if (mouseOverGadget)
  311.                             {
  312.                                 retval = GMR_NOREUSE | GMR_VERIFY;
  313.                             }
  314.                             else {
  315.                                 retval = GMR_NOREUSE;
  316.                             };
  317.                             break;
  318.                         case MENUDOWN:
  319.                             retval = GMR_REUSE;
  320.                             break;
  321.                         default:
  322.                             retval = GMR_MEACTIVE;
  323.                             break;
  324.                     };
  325.                     break;
  326.                 };
  327.                 default:
  328.                     retval = GMR_MEACTIVE;
  329.                     break;
  330.             };
  331.             break;
  332.         };
  333.         default:
  334.         {
  335.             retval = DoSuperMethodA(cl,o,msg);
  336.             break;
  337.         };
  338.     };
  339.     return retval;
  340. }
  341.  
  342. ULONG SplitviewClass::render(Class *cl, struct Gadget *g,
  343.     struct gpRender *msg, struct InstanceData *data, BOOL selected)
  344. {
  345.     struct RastPort *rp;
  346.     struct GadgetInfo *ginfo;
  347.     if (msg->MethodID == OM_SET || msg->MethodID == OM_UPDATE)
  348.         ginfo = ((struct opSet *) msg)->ops_GInfo
  349.     else
  350.         ginfo = msg->gpr_GInfo;
  351.     if (!ginfo)
  352.         return FALSE;
  353.     UWORD *pens = ginfo->gi_DrInfo->dri_Pens;
  354.     if (msg->MethodID == GM_RENDER)
  355.         rp = msg->gpr_RPort
  356.     else
  357.         rp = ObtainGIRPort(ginfo);
  358.     if (rp)
  359.     {
  360.         LONG shine = pens[SHINEPEN];
  361.         LONG shadow = pens[SHADOWPEN];
  362.         if (selected)
  363.         {
  364.             LONG j = shine;
  365.             shine = shadow;
  366.             shadow = j;
  367.         };
  368.         if (data->horiz)
  369.         {
  370.             WORD y = Level2Gfx(data->level,g->TopEdge,g->Height);
  371.             if (y >= g->TopEdge + g->Height - 1)
  372.                 y = g->TopEdge + g->Height - 2;
  373.             SetDrMd(rp,JAM1);
  374.             SetAPen(rp,shine);
  375.             Move(rp,g->LeftEdge + g->Width - 2, y);
  376.             Draw(rp,g->LeftEdge, y);
  377.             Draw(rp,g->LeftEdge, y + 1);
  378.             SetAPen(rp,shadow);
  379.             Move(rp,g->LeftEdge + 1, y + 1);
  380.             Draw(rp,g->LeftEdge + g->Width - 1, y + 1);
  381.             Draw(rp,g->LeftEdge + g->Width - 1, y);
  382.         }
  383.         else {
  384.             WORD x = Level2Gfx(data->level,g->LeftEdge,g->Width);
  385.             if (x >= g->LeftEdge + g->Width - 1)
  386.                 x = g->LeftEdge + g->Width - 2;
  387.             SetDrMd(rp,JAM1);
  388.             SetAPen(rp,shine);
  389.             Move(rp,x,g->TopEdge + g->Height - 2);
  390.             Draw(rp,x,g->TopEdge);
  391.             Draw(rp,x + 1,g->TopEdge);
  392.             SetAPen(rp,shadow);
  393.             Move(rp,x + 1,g->TopEdge + 1);
  394.             Draw(rp,x + 1,g->TopEdge + g->Height - 1);
  395.             Draw(rp,x,g->TopEdge + g->Height - 1);
  396.         };
  397.         if (msg->MethodID != GM_RENDER)
  398.             ReleaseGIRPort(rp);
  399.         return TRUE;
  400.     };
  401.     return FALSE;
  402. }
  403.  
  404. ULONG SplitviewClass::renderXor(Class *cl, struct Gadget *g,
  405.     struct gpRender *msg, struct InstanceData *data)
  406. {
  407.     struct RastPort *rp;
  408.     struct GadgetInfo *ginfo;
  409.     if (msg->MethodID == OM_SET || msg->MethodID == OM_UPDATE)
  410.         ginfo = ((struct opSet *) msg)->ops_GInfo
  411.     else
  412.         ginfo = msg->gpr_GInfo;
  413.     if (!ginfo)
  414.         return FALSE;
  415.     UWORD *pens = ginfo->gi_DrInfo->dri_Pens;
  416.     if (msg->MethodID == GM_RENDER)
  417.         rp = msg->gpr_RPort
  418.     else
  419.         rp = ObtainGIRPort(ginfo);
  420.     if (rp)
  421.     {
  422.         if (data->horiz)
  423.         {
  424.             WORD y = data->gfxlevel;
  425.             if (y >= g->Height - 1)
  426.                 y = g->Height - 2;
  427.             SetDrMd(rp,COMPLEMENT);
  428.             RectFill(rp,g->LeftEdge,g->TopEdge + y,
  429.                 g->LeftEdge + g->Width - 1, g->TopEdge + y + 1);
  430.         }
  431.         else {
  432.             WORD x = data->gfxlevel;
  433.             if (x >= g->Width - 1)
  434.                 x = g->Width - 2;
  435.             SetDrMd(rp,COMPLEMENT);
  436.             RectFill(rp,g->LeftEdge + x,g->TopEdge,
  437.                 g->LeftEdge + x + 1, g->TopEdge + g->Height - 1);
  438.         };
  439.         if (msg->MethodID != GM_RENDER)
  440.             ReleaseGIRPort(rp);
  441.         return TRUE;
  442.     };
  443.     return FALSE;
  444. }
  445.  
  446. ULONG SplitviewClass::clear(Class *cl, struct Gadget *g,
  447.     struct gpRender *msg, struct InstanceData *data)
  448. {
  449.     struct RastPort *rp;
  450.     struct GadgetInfo *ginfo;
  451.     if (msg->MethodID == OM_SET || msg->MethodID == OM_UPDATE)
  452.         ginfo = ((struct opSet *) msg)->ops_GInfo
  453.     else
  454.         ginfo = msg->gpr_GInfo;
  455.     if (!ginfo)
  456.         return FALSE;
  457.     UWORD *pens = ginfo->gi_DrInfo->dri_Pens;
  458.     if (msg->MethodID == GM_RENDER)
  459.         rp = msg->gpr_RPort
  460.     else
  461.         rp = ObtainGIRPort(ginfo);
  462.     if (rp)
  463.     {
  464.         if (data->horiz)
  465.         {
  466.             WORD y = Level2Gfx(data->level,0,g->Height);
  467.             if (y >= g->Height - 1)
  468.                 y = g->Height - 2;
  469.             EraseRect(rp,g->LeftEdge,g->TopEdge + y,
  470.                 g->LeftEdge + g->Width - 1, g->TopEdge + y + 1);
  471.         }
  472.         else {
  473.             WORD x = Level2Gfx(data->level,0,g->Width);
  474.             if (x >= g->Width - 1)
  475.                 x = g->Width - 2;
  476.             EraseRect(rp,g->LeftEdge + x,g->TopEdge,
  477.                 g->LeftEdge + x + 1, g->TopEdge + g->Height - 1);
  478.         };
  479.         if (msg->MethodID != GM_RENDER)
  480.             ReleaseGIRPort(rp);
  481.         return TRUE;
  482.     };
  483.     return FALSE;
  484. }
  485.  
  486. // *************************************************************
  487.  
  488. SplitviewClass BSplitviewC::svc;
  489.  
  490. // *************************************************************
  491.  
  492.