home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Programming / C / OTL-MC7.DMS / in.adf / classsource.lha / ClassSource / BOOPSI / gadgets / arrowscroller.c next >
Encoding:
C/C++ Source or Header  |  1995-02-12  |  20.9 KB  |  825 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_Prop      1
  16. #define ACTIVE_UpLeft    2
  17. #define ACTIVE_DownRight 3
  18.  
  19. struct InstanceData {
  20.     BOOL arrows;
  21.     Object *frame;
  22.     WORD arrowheight;
  23.     WORD arrowwidth;
  24.     WORD propbottom;
  25.     WORD propright;
  26.     ULONG freedom;
  27.     UWORD top;
  28.     UWORD visible;
  29.     UWORD total;
  30.     UWORD scrollamount;
  31.     Object *prop;
  32.     ULONG activePart;
  33.     BOOL border;
  34.  
  35.     WORD arrowleft1;
  36.     WORD arrowtop1;
  37.     WORD arrowleft2;
  38.     WORD arrowtop2;
  39.     WORD blOffset;
  40.     WORD btOffset;
  41.     WORD bwOffset;
  42.     WORD bhOffset;
  43. };
  44.  
  45. ArrowScrollerClass::ArrowScrollerClass()
  46.     : BoopsiClass(sizeof(struct InstanceData),(ULONG (*)()) &dispatcher,GADGETCLASS,NULL)
  47. {
  48. }
  49.  
  50. ULONG ArrowScrollerClass::dispatcher(Class *cl, Object *o, Msg msg)
  51. {
  52.     struct InstanceData *data;
  53.     ULONG retval = FALSE;
  54.     switch (msg->MethodID)
  55.     {
  56.         case OM_NEW:
  57.         {
  58.             Object *object;
  59.             if (object = (Object *) DoSuperMethodA(cl,o,msg))
  60.             {
  61.                 data = (struct InstanceData *) INST_DATA(cl,object);
  62.                 data->arrows = TRUE;
  63.                 data->arrowheight = 0;
  64.                 data->arrowwidth = 0;
  65.                 data->freedom = FREEVERT;
  66.                 data->top = 0;
  67.                 data->visible = 0;
  68.                 data->total = 0;
  69.                 data->scrollamount = 1;
  70.                 data->activePart = ACTIVE_None;
  71.                 data->border = TRUE;
  72.                 WORD otop = 0;
  73.                 WORD oleft = 0;
  74.                 WORD oheight = 0;
  75.                 WORD owidth = 0;
  76.                 BOOL orborder = FALSE;
  77.                 BOOL olborder = FALSE;
  78.                 BOOL otborder = FALSE;
  79.                 BOOL obborder = FALSE;
  80.                 TagItemCursorC tic(((struct opSet *) msg)->ops_AttrList);
  81.                 while (!tic.isDone()) {
  82.                     /* register */ ULONG ticData = tic.itemData();
  83.                     switch (tic.itemTag())
  84.                     {
  85.                         case GA_Top:
  86.                             otop = (WORD) ticData;
  87.                             break;
  88.                         case GA_Left:
  89.                             oleft = (WORD) ticData;
  90.                             break;
  91.                         case GA_Width:
  92.                             owidth = (WORD) ticData;
  93.                             break;
  94.                         case GA_Height:
  95.                             oheight = (WORD) ticData;
  96.                             break;
  97.                         case GA_RightBorder:
  98.                             orborder = (BOOL) ticData;
  99.                             break;
  100.                         case GA_LeftBorder:
  101.                             olborder = (BOOL) ticData;
  102.                             break;
  103.                         case GA_TopBorder:
  104.                             otborder = (BOOL) ticData;
  105.                             break;
  106.                         case GA_BottomBorder:
  107.                             obborder = (BOOL) ticData;
  108.                             break;
  109.                         case ASCA_Arrows:
  110.                             data->arrows = (BOOL) ticData;
  111.                             break;
  112.                         case ASCA_Freedom:
  113.                             data->freedom = (ULONG) ticData;
  114.                             break;
  115.                         case ASCA_Top:
  116.                             data->top = (UWORD) ticData;
  117.                             break;
  118.                         case ASCA_Visible:
  119.                             data->visible = (UWORD) ticData;
  120.                             break;
  121.                         case ASCA_Total:
  122.                             data->total = (UWORD) ticData;
  123.                             break;
  124.                         case ASCA_Borderless:
  125.                             data->border = !(BOOL) ticData;
  126.                             break;
  127.                         default:
  128.                             break;
  129.                     };
  130.                     tic.next();
  131.                 };
  132.                 if (data->border)
  133.                 {
  134.                     data->blOffset = 2;
  135.                     data->btOffset = 2;
  136.                     data->bwOffset = 4;
  137.                     data->bhOffset = 4;
  138.                 }
  139.                 else {
  140.                     if (olborder|orborder|otborder|obborder)
  141.                     {
  142.                         if (data->freedom == FREEVERT)
  143.                         {
  144.                             data->blOffset = 4;
  145.                             data->btOffset = 0;
  146.                             data->bwOffset = 8;
  147.                             data->bhOffset = 2;
  148.                         }
  149.                         else {
  150.                             data->blOffset = 0;
  151.                             data->btOffset = 2;
  152.                             data->bwOffset = 3;
  153.                             data->bhOffset = 4;
  154.                         };
  155.                     }
  156.                     else {
  157.                         data->blOffset = 0;
  158.                         data->btOffset = 0;
  159.                         data->bwOffset = 0;
  160.                         data->bhOffset = 0;
  161.                     };
  162.                 }
  163.                 calcArrows(cl,(struct Gadget *) object, data);
  164.                 data->prop = (Object *) NewObject(NULL,PROPGCLASS,
  165.                     GA_Top, otop + data->btOffset,
  166.                     GA_Left, oleft + data->blOffset,
  167.                     GA_Width, owidth - data->bwOffset - data->propright,
  168.                     GA_Height, oheight - data->bhOffset - data->propbottom,
  169.                     GA_LeftBorder, olborder,
  170.                     GA_RightBorder, orborder,
  171.                     GA_TopBorder, otborder,
  172.                     GA_BottomBorder, obborder,
  173.                     PGA_Borderless, TRUE,
  174.                     PGA_Freedom, data->freedom,
  175.                     PGA_NewLook, TRUE,
  176.                     PGA_Top, data->top,
  177.                     PGA_Visible, data->visible,
  178.                     PGA_Total, data->total,
  179.                     ICA_TARGET, object,
  180.                     TAG_END);
  181.                 data->frame = (Object *) NewObject(NULL,FRAMEICLASS,
  182.                     IA_Recessed, FALSE,
  183.                     TAG_END);
  184.                 retval = (ULONG) object;
  185.             };
  186.             break;
  187.         };
  188.         case OM_DISPOSE:
  189.         {
  190.             data = (struct InstanceData *) INST_DATA(cl,o);
  191.             if (data->prop)
  192.                 DisposeObject(data->prop);
  193.             if (data->frame)
  194.                 DisposeObject(data->frame);
  195.             retval = DoSuperMethodA(cl,o,msg);
  196.             break;
  197.         };
  198.         case OM_GET:
  199.         {
  200.             data = (struct InstanceData *) INST_DATA(cl,o);
  201.             switch (((struct opGet *) msg)->opg_AttrID)
  202.             {
  203.                 case GA_Left:
  204.                     *(((struct opGet *) msg)->opg_Storage) = ((struct Gadget *) o)->LeftEdge;
  205.                     retval = TRUE;
  206.                     break;
  207.                 case GA_Top:
  208.                     *(((struct opGet *) msg)->opg_Storage) = ((struct Gadget *) o)->TopEdge;
  209.                     retval = TRUE;
  210.                     break;
  211.                 case GA_Width:
  212.                     *(((struct opGet *) msg)->opg_Storage) = ((struct Gadget *) o)->Width;
  213.                     retval = TRUE;
  214.                     break;
  215.                 case GA_Height:
  216.                     *(((struct opGet *) msg)->opg_Storage) = ((struct Gadget *) o)->Height;
  217.                     retval = TRUE;
  218.                     break;
  219.                 case ASCA_Arrows:
  220.                     *(((struct opGet *) msg)->opg_Storage) = (ULONG) data->arrows;
  221.                     retval = TRUE;
  222.                     break;
  223.                 case ASCA_LeftBorder:
  224.                     *(((struct opGet *) msg)->opg_Storage) = (ULONG) 0;
  225.                     retval = TRUE;
  226.                     break;
  227.                 case ASCA_RightBorder:
  228.                     *(((struct opGet *) msg)->opg_Storage) = (ULONG) 0;
  229.                     retval = TRUE;
  230.                     break;
  231.                 case ASCA_TopBorder:
  232.                     *(((struct opGet *) msg)->opg_Storage) = (ULONG) 0;
  233.                     retval = TRUE;
  234.                     break;
  235.                 case ASCA_BottomBorder:
  236.                     *(((struct opGet *) msg)->opg_Storage) = (ULONG) 0;
  237.                     retval = TRUE;
  238.                     break;
  239.                 case ASCA_AutoWidth:
  240.                     *(((struct opGet *) msg)->opg_Storage) =
  241.                         (ULONG) calcWidth(cl,(struct Gadget *) o, data);
  242.                     retval = TRUE;
  243.                     break;
  244.                 case ASCA_AutoHeight:
  245.                     *(((struct opGet *) msg)->opg_Storage) =
  246.                         (ULONG) calcHeight(cl,(struct Gadget *) o, data);
  247.                     retval = TRUE;
  248.                     break;
  249.                 case ASCA_Freedom:
  250.                     *(((struct opGet *) msg)->opg_Storage) = (ULONG) data->freedom;
  251.                     retval = TRUE;
  252.                     break;
  253.                 case ASCA_Top:
  254.                     *(((struct opGet *) msg)->opg_Storage) = (ULONG) data->top;
  255.                     retval = TRUE;
  256.                     break;
  257.                 case ASCA_Visible:
  258.                     *(((struct opGet *) msg)->opg_Storage) = (ULONG) data->visible;
  259.                     retval = TRUE;
  260.                     break;
  261.                 case ASCA_Total:
  262.                     *(((struct opGet *) msg)->opg_Storage) = (ULONG) data->total;
  263.                     retval = TRUE;
  264.                     break;
  265.                 case ASCA_Borderless:
  266.                     *(((struct opGet *) msg)->opg_Storage) = (ULONG) !data->border;
  267.                     retval = TRUE;
  268.                     break;
  269.                 default:
  270.                     retval = DoSuperMethodA(cl,o,msg);
  271.                     break;
  272.             };
  273.             break;
  274.         };
  275.         case OM_SET:
  276.         {
  277.             data = (struct InstanceData *) INST_DATA(cl,o);
  278.             BOOL redrawIt = FALSE;
  279.             BOOL recalcIt = FALSE;
  280.             TagItemCursorC tic(((struct opSet *) msg)->ops_AttrList);
  281.             while (!tic.isDone()) {
  282.                 /* register */ ULONG ticData = tic.itemData();
  283.                 switch (tic.itemTag())
  284.                 {
  285.                     case GA_Top:
  286.                         recalcIt = TRUE;
  287.                         break;
  288.                     case GA_Left:
  289.                         recalcIt = TRUE;
  290.                         break;
  291.                     case GA_Width:
  292.                         recalcIt = TRUE;
  293.                         break;
  294.                     case GA_Height:
  295.                         recalcIt = TRUE;
  296.                         break;
  297.                     case ASCA_Top:
  298.                         data->top = ticData;
  299.                         redrawIt = TRUE;
  300.                         break;
  301.                     case ASCA_Visible:
  302.                         data->visible = ticData;
  303.                         redrawIt = TRUE;
  304.                         break;
  305.                     case ASCA_Total:
  306.                         data->total = ticData;
  307.                         redrawIt = TRUE;
  308.                         break;
  309.                     default:
  310.                         break;
  311.                 };
  312.                 tic.next();
  313.             };
  314.             retval = DoSuperMethodA(cl,o,msg);
  315.             if (recalcIt)
  316.             {
  317.                 calcArrows(cl,(struct Gadget *) o, data);
  318.             };
  319.             if (redrawIt)
  320.             {
  321.                 render(cl,(struct Gadget *) o,
  322.                     (struct gpRender *) msg,data);
  323.             };
  324.             break;
  325.         };
  326.         case OM_UPDATE:
  327.         {
  328.             data = (struct InstanceData *) INST_DATA(cl,o);
  329.             BOOL redrawIt = FALSE;
  330.             TagItemCursorC tic(((struct opSet *) msg)->ops_AttrList);
  331.             while (!tic.isDone()) {
  332.                 /* register */ ULONG ticData = tic.itemData();
  333.                 switch (tic.itemTag())
  334.                 {
  335.                     case PGA_Top:
  336.                     {
  337.                         if (ticData != data->top)
  338.                         {
  339.                             data->top = ticData;
  340.                             struct TagItem tt[2];
  341.                             tt[0].ti_Tag = ASCA_Top;
  342.                             tt[0].ti_Data = ticData;
  343.                             tt[1].ti_Tag = TAG_END;
  344.                             DoMethod(o,OM_NOTIFY,tt,((struct opSet *) msg)->ops_GInfo,0);
  345.                         };
  346.                         break;
  347.                     };
  348.                     case ASCA_Top:
  349.                         data->top = ticData;
  350.                         redrawIt = TRUE;
  351.                         break;
  352.                     case ASCA_Visible:
  353.                         data->visible = ticData;
  354.                         redrawIt = TRUE;
  355.                         break;
  356.                     case ASCA_Total:
  357.                         data->total = ticData;
  358.                         redrawIt = TRUE;
  359.                         break;
  360.                     default:
  361.                         break;
  362.                 };
  363.                 tic.next();
  364.             };
  365.             if (redrawIt)
  366.             {
  367.                 render(cl,(struct Gadget *) o,
  368.                     (struct gpRender *) msg,data,TRUE);
  369.             };
  370.             break;
  371.         };
  372.         case GM_RENDER:
  373.         {
  374.             data = (struct InstanceData *) INST_DATA(cl,o);
  375.             retval = render(cl,(struct Gadget *) o,
  376.                 (struct gpRender *) msg,data);
  377.             break;
  378.         };
  379.         case GM_HITTEST:
  380.         {
  381.             retval = GMR_GADGETHIT;
  382.             break;
  383.         };
  384.         case GM_GOACTIVE:
  385.         {
  386.             data = (struct InstanceData *) INST_DATA(cl,o);
  387.             ((struct Gadget *) o)->Flags |= GFLG_SELECTED;
  388.             if (data->prop)
  389.             {
  390.                 struct gpInput *gpi = (struct gpInput *) msg;
  391.                 if (gpi->gpi_Mouse.X >= data->blOffset &&
  392.                     gpi->gpi_Mouse.X < ((struct Gadget *) o)->Width - data->bwOffset - data->propright &&
  393.                     gpi->gpi_Mouse.Y >= data->btOffset &&
  394.                     gpi->gpi_Mouse.Y < ((struct Gadget *) o)->Height - data->bhOffset - data->propbottom)
  395.                 {
  396.                     data->activePart = ACTIVE_Prop;
  397.                     gpi->gpi_Mouse.X -= data->blOffset;
  398.                     gpi->gpi_Mouse.Y -= data->btOffset;
  399.                     retval = DoMethodA(data->prop,(Msg) msg);
  400.                 }
  401.                 else if (data->arrows)
  402.                 {
  403.                     struct Gadget *g = (struct Gadget *) o;
  404.                     if (data->freedom == FREEVERT)
  405.                     {
  406.                         data->arrowleft1 = 0;
  407.                         data->arrowleft2 = 0;
  408.                         data->arrowtop1 = g->Height - data->propbottom;
  409.                         data->arrowtop2 = data->arrowtop1 + data->arrowheight;
  410.                     }
  411.                     else {
  412.                         data->arrowleft1 = g->Width - data->propright;
  413.                         data->arrowleft2 = data->arrowleft1 + data->arrowwidth;
  414.                         data->arrowtop1 = 0;
  415.                         data->arrowtop2 = 0;
  416.                     };
  417.                     if (gpi->gpi_Mouse.X >= data->arrowleft1 &&
  418.                         gpi->gpi_Mouse.X < data->arrowleft1 + data->arrowwidth &&
  419.                         gpi->gpi_Mouse.Y >= data->arrowtop1 &&
  420.                         gpi->gpi_Mouse.Y < data->arrowtop1 + data->arrowheight)
  421.                     {
  422.                         data->activePart = ACTIVE_UpLeft;
  423.                         render(cl,(struct Gadget *) o,
  424.                             (struct gpRender *) msg,data,TRUE);
  425.                         scrollUpLeft(cl,g,data,gpi->gpi_GInfo);
  426.                         retval = GMR_MEACTIVE;
  427.                     }
  428.                     else if (gpi->gpi_Mouse.X >= data->arrowleft2 &&
  429.                         gpi->gpi_Mouse.X < data->arrowleft2 + data->arrowwidth &&
  430.                         gpi->gpi_Mouse.Y >= data->arrowtop2 &&
  431.                         gpi->gpi_Mouse.Y < data->arrowtop2 + data->arrowheight)
  432.                     {
  433.                         data->activePart = ACTIVE_DownRight;
  434.                         render(cl,(struct Gadget *) o,
  435.                             (struct gpRender *) msg,data,TRUE);
  436.                         scrollDownRight(cl,g,data,gpi->gpi_GInfo);
  437.                         retval = GMR_MEACTIVE;
  438.                     }
  439.                     else
  440.                         retval = GMR_NOREUSE;
  441.                 }
  442.                 else
  443.                     retval = GMR_NOREUSE;
  444.             };
  445.             break;
  446.         };
  447.         case GM_GOINACTIVE:
  448.         {
  449.             data = (struct InstanceData *) INST_DATA(cl,o);
  450.             if (data->prop)
  451.             {
  452.                 if (data->activePart == ACTIVE_Prop)
  453.                 {
  454.                     data->activePart = ACTIVE_None;
  455.                     retval = DoMethodA(data->prop,(Msg) msg);
  456.                 }
  457.                 else {
  458.                     data->activePart = ACTIVE_None;
  459.                     render(cl,(struct Gadget *) o,
  460.                         (struct gpRender *) msg,data,TRUE);
  461.                 };
  462.             };
  463.             ((struct Gadget *) o)->Flags &= ~GFLG_SELECTED;
  464.             break;
  465.         };
  466.         case GM_HANDLEINPUT:
  467.         {
  468.             data = (struct InstanceData *) INST_DATA(cl,o);
  469.             if (data->prop)
  470.             {
  471.                 if (data->activePart == ACTIVE_Prop)
  472.                 {
  473.                     struct gpInput *gpi = (struct gpInput *) msg;
  474.                     gpi->gpi_Mouse.X -= data->blOffset;
  475.                     gpi->gpi_Mouse.Y -= data->btOffset;
  476.                     retval = DoMethodA(data->prop,(Msg) msg);
  477.                 }
  478.                 else {
  479.                     struct gpInput *gpi = (struct gpInput *) msg;
  480.                     struct InputEvent *ie = gpi->gpi_IEvent;
  481.                     BOOL mouseOverGadget = FALSE;
  482.                     if (data->activePart == ACTIVE_UpLeft)
  483.                     {
  484.                         mouseOverGadget = ((gpi->gpi_Mouse.X >= data->arrowleft1) &&
  485.                             (gpi->gpi_Mouse.X < data->arrowleft1 + data->arrowwidth) &&
  486.                             (gpi->gpi_Mouse.Y >= data->arrowtop1) &&
  487.                             (gpi->gpi_Mouse.Y < data->arrowtop1 + data->arrowheight));
  488.                     }
  489.                     else {
  490.                         mouseOverGadget = ((gpi->gpi_Mouse.X >= data->arrowleft2) &&
  491.                             (gpi->gpi_Mouse.X < data->arrowleft2 + data->arrowwidth) &&
  492.                             (gpi->gpi_Mouse.Y >= data->arrowtop2) &&
  493.                             (gpi->gpi_Mouse.Y < data->arrowtop2 + data->arrowheight));
  494.                     };
  495.                     if (mouseOverGadget)
  496.                     {
  497.                         if (!(((struct Gadget *) o)->Flags & GFLG_SELECTED))
  498.                         {
  499.                             ((struct Gadget *) o)->Flags |= GFLG_SELECTED;
  500.                             render(cl,(struct Gadget *) o,
  501.                                 (struct gpRender *) msg,data,TRUE);
  502.                         };
  503.                     };
  504.                     else {
  505.                         if (((struct Gadget *) o)->Flags & GFLG_SELECTED)
  506.                         {
  507.                             ((struct Gadget *) o)->Flags &= ~GFLG_SELECTED;
  508.                             render(cl,(struct Gadget *) o,
  509.                                 (struct gpRender *) msg,data,FALSE);
  510.                         };
  511.                     };
  512.                     switch (ie->ie_Class)
  513.                     {
  514.                         case IECLASS_RAWMOUSE:
  515.                         {
  516.                             switch (ie->ie_Code)
  517.                             {
  518.                                 case SELECTUP:
  519.                                     if (mouseOverGadget)
  520.                                     {
  521.                                         retval = GMR_NOREUSE | GMR_VERIFY;
  522.                                     }
  523.                                     else {
  524.                                         retval = GMR_NOREUSE;
  525.                                     };
  526.                                     break;
  527.                                 case MENUDOWN:
  528.                                     retval = GMR_REUSE;
  529.                                     break;
  530.                                 default:
  531.                                     retval = GMR_MEACTIVE;
  532.                                     break;
  533.                             };
  534.                             break;
  535.                         };
  536.                         case IECLASS_TIMER:
  537.                         {
  538.                             if (mouseOverGadget)
  539.                             {
  540.                                 if (data->activePart == ACTIVE_UpLeft)
  541.                                 {
  542.                                     scrollUpLeft(cl,(struct Gadget *) o,data,gpi->gpi_GInfo);
  543.                                 }
  544.                                 else if (data->activePart == ACTIVE_DownRight)
  545.                                 {
  546.                                     scrollDownRight(cl,(struct Gadget *) o,data,gpi->gpi_GInfo);
  547.                                 };
  548.                             };
  549.                         };
  550.                         default:
  551.                             retval = GMR_MEACTIVE;
  552.                             break;
  553.                     };
  554.                 };
  555.             };
  556.             break;
  557.         };
  558.         default:
  559.         {
  560.             retval = DoSuperMethodA(cl,o,msg);
  561.             break;
  562.         };
  563.     };
  564.     return retval;
  565. }
  566.  
  567. ULONG ArrowScrollerClass::render(Class *cl, struct Gadget *g,
  568.     struct gpRender *msg, struct InstanceData *data, BOOL overGadget)
  569. {
  570.     static struct DrawData up[] = {
  571.         { DRAWCMD_Move, { 4096,13107 }},
  572.         { DRAWCMD_Attr, { SHINEPEN, TEXTPEN }},
  573.         { DRAWCMD_Draw, { 8192,3276 }},
  574.         { DRAWCMD_Attr, { SHADOWPEN, TEXTPEN }},
  575.         { DRAWCMD_Draw, { 12288,13107 }},
  576.         { DRAWCMD_Draw, { 8192,9830 }},
  577.         { DRAWCMD_Fill, { FILLPEN, TEXTPEN }},
  578.         { DRAWCMD_End }
  579.     };
  580.     static struct DrawData down[] = {
  581.         { DRAWCMD_Move, { 4096,3276 }},
  582.         { DRAWCMD_Attr, { SHADOWPEN, TEXTPEN }},
  583.         { DRAWCMD_Draw, { 8192,13107 }},
  584.         { DRAWCMD_Attr, { SHINEPEN, TEXTPEN }},
  585.         { DRAWCMD_Draw, { 12288,3276 }},
  586.         { DRAWCMD_Attr, { SHADOWPEN, TEXTPEN }},
  587.         { DRAWCMD_Draw, { 8192,6553 }},
  588.         { DRAWCMD_Fill, { FILLPEN, TEXTPEN }},
  589.         { DRAWCMD_End }
  590.     };
  591.     static struct DrawData left[] = {
  592.         { DRAWCMD_Move, { 13107,4096 }},
  593.         { DRAWCMD_Attr, { SHINEPEN, TEXTPEN }},
  594.         { DRAWCMD_Draw, { 3276,8192 }},
  595.         { DRAWCMD_Attr, { SHADOWPEN, TEXTPEN }},
  596.         { DRAWCMD_Draw, { 13107,12288 }},
  597.         { DRAWCMD_Draw, { 9830,8192 }},
  598.         { DRAWCMD_Fill, { FILLPEN, TEXTPEN }},
  599.         { DRAWCMD_End }
  600.     };
  601.     static struct DrawData right[] = {
  602.         { DRAWCMD_Move, { 3276,4096 }},
  603.         { DRAWCMD_Attr, { SHADOWPEN, TEXTPEN }},
  604.         { DRAWCMD_Draw, { 13107,8192 }},
  605.         { DRAWCMD_Draw, { 3276,12288 }},
  606.         { DRAWCMD_Attr, { SHINEPEN, TEXTPEN }},
  607.         { DRAWCMD_Draw, { 6553,8192 }},
  608.         { DRAWCMD_Attr, { SHADOWPEN, TEXTPEN }},
  609.         { DRAWCMD_Fill, { FILLPEN, TEXTPEN }},
  610.         { DRAWCMD_End }
  611.     };
  612.     struct RastPort *rp;
  613.     struct GadgetInfo *ginfo;
  614.     if (msg->MethodID == OM_SET || msg->MethodID == OM_UPDATE)
  615.         ginfo = ((struct opSet *) msg)->ops_GInfo
  616.     else
  617.         ginfo = msg->gpr_GInfo;
  618.     if (!ginfo)
  619.         return TRUE;
  620.     UWORD *pens = ginfo->gi_DrInfo->dri_Pens;
  621.     if (msg->MethodID == GM_RENDER)
  622.         rp = msg->gpr_RPort
  623.     else
  624.         rp = ObtainGIRPort(ginfo);
  625.     if (rp)
  626.     {
  627.         if (data->border && data->frame)
  628.         {
  629.             SetAttrs(data->frame,
  630.                 IA_Left,g->LeftEdge,
  631.                 IA_Top,g->TopEdge,
  632.                 IA_Width,g->Width - data->propright,
  633.                 IA_Height,g->Height - data->propbottom,
  634.                 IA_EdgesOnly, TRUE,
  635.                 TAG_END);
  636.             DrawImageState(rp,(struct Image *) data->frame,
  637.                     0, 0, IDS_NORMAL,ginfo->gi_DrInfo);
  638.         };
  639.         if (data->arrows)
  640.         {
  641.             WORD left1, top1, left2, top2;
  642.             struct DrawData *upleft;
  643.             struct DrawData *downright;
  644.             if (data->freedom == FREEVERT)
  645.             {
  646.                 left1 = g->LeftEdge;
  647.                 left2 = left1;
  648.                 top1 = g->TopEdge + g->Height - data->propbottom;
  649.                 top2 = top1 + data->arrowheight;
  650.                 upleft = up;
  651.                 downright = down;
  652.             }
  653.             else {
  654.                 left1 = g->LeftEdge + g->Width - data->propright;
  655.                 left2 = left1 + data->arrowwidth;
  656.                 top1 = g->TopEdge;
  657.                 top2 = top1;
  658.                 upleft = left;
  659.                 downright = right;
  660.             };
  661.             if (data->frame)
  662.             {
  663.                 UWORD fillpen;
  664.                 BOOL sel = data->activePart == ACTIVE_UpLeft && overGadget;
  665.                 if ((g->Activation & (GACT_BOTTOMBORDER|GACT_LEFTBORDER|GACT_RIGHTBORDER|GACT_TOPBORDER))
  666.                     && (ginfo->gi_Window->Flags & WFLG_WINDOWACTIVE))
  667.                 {
  668.                     fillpen = sel ? BACKGROUNDPEN : FILLPEN;
  669.                 }
  670.                 else {
  671.                     fillpen = sel ? FILLPEN : BACKGROUNDPEN;
  672.                 }
  673.                 SetAPen(rp,pens[fillpen]);
  674.                 SetDrMd(rp,JAM1);
  675.                 RectFill(rp,
  676.                     left1, top1,
  677.                     left1 + data->arrowwidth - 1, top1 + data->arrowheight - 1);
  678.                 SetAttrs(data->frame,
  679.                     IA_Left,left1,
  680.                     IA_Top,top1,
  681.                     IA_Width,data->arrowwidth,
  682.                     IA_Height,data->arrowheight,
  683.                     IA_EdgesOnly,TRUE,
  684.                     TAG_END);
  685.                 DrawImageState(rp,(struct Image *) data->frame,
  686.                         0, 0, sel ? IDS_SELECTED : IDS_NORMAL,ginfo->gi_DrInfo);
  687.                 drawOutlineImage(rp,upleft,left1,top1,
  688.                     data->arrowwidth,data->arrowheight,ginfo->gi_DrInfo,
  689.                     TRUE,TRUE,FALSE,sel ? IDS_SELECTED : IDS_NORMAL);
  690.             };
  691.             if (data->frame)
  692.             {
  693.                 UWORD fillpen;
  694.                 BOOL sel = data->activePart == ACTIVE_DownRight && overGadget;
  695.                 if ((g->Activation & (GACT_BOTTOMBORDER|GACT_LEFTBORDER|GACT_RIGHTBORDER|GACT_TOPBORDER))
  696.                     && (ginfo->gi_Window->Flags & WFLG_WINDOWACTIVE))
  697.                 {
  698.                     fillpen = sel ? BACKGROUNDPEN : FILLPEN;
  699.                 }
  700.                 else {
  701.                     fillpen = sel ? FILLPEN : BACKGROUNDPEN;
  702.                 }
  703.                 SetAPen(rp,pens[fillpen]);
  704.                 SetDrMd(rp,JAM1);
  705.                 RectFill(rp,
  706.                     left2, top2,
  707.                     left2 + data->arrowwidth - 1, top2 + data->arrowheight - 1);
  708.                 SetAttrs(data->frame,
  709.                     IA_Left,left2,
  710.                     IA_Top,top2,
  711.                     IA_Width,data->arrowwidth,
  712.                     IA_Height,data->arrowheight,
  713.                     IA_EdgesOnly,TRUE,
  714.                     TAG_END);
  715.                 DrawImageState(rp,(struct Image *) data->frame,
  716.                         0, 0, sel ? IDS_SELECTED : IDS_NORMAL,ginfo->gi_DrInfo);
  717.                 drawOutlineImage(rp,downright,left2,top2,
  718.                     data->arrowwidth,data->arrowheight,ginfo->gi_DrInfo,
  719.                     TRUE,TRUE,FALSE,sel ? IDS_SELECTED : IDS_NORMAL);
  720.             };
  721.         };
  722.         if (data->prop)
  723.         {
  724.             SetAttrs(data->prop,
  725.                 GA_Top,g->TopEdge + data->btOffset,
  726.                 GA_Left,g->LeftEdge + data->blOffset,
  727.                 GA_Width,g->Width - data->bwOffset - data->propright,
  728.                 GA_Height,g->Height - data->bhOffset - data->propbottom,
  729.                 PGA_Top,data->top,
  730.                 PGA_Visible,data->visible,
  731.                 PGA_Total,data->total,
  732.                 TAG_END);
  733.             if (data->activePart <= ACTIVE_Prop)
  734.                 DoMethod(data->prop,GM_RENDER,ginfo,rp,GREDRAW_REDRAW);
  735.         };
  736.         if (msg->MethodID != GM_RENDER)
  737.             ReleaseGIRPort(rp);
  738.         return TRUE;
  739.     };
  740.     return FALSE;
  741. }
  742.  
  743. VOID ArrowScrollerClass::calcArrows(Class *cl, struct Gadget *g,
  744.         struct InstanceData *data)
  745. {
  746.     data->propbottom = 0;
  747.     data->propright = 0;
  748.     if (data->arrows)
  749.     {
  750.         if (data->freedom == FREEVERT)
  751.         {
  752.             data->arrowwidth = g->Width;
  753.             data->arrowheight = (g->Width * 11) / 18;
  754.             data->propbottom = 2*data->arrowheight;
  755.         }
  756.         else {
  757.             data->arrowwidth = (g->Height * 16) / 10;
  758.             data->arrowheight = g->Height;
  759.             data->propright = 2*data->arrowwidth;
  760.         };
  761.     };
  762. }
  763.  
  764. VOID ArrowScrollerClass::scrollUpLeft(Class *cl, struct Gadget *g,
  765.         struct InstanceData *data, struct GadgetInfo *ginfo)
  766. {
  767.     if (data->prop)
  768.     {
  769.         if (data->top > data->scrollamount)
  770.             data->top -= data->scrollamount
  771.         else
  772.             data->top = 0;
  773.         struct TagItem tt[2];
  774.         tt[0].ti_Tag = PGA_Top,
  775.         tt[0].ti_Data = data->top;
  776.         tt[1].ti_Tag = TAG_END;
  777.         DoMethod(data->prop,OM_UPDATE,tt,ginfo,0);
  778.         tt[0].ti_Tag = ASCA_Top;
  779.         tt[0].ti_Data = data->top;
  780.         tt[1].ti_Tag = TAG_END;
  781.         DoSuperMethod(cl,(Object *) g,OM_NOTIFY,tt,ginfo,0);
  782.     }
  783. }
  784.  
  785. VOID ArrowScrollerClass::scrollDownRight(Class *cl, struct Gadget *g,
  786.         struct InstanceData *data, struct GadgetInfo *ginfo)
  787. {
  788.     if (data->prop)
  789.     {
  790.         data->top += data->scrollamount;
  791.         struct TagItem tt[2];
  792.         tt[0].ti_Tag = PGA_Top,
  793.         tt[0].ti_Data = data->top;
  794.         tt[1].ti_Tag = TAG_END;
  795.         DoMethod(data->prop,OM_UPDATE,tt,ginfo,0);
  796.         tt[0].ti_Tag = ASCA_Top;
  797.         tt[0].ti_Data = data->top;
  798.         tt[1].ti_Tag = TAG_END;
  799.         DoSuperMethod(cl,(Object *) g,OM_NOTIFY,tt,ginfo,0);
  800.     }
  801. }
  802.  
  803. WORD ArrowScrollerClass::calcWidth(Class *cl, struct Gadget *g,
  804.         struct InstanceData *data)
  805. {
  806.     if (data->freedom == FREEHORIZ)
  807.         return data->propright + 8;
  808.     return 18;
  809. }
  810.  
  811. WORD ArrowScrollerClass::calcHeight(Class *cl, struct Gadget *g,
  812.         struct InstanceData *data)
  813. {
  814.     if (data->freedom == FREEVERT)
  815.         return data->propbottom + 8;
  816.     return 10;
  817. }
  818.  
  819. // *************************************************************
  820.  
  821. ArrowScrollerClass BArrowScrollerC::sc;
  822.  
  823. // *************************************************************
  824.  
  825.