home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD v1.2 / amidev_cd_12.iso / reference / amiga_mail_vol2 / iv-111 / relative.c < prev   
C/C++ Source or Header  |  1996-01-30  |  11KB  |  387 lines

  1. ;/*
  2. sc DATA=NEAR NMINC STRMERGE NOSTKCHK SAVEDS IGNORE=73 relative
  3. slink FROM LIB:c.o relative.o TO relative LIB LIB:sc.lib LIB:amiga.lib
  4. quit
  5. */
  6.  
  7. /* (c)  Copyright 1993 Commodore-Amiga, Inc.   All rights reserved. */
  8. /* The information contained herein is subject to change without    */
  9. /* notice, and is provided "as is" without warranty of any kind,    */
  10. /* either expressed or implied.  The entire risk as to the use of   */
  11. /* this information is assumed by the user.                         */
  12.  
  13. /*
  14.  * relative.c - shows custom gadget relativity
  15.  *
  16.  * custom gadget relativity allows a gadget to arbitrarily resize
  17.  * itself whenever the window changes size.  This is a complete superset
  18.  * of the functionality of the old GRELWIDTH, GRELRIGHT, etc., features.
  19.  * This example shows a subclass of gadgetclass whose imagery comes
  20.  * from frameiclass.  This gadget's property is that it is always half
  21.  * the size of its domain, and centered within it.  That is, it's always
  22.  * half as wide and half as tall as the inner area of its window, and
  23.  * centered within that area.
  24.  */
  25.  
  26.  
  27. #include <intuition/intuition.h>
  28. #include <intuition/gadgetclass.h>
  29. #include <intuition/imageclass.h>
  30. #include <intuition/cghooks.h>
  31. #include <intuition/classes.h>
  32. #include <intuition/classusr.h>
  33.  
  34. #include <clib/alib_protos.h>
  35. #include <clib/alib_stdio_protos.h>
  36. #include <clib/exec_protos.h>
  37. #include <clib/graphics_protos.h>
  38. #include <clib/intuition_protos.h>
  39.  
  40. struct Library *GfxBase = NULL;
  41. struct Library *IntuitionBase = NULL;
  42. struct Window *win = NULL;
  43. struct Gadget *gad = NULL;
  44. Class *customrelclass = NULL;
  45.  
  46. Class *initCustomRelClass(void);
  47. ULONG __saveds __asm dispatchCustomRel( register __a0 Class *cl,
  48.                                          register __a2 Object *o,
  49.                                          register __a1 Msg msg );
  50. void                 renderCustomRel( struct Gadget *gad,
  51.                                        struct RastPort *rp,
  52.                                        struct GadgetInfo *gi );
  53. void                 layoutCustomRel( struct Gadget *gad,
  54.                                        struct GadgetInfo *gi,
  55.                                        ULONG initial );
  56. LONG                 handleCustomRel( struct Gadget *gad,
  57.                                        struct gpInput *msg );
  58.  
  59. void main(void)
  60. {
  61.   if ( GfxBase = OpenLibrary("graphics.library",39) )
  62.   {
  63.     if ( IntuitionBase = OpenLibrary("intuition.library",39) )
  64.     {
  65.       if ( customrelclass = initCustomRelClass() )
  66.       {
  67.         if ( gad = NewObject( customrelclass, NULL,
  68.             GA_Left, 20,
  69.             GA_Top, 20,
  70.             GA_Width, 20,
  71.             GA_Height, 20,
  72.             GA_RelVerify, TRUE,
  73.             GA_Immediate, TRUE,
  74.             TAG_DONE ) )
  75.         {
  76.           if ( win = OpenWindowTags( NULL,
  77.               WA_Title, "Custom Relativity Demo",
  78.               WA_CloseGadget, TRUE,
  79.               WA_DepthGadget, TRUE,
  80.               WA_DragBar, TRUE,
  81.               WA_SizeGadget, TRUE,
  82.               WA_Gadgets, gad,
  83.               WA_Activate, TRUE,
  84.               WA_IDCMP, IDCMP_GADGETHELP | IDCMP_RAWKEY | IDCMP_CLOSEWINDOW |
  85.                         IDCMP_GADGETDOWN | IDCMP_GADGETUP,
  86.               WA_Width, 150,
  87.               WA_Height, 150,
  88.               WA_MinWidth, 50,
  89.               WA_MinHeight, 50,
  90.               WA_MaxWidth, ~0,
  91.               WA_MaxHeight, ~0,
  92.               WA_NoCareRefresh, TRUE,
  93.               TAG_DONE ) )
  94.           {
  95.             BOOL terminated = FALSE;
  96.             struct IntuiMessage *imsg;
  97.  
  98.             /* Turn on Gadget Help */
  99.             HelpControl( win, HC_GADGETHELP );
  100.  
  101.             while (!terminated)
  102.             {
  103.               Wait (1 << win->UserPort->mp_SigBit);
  104.               while (imsg = (struct IntuiMessage *) GetMsg(win->UserPort))
  105.               {
  106.                 switch ( imsg->Class )
  107.                 {
  108.                 case IDCMP_CLOSEWINDOW:
  109.                   terminated = TRUE;
  110.                   break;
  111.  
  112.                 case IDCMP_RAWKEY:
  113.                   printf("RAWKEY %lx\n", imsg->Code);
  114.                   break;
  115.  
  116.                 case IDCMP_GADGETUP:
  117.                   printf("Gadget Up\n");
  118.                   break;
  119.  
  120.                 case IDCMP_GADGETDOWN:
  121.                   printf("Gadget Down\n");
  122.                   break;
  123.  
  124.                 case IDCMP_GADGETHELP:
  125.                   if ( imsg->IAddress == NULL )
  126.                   {
  127.                     printf("Gadget Help: Mouse not over window\n");
  128.                   }
  129.                   else if ( imsg->IAddress == (APTR) win )
  130.                   {
  131.                     printf("Gadget Help: Mouse in window, not over a gadget\n");
  132.                   }
  133.                   else
  134.                   {
  135.                     /* Detect system gadgets.  Figure out by looking at
  136.                      * system-gadget-type bits in GadgetType field:
  137.                      */
  138.                     LONG sysgtype =
  139.                       ((struct Gadget *)imsg->IAddress)->GadgetType & GTYP_SYSTYPEMASK;
  140.                     switch ( sysgtype )
  141.                     {
  142.                     case GTYP_SIZING:
  143.                       printf("Gadget Help for window sizing gadget\n");
  144.                       break;
  145.  
  146.                     case GTYP_WDRAGGING:
  147.                       printf("Gadget Help for window drag-bar\n");
  148.                       break;
  149.  
  150.                     case GTYP_WUPFRONT:
  151.                       printf("Gadget Help for window depth gadget\n");
  152.                       break;
  153.  
  154.                     case GTYP_WDOWNBACK:
  155.                       printf("Gadget Help for window zoom gadget\n");
  156.                       break;
  157.  
  158.                     case GTYP_CLOSE:
  159.                       printf("Gadget Help for window close gadget\n");
  160.                       break;
  161.  
  162.                     case 0:
  163.                       /* In this example, we only have one gadget,
  164.                        * so we know which one it is.  Normally, you'd
  165.                        * have to figure that out here, using the
  166.                        * usual techniques you already use for other
  167.                        * gadget messages.
  168.                        */
  169.                       printf("Gadget Help for gadget, code 0x%x\n",
  170.                           imsg->Code);
  171.                       break;
  172.  
  173.                     default:
  174.                       printf("Gadget Help on some other system gadget\n");
  175.                       break;
  176.                     }
  177.                   }
  178.                 }
  179.                 ReplyMsg((struct Message *)imsg);
  180.               }
  181.             }
  182.             CloseWindow( win );
  183.           }
  184.           DisposeObject( gad );
  185.         }
  186.         FreeClass( customrelclass );
  187.       }
  188.       CloseLibrary( IntuitionBase );
  189.     }
  190.     CloseLibrary( GfxBase );
  191.   }
  192. }
  193.  
  194.  
  195. /* initCustomRelClass()
  196.  *
  197.  * Initialize a simple private subclass of gadgetclass that
  198.  * knows about GM_LAYOUT.
  199.  *
  200.  */
  201.  
  202. Class *initCustomRelClass( void )
  203. {
  204.   Class *cl;
  205.  
  206.   /* Create a private class: */
  207.   if ( cl = MakeClass( NULL, "gadgetclass", NULL, 0, 0 ) )
  208.   {
  209.     cl->cl_Dispatcher.h_SubEntry = NULL;
  210.     cl->cl_Dispatcher.h_Entry = dispatchCustomRel;
  211.     cl->cl_Dispatcher.h_Data = NULL;
  212.   }
  213.   return ( cl );
  214. }
  215.  
  216. /* dispatchCustomRel()
  217.  *
  218.  * boopsi dispatcher for the custom relativity class.
  219.  *
  220.  */
  221.  
  222. ULONG __saveds __asm
  223. dispatchCustomRel( register __a0 Class *cl,
  224.                     register __a2 Object *o,
  225.                     register __a1 Msg msg )
  226. {
  227.   ULONG retval = 1;
  228.   Object *newobj;
  229.  
  230.   switch ( msg->MethodID )
  231.   {
  232.   case OM_NEW:
  233.     if ( retval = (ULONG)(newobj = (Object *) DoSuperMethodA( cl, o, msg )) )
  234.     {
  235.       /* Set custom relativity */
  236.       ((struct Gadget *)newobj)->Flags |= GFLG_RELSPECIAL;
  237.  
  238.       /* Tell Intuition this gadget supports gadget help */
  239.       SetAttrs(newobj, GA_GadgetHelp, TRUE, TAG_DONE, NULL);
  240.  
  241.       /* Attempt to allocate a frame.  If I can't, then
  242.        * delete myself and fail.
  243.        */
  244.       if ( ! ( ((struct Gadget *)newobj)->GadgetRender =
  245.           NewObject( NULL, "frameiclass",
  246.                      IA_FrameType, FRAME_BUTTON,
  247.                      TAG_DONE ) ) )
  248.       {
  249.         CoerceMethod( cl, o, OM_DISPOSE );
  250.         retval = NULL;
  251.       }
  252.     }
  253.     break;
  254.  
  255.   case GM_LAYOUT:
  256.     layoutCustomRel( (struct Gadget *)o, ((struct gpLayout *)msg)->gpl_GInfo,
  257.         ((struct gpLayout *)msg)->gpl_Initial );
  258.     break;
  259.  
  260.   case GM_RENDER:
  261.     renderCustomRel( (struct Gadget *)o, ((struct gpRender *) msg)->gpr_RPort,
  262.         ((struct gpRender *) msg)->gpr_GInfo );
  263.     break;
  264.  
  265.   case GM_GOACTIVE:
  266.     return( GMR_MEACTIVE );
  267.     break;
  268.  
  269.   case GM_HELPTEST:
  270.     return(GMR_HELPCODE | 0x0000C0DE);
  271.     break;
  272.  
  273.   case GM_HANDLEINPUT:
  274.     retval = handleCustomRel( (struct Gadget *)o, (struct gpInput *)msg );
  275.     break;
  276.  
  277.   case OM_DISPOSE:
  278.     DisposeObject( ((struct Gadget *)o)->GadgetRender );
  279.     /* fall through to default */
  280.   default:
  281.     retval = (ULONG) DoSuperMethodA( cl, o, msg );
  282.   }
  283.   return( retval );
  284. }
  285.  
  286.  
  287. /* renderCustomRel()
  288.  *
  289.  * Simple routine to draw my imagery based on my selected state.
  290.  *
  291.  */
  292. void
  293. renderCustomRel( struct Gadget *gad, struct RastPort *rp, struct GadgetInfo *gi )
  294. {
  295.   DrawImageState( rp, gad->GadgetRender, gad->LeftEdge, gad->TopEdge,
  296.       (gad->Flags & GFLG_SELECTED) ? IDS_SELECTED : IDS_NORMAL,
  297.       gi ? gi->gi_DrInfo : NULL );
  298. }
  299.  
  300.  
  301. /* layoutCustomRel()
  302.  *
  303.  * Lay myself out based on my domain dimensions.  Refigure my own size,
  304.  * then inform my image of the size change.
  305.  *
  306.  */
  307. void
  308. layoutCustomRel( struct Gadget *gad, struct GadgetInfo *gi, ULONG initial )
  309. {
  310.   if ( gi->gi_Requester )
  311.   {
  312.     /* Center it within the requester */
  313.     gad->Width = gi->gi_Domain.Width / 2;
  314.     gad->Height = gi->gi_Domain.Height / 2;
  315.     gad->LeftEdge = gad->Width / 2;
  316.     gad->TopEdge = gad->Height / 2;
  317.   }
  318.   else
  319.   {
  320.     /* Center it within the window, after accounting for
  321.      * the window borders
  322.      */
  323.     gad->Width = ( gi->gi_Domain.Width -
  324.         gi->gi_Window->BorderLeft - gi->gi_Window->BorderRight ) / 2;
  325.     gad->Height = ( gi->gi_Domain.Height -
  326.         gi->gi_Window->BorderTop - gi->gi_Window->BorderBottom ) / 2;
  327.     gad->LeftEdge = ( gad->Width / 2 ) + gi->gi_Window->BorderLeft;
  328.     gad->TopEdge = ( gad->Height / 2 ) + gi->gi_Window->BorderTop;
  329.   }
  330.   SetAttrs( gad->GadgetRender,
  331.     IA_Width, gad->Width,
  332.     IA_Height, gad->Height,
  333.     TAG_DONE );
  334. }
  335.  
  336.  
  337. /* handleCustomRel()
  338.  *
  339.  * Routine to handle input to the gadget.  Behaves like a basic
  340.  * hit-select gadget.
  341.  *
  342.  */
  343. LONG
  344. handleCustomRel( struct Gadget *gad, struct gpInput *msg )
  345. {
  346.   WORD selected = 0;
  347.   struct RastPort *rp;
  348.   LONG retval = GMR_MEACTIVE;
  349.  
  350.   /* Could send IM_HITTEST to image instead */
  351.   if ( ( msg->gpi_Mouse.X >= 0 ) &&
  352.       ( msg->gpi_Mouse.X < gad->Width ) &&
  353.       ( msg->gpi_Mouse.Y >= 0 ) &&
  354.       ( msg->gpi_Mouse.Y < gad->Height ) )
  355.   {
  356.     selected = GFLG_SELECTED;
  357.   }
  358.  
  359.   if ((msg->gpi_IEvent->ie_Class == IECLASS_RAWMOUSE) &&
  360.       (msg->gpi_IEvent->ie_Code == SELECTUP))
  361.   {
  362.     /* gadgetup, time to go */
  363.     if ( selected )
  364.     {
  365.       retval = GMR_NOREUSE | GMR_VERIFY;
  366.     }
  367.     else
  368.     {
  369.       retval = GMR_NOREUSE;
  370.     }
  371.     /* and unselect the gadget on our way out... */
  372.     selected = 0;
  373.   }
  374.  
  375.   if ( ( gad->Flags & GFLG_SELECTED ) != selected )
  376.   {
  377.     gad->Flags ^= GFLG_SELECTED;
  378.     if ( rp = ObtainGIRPort( msg->gpi_GInfo ) )
  379.     {
  380.       DoMethod( (Object *)gad, GM_RENDER, msg->gpi_GInfo, rp, GREDRAW_UPDATE );
  381.       ReleaseGIRPort( rp );
  382.     }
  383.   }
  384.  
  385.   return( retval );
  386. }
  387.