home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1994 #1 / monster.zip / monster / PROG_C / BUTCLAS3.ZIP / PROGRESS.C < prev    next >
C/C++ Source or Header  |  1993-06-04  |  7KB  |  310 lines

  1. #include "headers.h"
  2.  
  3. #include "buttonclass.h"
  4.  
  5. #define FLAG_SHOWPERCENT 1
  6.  
  7. struct ProgressData {
  8.     UWORD min;
  9.     UWORD max;
  10.     UWORD current;
  11.     UWORD flags;
  12.     struct TextFont *textFont;
  13. };
  14.  
  15. struct ClassGlobalData {
  16.     struct Library *SysBase;
  17.     struct Library *IntuitionBase;
  18.     struct Library *UtilityBase;
  19.     struct Library *GfxBase;
  20. };
  21. typedef struct ClassGlobalData CGLOB;
  22.  
  23.  
  24. #define D(x) ;
  25.  
  26. #define REG(x) register __ ## x
  27.  
  28. extern ULONG __stdargs DoSuperMethodA( struct IClass *cl, Object *obj, Msg message );
  29. extern ULONG DoMethod( Object *obj, unsigned long MethodID, ... );
  30. static ULONG __asm dispatchProgressGadget(REG(a0) Class *cl, REG(a2) Object *o, REG(a1) Msg msg);
  31. static ULONG RenderProgress(CGLOB *z, Class *cl, struct Gadget *g, struct gpRender *msg, struct ProgressData *inst);
  32. static void SPrintf(struct Library *SysBase, STRPTR buffer, STRPTR format, ...);
  33.  
  34. #define IntuitionBase    z->IntuitionBase
  35. #define UtilityBase        z->UtilityBase
  36. #define GfxBase            z->GfxBase
  37.  
  38. Class *initProgressGadgetClass(struct Library *IBase, struct Library *UBase, struct Library *GBase)
  39. {
  40.   Class *cl;
  41.   CGLOB *z;
  42.   struct Library *SysBase= *((void **)4L);
  43.  
  44.     z= AllocVec(sizeof(CGLOB), MEMF_CLEAR);
  45.     if( z )
  46.         {
  47.         z->SysBase   = SysBase;
  48.         IntuitionBase= IBase;
  49.         UtilityBase  = UBase;
  50.         GfxBase      = GBase;
  51.         if( cl = MakeClass( NULL, "gadgetclass", NULL, sizeof(struct ProgressData), 0) )
  52.             {
  53.             cl->cl_Dispatcher.h_Entry = (ULONG(*)()) dispatchProgressGadget;
  54.             cl->cl_Dispatcher.h_Data  = z;
  55.             return(cl);
  56.             }
  57.         FreeVec(z);
  58.         }
  59.     return(NULL);
  60. }
  61. #define SysBase            z->SysBase
  62.  
  63. BOOL freeProgressGadgetClass( Class *cl )
  64. {
  65.   CGLOB *z= cl->cl_Dispatcher.h_Data;
  66.   BOOL retval;
  67.  
  68.     retval= FreeClass(cl);
  69.     FreeVec(z);
  70.     return( retval );
  71. }
  72.  
  73. static ULONG __asm dispatchProgressGadget(REG(a0) Class *cl, REG(a2) Object *o, REG(a1) Msg msg)
  74. {
  75.   CGLOB  *z= cl->cl_Dispatcher.h_Data;
  76.   struct Gadget *g= (struct Gadget *)o;
  77.   struct RastPort *rp;
  78.   struct ProgressData *inst;
  79.   struct TagItem *ti;
  80.   struct opGet *opget;
  81.   ULONG retval;
  82.   Object *object;
  83.  
  84.  
  85.     switch( msg->MethodID )
  86.         {
  87.         case OM_NEW:
  88.             D( kprintf("OM_NEW\n"); )
  89.             if( object = (Object *)DoSuperMethodA(cl, o, msg) )
  90.                 {
  91.                 ti= ((struct opSet *)msg)->ops_AttrList;
  92.  
  93.                 inst= INST_DATA(cl, object);
  94.                 inst->min = GetTagData(PRO_Min,   0, ti);
  95.                 inst->max = GetTagData(PRO_Max, 100, ti);
  96.                 inst->current = GetTagData(PRO_Current, 0, ti);
  97.                 inst->flags = (GetTagData(PRO_ShowPercent, 0, ti) ? FLAG_SHOWPERCENT : 0);
  98.                 inst->textFont= (struct TextFont *)GetTagData(PRO_TextFont, 0, ti);
  99.                 }
  100.             retval= (ULONG)object;
  101.             break;
  102.         case GM_RENDER:
  103.             D( kprintf("GM_RENDER\n"); )
  104.             inst= INST_DATA(cl, o);
  105.             retval= RenderProgress(z, cl, g, (struct gpRender *)msg, inst);
  106.             break;
  107.         case OM_SET:
  108.             D( kprintf("OM_SET\n"); )
  109.             ti= ((struct opSet *)msg)->ops_AttrList;
  110.             if( FindTagItem(GA_Width,  ti) ||
  111.                 FindTagItem(GA_Height, ti) ||
  112.                 FindTagItem(GA_Top,    ti) ||
  113.                 FindTagItem(GA_Left,   ti) ||
  114.                 FindTagItem(PRO_Min, ti) ||
  115.                 FindTagItem(PRO_Max, ti) ||
  116.                 FindTagItem(PRO_Current, ti) ||
  117.                 FindTagItem(PRO_ShowPercent, ti) ||
  118.                 FindTagItem(PRO_TextFont, ti) )
  119.                 {
  120.                 WORD x,y,w,h;
  121.                 
  122.                 x= g->LeftEdge;
  123.                 y= g->TopEdge;
  124.                 w= g->Width;
  125.                 h= g->Height;
  126.  
  127.                 retval= DoSuperMethodA(cl, o, msg);
  128.  
  129.                 if( rp=ObtainGIRPort( ((struct opSet *)msg)->ops_GInfo) )
  130.                     {
  131.                     UWORD *pens= ((struct opSet *)msg)->ops_GInfo->gi_DrInfo->dri_Pens;
  132.                     struct TagItem *tmp;
  133.                     
  134.                     if( x!=g->LeftEdge || y!=g->TopEdge || w!=g->Width || h!=g->Height )
  135.                         {
  136.                         SetAPen(rp, pens[BACKGROUNDPEN]);
  137.                         SetDrMd(rp, JAM1);
  138.                         RectFill(rp, x, y, x+w, y+h);
  139.                         }
  140.  
  141.                     inst= INST_DATA(cl, o);
  142.  
  143.                     inst->min = GetTagData(PRO_Min, (LONG)inst->min, ti);
  144.                     inst->max = GetTagData(PRO_Max, (LONG)inst->max, ti);
  145.                     inst->current = GetTagData(PRO_Current, (LONG)inst->current, ti);
  146.                     inst->textFont= (struct TextFont *)GetTagData(PRO_TextFont, (LONG)inst->textFont, ti);
  147.                     if( tmp=FindTagItem(PRO_ShowPercent, ti) )
  148.                         {
  149.                         inst->flags = ( tmp->ti_Data ? FLAG_SHOWPERCENT : 0);
  150.                         }
  151.  
  152.                     DoMethod(o, GM_RENDER, ((struct opSet *)msg)->ops_GInfo, rp, GREDRAW_REDRAW);
  153.                     ReleaseGIRPort(rp);
  154.                     }
  155.                 }
  156.             else
  157.                 {
  158.                 retval= DoSuperMethodA(cl, o, msg);
  159.                 }
  160.             break;
  161.         case OM_GET:
  162.             D( kprintf("OM_GET\n"); )
  163.             opget= (struct opGet *)msg;
  164.             inst= INST_DATA(cl, o);
  165.             retval= TRUE;
  166.             switch( opget->opg_AttrID )
  167.                 {
  168.                 case PRO_Current:
  169.                     *(opget->opg_Storage)= (ULONG)inst->current;
  170.                     break;
  171.                 case PRO_Min:
  172.                     *(opget->opg_Storage)= (ULONG)inst->min;
  173.                     break;
  174.                 case PRO_Max:
  175.                     *(opget->opg_Storage)= (ULONG)inst->max;
  176.                     break;
  177.                 case PRO_ShowPercent:
  178.                     *(opget->opg_Storage)= (ULONG)( inst->flags & FLAG_SHOWPERCENT );
  179.                     break;
  180.                 case PRO_TextFont:
  181.                     *(opget->opg_Storage)= (ULONG)inst->textFont;
  182.                     break;
  183.                 default:
  184.                     retval= DoSuperMethodA(cl, o, msg);
  185.                 }
  186.             break;
  187.         case GM_HITTEST:
  188.         case GM_GOACTIVE:
  189.         case GM_HANDLEINPUT:
  190.         case GM_GOINACTIVE:
  191.         default:
  192.             D( kprintf("DEFAULT\n"); )
  193.             retval= DoSuperMethodA(cl, o ,msg);
  194.             break;
  195.         }
  196.     return( retval );
  197. }
  198.  
  199. static ULONG RenderProgress(CGLOB *z, Class *cl, struct Gadget *g, struct gpRender *msg, struct ProgressData *inst)
  200. {
  201.   struct RastPort *rp;
  202.   ULONG retval=TRUE;
  203.   UWORD *pens= msg->gpr_GInfo->gi_DrInfo->dri_Pens;
  204.  
  205.     if( msg->MethodID == GM_RENDER )
  206.         {
  207.         rp= msg->gpr_RPort;
  208.         }
  209.     else
  210.         {
  211.         rp= ObtainGIRPort(msg->gpr_GInfo);
  212.         }
  213.  
  214.     if( rp )
  215.         {
  216.         UBYTE shine, shadow, sel, back;
  217.         UWORD x, y, w, h;
  218.         UBYTE oldAPen, oldDrMd;
  219.         LONG pos, min, max;
  220.  
  221.         oldAPen= rp->FgPen;
  222.         oldDrMd= rp->DrawMode;
  223.  
  224.         back  = pens[BACKGROUNDPEN];
  225.         sel   = pens[FILLPEN];
  226.         shine = pens[SHADOWPEN];
  227.         shadow= pens[SHINEPEN];
  228.  
  229.         x= g->LeftEdge;    
  230.         y= g->TopEdge;
  231.         w= g->Width-1;
  232.         h= g->Height-1;
  233.  
  234.         pos= (LONG)inst->current;
  235.         min= (LONG)inst->min;
  236.         max= (LONG)inst->max;
  237.         if( pos < min )
  238.             {
  239.             pos = min;
  240.             }
  241.         if( pos > max )
  242.             {
  243.             pos = max;
  244.             }
  245.  
  246.         pos = (pos - min) * (LONG)(w) / (max - min);
  247.  
  248.         //SetDrMd(rp, JAM1);
  249.         if( pos > 0 )
  250.             {
  251.             SetAPen(rp, sel);
  252.             RectFill( rp, x+2, y+1, x+pos-2, y+h-1 );
  253.             }
  254.  
  255.         if( pos < w )
  256.             {
  257.             SetAPen(rp, back);
  258.             RectFill( rp, x+pos+2, y+1, x+w-2, y+h-1 );
  259.             }
  260.  
  261.         SetAPen(rp, shadow);
  262.         RectFill(rp, x+1, y+h, x+w, y+h);
  263.         RectFill(rp, x+w-1, y+1, x+w-1, y+h);
  264.         RectFill(rp, x+w, y, x+w, y+h);
  265.         
  266.  
  267.         SetAPen(rp, shine);
  268.         RectFill(rp, x, y, x+w-1, y);
  269.         RectFill(rp, x, y+1, x, y+h);
  270.         RectFill(rp, x+1, y+1, x+1, y+h-1);
  271.  
  272.         if( inst->flags & FLAG_SHOWPERCENT )
  273.             {
  274.             UBYTE per[5];
  275.             UWORD slen, text_x, text_y;
  276.             struct TextExtent te;
  277.  
  278.             SPrintf(SysBase, per, "%ld%%", (w ? pos*100/w : 0 ));
  279.             slen= strlen(per);
  280.             TextExtent(rp, per, slen, &te);
  281.             text_x= x + (w+1)/2 - te.te_Width/2;
  282.             text_y= y + (h+1)/2 - (te.te_Extent.MaxY - te.te_Extent.MinY + 1)/2 - te.te_Extent.MinY;
  283.  
  284.             if( inst->textFont ) SetFont(rp, inst->textFont);
  285.             SetAPen(rp, pens[TEXTPEN]);
  286.             Move(rp, text_x, text_y);
  287.             Text(rp, per, slen);
  288.             }
  289.  
  290.         SetAPen(rp, oldAPen);
  291.         SetDrMd(rp, oldDrMd);
  292.  
  293.         if( msg->MethodID != GM_RENDER )
  294.             {
  295.             ReleaseGIRPort(rp);
  296.             }
  297.         }
  298.     else
  299.         {
  300.         retval= FALSE;
  301.         }
  302.     return( retval );
  303. }
  304.  
  305. #undef SysBase
  306. static void SPrintf(struct Library *SysBase, STRPTR buffer, STRPTR format, ...)
  307. {
  308.     RawDoFmt( format, (APTR)(&format+1), (void (*)())"\x16\xc0\x4E\x75", buffer);
  309. }
  310.