home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / Reference / DevCon / Atlanta_1990 / Atlanta-Devcon.1 / Libraries / Intuition / boopsi / emboxpubcl.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-26  |  6.2 KB  |  280 lines

  1. /* emboxclass.c -- :ts=8
  2.  * Example of a PUBLIC image class.
  3.  * This one does a raised embossed box.
  4.  * Doesn't do resolution sensitive bevel widths yet,
  5.  * nor correctly supports IA_LINEWIDTH yet.
  6.  * But's it's an example of an image subclass
  7.  * with some instance data.
  8.  */
  9.  
  10. /*
  11. Copyright (c) 1989, 1990 Commodore-Amiga, Inc.
  12.  
  13. Executables based on this information may be used in software
  14. for Commodore Amiga computers. All other rights reserved.
  15. This information is provided "as is"; no warranties are made.
  16. All use is at your own risk, and no liability or responsibility
  17. is assumed.
  18. */
  19.  
  20. #include "sysall.h"
  21.  
  22. #if 0    /* in sysall.h    */
  23. #include <intuition/classusr.h>
  24. #include <intuition/classes.h>
  25. #include <intuition/imageclass.h>
  26. #endif
  27.  
  28. #include <intuition/classes.h>
  29.  
  30. #include <graphics/gfxmacros.h>
  31.  
  32. #define D(x)    ;
  33. #define DH(x)    ;
  34.  
  35. struct EmbBData {
  36.     /* right now, this is kept in pixels, and isn't adjusted
  37.      * for resolution.  A fancier version might take this
  38.      * parameter in "resolution ticks"
  39.      */
  40.     UWORD        ebd_LineWidth;
  41. };
  42.  
  43. #define IM(o)    ((struct Image *)(o))    /* transparent base class */
  44.  
  45. #define DEFAULTLINEWIDTH    1
  46.  
  47. /* public class    */
  48. #define PRIVATECLASS    FALSE
  49.  
  50. #if PRIVATECLASS
  51. #define MYCLASSID    (NULL)
  52. #else
  53. #define MYCLASSID    "emboxclass"
  54. #endif
  55. extern struct Library    *IntuitionBase;
  56.  
  57. #define SUPERCLASSID    (IMAGECLASS)
  58.  
  59. Class    *
  60. initEmbBClass()
  61. {
  62.     ULONG    __saveds dispatchEmbB();
  63.     ULONG    hookEntry();
  64.     Class    *cl;
  65.     Class    *MakeClass();
  66.  
  67.     if ( cl =  MakeClass( MYCLASSID, 
  68.         SUPERCLASSID, NULL,        /* superclass is public      */
  69.          sizeof (struct EmbBData),    /* my object's instance data */
  70.         0 ) )
  71.     {
  72.     /* initialize the cl_Dispatcher Hook    */
  73.     cl->cl_Dispatcher.h_Entry = hookEntry;
  74.     cl->cl_Dispatcher.h_SubEntry = dispatchEmbB;
  75.     cl->cl_Dispatcher.h_Data = (VOID *) 0xFACE;    /* unused */
  76.  
  77. #if !PRIVATECLASS
  78.     AddClass( cl );            /* make public and available    */
  79. #endif
  80.     }
  81.     return ( cl );
  82. }
  83.  
  84. freeEmbBClass( cl )
  85. Class    *cl;
  86. {
  87.     return ( FreeClass( cl )  );
  88. }
  89.  
  90. ULONG  __saveds
  91. dispatchEmbB( cl, o, msg )
  92. Class   *cl;
  93. Object  *o;
  94. Msg     msg;
  95. {
  96.     Object          *newobj;
  97.     struct EmbBData     *ebd;
  98.  
  99.     switch ( msg->MethodID )
  100.     {
  101.     case OM_NEW:
  102.     /* let superclass do it's creation routine first    */
  103.     if ( newobj = (Object *) DSM( cl, o, msg ) )
  104.     {
  105.         /* init my instance data    */
  106.  
  107.         /* get pointer to it, like a good fellow    */
  108.         ebd = INST_DATA( cl, newobj );
  109.  
  110.         /* mandatory default init */
  111.         ebd->ebd_LineWidth = DEFAULTLINEWIDTH;
  112.  
  113.         /* may override ebd_LineWidth    */
  114.         setEmbBAttrs( cl, newobj, msg );
  115.     }
  116.  
  117.     return ( (ULONG) newobj );
  118.  
  119.     case OM_GET:
  120.     return ( (ULONG) getEmbBAttrs( cl, o, msg  ) );
  121.  
  122.     case OM_SET:
  123.     DSM( cl, o, msg );        /* let the superclass see the atts */
  124.     setEmbBAttrs( cl, o, msg  );    /* set the ones I care about       */
  125.     return ( (ULONG) 1 );        /* i'm happy               */
  126.  
  127.     case IM_DRAW:            /* draw with state */
  128.     return ( (ULONG) drawEmbB( cl, o, msg ) );
  129.  
  130.     /* use superclass defaults */
  131.     case IM_HITTEST:
  132.     case IM_ERASE:
  133.     case OM_DISPOSE:
  134.     default:
  135.     return ( (ULONG) DSM( cl, o, msg ) );
  136.     }
  137. }
  138.  
  139. drawEmbB( cl, o, msg )
  140. Class        *cl;
  141. Object        *o;
  142. struct impDraw    *msg;
  143. {
  144.     struct EmbBData     *ebd = INST_DATA( cl, o );
  145.     struct IBox        box;
  146.  
  147.     UWORD        *pens;        /* pen spec array */
  148.     UWORD        ulpen;        /* upper left    */
  149.     UWORD        lrpen;        /* lower right    */
  150.     UWORD        fillpen;    /* filled area    */
  151.  
  152.     /* let's be sure that we were passed a DrawInfo    */
  153.     pens =  ( msg->imp_DrInfo )?  msg->imp_DrInfo->dri_Pens: NULL;
  154.  
  155.     box = *IM_BOX( IM(o) );        /* get Image.Left/Top/Width/Height */
  156.     box.Left += msg->imp_Offset.X;
  157.     box.Top += msg->imp_Offset.Y;
  158.  
  159.     switch ( msg->imp_State )
  160.     {
  161.     case IDS_SELECTED:
  162.     case IDS_INACTIVESELECTED:
  163.     ulpen = pens? pens[ shadowPen ]: 2;
  164.     lrpen = pens? pens[ shinePen ]: 1;
  165.     fillpen = pens? pens[ hifillPen ]: 3;
  166.     break;
  167.  
  168.     case IDS_NORMAL:    /* doesn't use activefill in borders now */
  169.     case IDS_DISABLED:    /* I don't have a ghosted version yet     */
  170.     case IDS_INACTIVENORMAL:    /* doesn't use activefill in borders now */
  171.     default:
  172.     ulpen = pens? pens[ shinePen ]: 2;
  173.     lrpen = pens? pens[ shadowPen ]: 1;
  174.     fillpen = pens? pens[ backgroundPen ]: 0;
  175.     break;
  176.     }
  177.  
  178.     embossedBoxTrim( msg->imp_RPort, &box,
  179.     ebd->ebd_LineWidth, ebd->ebd_LineWidth,
  180.     ulpen, lrpen );
  181.  
  182.     /* interior */
  183.     interiorBox( msg->imp_RPort, &box,
  184.     ebd->ebd_LineWidth,    /* inset in x dim */
  185.     ebd->ebd_LineWidth,    /* inset in y dim */
  186.     fillpen );
  187. }
  188.  
  189. /* return requested attribute value    */
  190. getEmbBAttrs( cl, o, msg )
  191. Class        *cl;
  192. Object        *o;
  193. struct opGet    *msg;
  194. {
  195.     struct EmbBData     *ebd = INST_DATA( cl, o );
  196.  
  197.     if ( msg->opg_AttrID == IA_LINEWIDTH )
  198.     {
  199.         *msg->opg_Storage = ebd->ebd_LineWidth;
  200.     return ( 1 );
  201.     }
  202.     else
  203.         return ( DSM( cl, o, msg ) );
  204.  
  205. }
  206.  
  207. /* set specified attribute value.
  208.  * Technique provided is a little more general than we need ...
  209.  */
  210. setEmbBAttrs( cl, o, msg )
  211. Class        *cl;
  212. Object        *o;
  213. struct opSet    *msg;
  214. {
  215.     struct TagItem    *NextTagItem();
  216.     struct TagItem    *tags = msg->ops_AttrList;
  217.     struct TagItem    *tag;
  218.     ULONG        tidata;
  219.  
  220.     struct EmbBData     *ebd = INST_DATA( cl, o );
  221.  
  222.     while ( tag = NextTagItem( &tags ) )
  223.     {
  224.     tidata = tag->ti_Data;
  225.     switch ( tag->ti_Tag )
  226.     {
  227.     case IA_LINEWIDTH:
  228.         ebd->ebd_LineWidth = tidata;
  229.         break;
  230.     }
  231.     }
  232. }
  233.  
  234. /* fill region centered in a box */
  235. interiorBox( rp, b, xw, yw, pen )
  236. struct RastPort    *rp;
  237. struct IBox    *b;
  238. {
  239.     if ( (b->Width > (xw<<1)) && (b->Height > (yw<<1)) )
  240.     {
  241.     rp->Mask = -1;
  242.     BNDRYOFF( rp );
  243.     SetAfPt(rp, NULL, 0);
  244.     SetDrMd(rp, JAM2);
  245.     SetAPen(rp, pen);
  246.     RectFill( rp,
  247.         b->Left + xw,
  248.         b->Top + yw,
  249.         b->Left + b->Width - 1 - xw,
  250.         b->Top + b->Height - 1 - yw );
  251.     }
  252. }
  253.  
  254. /* suggestion of Talin: don't draw upper-right and lower-left points */
  255. /* ignoring thickness for now    */
  256. embossedBoxTrim( rp, b, hthick, vthick, ulpen, lrpen )
  257. struct RastPort    *rp;
  258. struct IBox    *b;
  259. {
  260.     int    bottom, right;
  261.  
  262.     bottom = b->Top + b->Height - 1;
  263.     right = b->Left + b->Width - 1;
  264.  
  265.     /* upper right edges    */
  266.     SetAPen( rp, ulpen );
  267.  
  268.     Move( rp, b->Left, bottom - 1 );
  269.     Draw( rp, b->Left, b->Top );
  270.     Draw( rp, right - 1, b->Top );
  271.  
  272.     /* lower right edges    */
  273.     SetAPen( rp, lrpen );
  274.  
  275.     Move( rp, right, b->Top + 1 );
  276.     Draw( rp, right, bottom );
  277.     Draw( rp, b->Left + 1, bottom );
  278. }
  279.  
  280.