home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Programming / C / MAXON_C3.DMS / in.adf / Demos / ANSI-C / Intuition / relspecial.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-09-21  |  7.2 KB  |  300 lines

  1. /*
  2.  * relspecial.c - shows special gadget relativity
  3.  *
  4.  * (c) Copyright 1992 Commodore-Amiga, Inc.  All Rights Reserved.
  5.  * Preliminary and Confidential.
  6.  * 
  7.  * Special gadget relativity allows a gadget to arbitrarily resize
  8.  * itself whenever the window changes size.  This is a complete superset
  9.  * of the functionality of the old GRELWIDTH, GRELRIGHT, etc., features.
  10.  * This example shows a subclass of gadgetclass whose imagery comes
  11.  * from frameiclass.  This gadget's property is that it is always half
  12.  * the size of its domain, and centered within it.  That is, it's always
  13.  * half as wide and half as tall as the inner area of its window, and
  14.  * centered within that area.
  15.  */
  16.  
  17. #include <intuition/intuition.h>
  18. #include <intuition/gadgetclass.h>
  19. #include <intuition/imageclass.h>
  20. #include <intuition/cghooks.h>
  21. #include <intuition/classes.h>
  22. #include <intuition/classusr.h>
  23.  
  24. #include <clib/alib_protos.h>
  25. #include <clib/exec_protos.h>
  26. #include <clib/graphics_protos.h>
  27. #include <clib/intuition_protos.h>
  28.  
  29. struct Library *GfxBase = NULL;
  30. struct Library *IntuitionBase = NULL;
  31. struct Window *win = NULL;
  32. struct Gadget *gad = NULL;
  33. Class *specialrelclass = NULL;
  34.  
  35. Class *initSpecialRelClass(void);
  36. ULONG __saveds __asm dispatchSpecialRel( register __a0 Class *cl,
  37.     register __a2 Object *o, register __a1 Msg msg );
  38. void renderSpecialRel( struct Gadget *gad, struct RastPort *rp,
  39.     struct GadgetInfo *gi );
  40. void layoutSpecialRel( struct Gadget *gad, struct GadgetInfo *gi,
  41.     ULONG initial );
  42. LONG handleSpecialRel( struct Gadget *gad, struct gpInput *msg );
  43.  
  44.  
  45. void main(void)
  46. {
  47.     if ( GfxBase = OpenLibrary("graphics.library",39) )
  48.     {
  49.     if ( IntuitionBase = OpenLibrary("intuition.library",39) )
  50.     {
  51.         if ( specialrelclass = initSpecialRelClass() )
  52.         {
  53.         if ( gad = NewObject( specialrelclass, NULL,
  54.             GA_Left, 20,
  55.             GA_Top, 20,
  56.             GA_Width, 20,
  57.             GA_Height, 20,
  58.             GA_RelVerify, TRUE,
  59.             GA_Immediate, TRUE,
  60.             TAG_DONE ) )
  61.         {
  62.             if ( win = OpenWindowTags( NULL,
  63.             WA_Title, "Special Relativity Demo",
  64.             WA_CloseGadget, TRUE,
  65.             WA_DepthGadget, TRUE,
  66.             WA_DragBar, TRUE,
  67.             WA_SizeGadget, TRUE,
  68.             WA_Gadgets, gad,
  69.             WA_Activate, TRUE,
  70.             WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_GADGETDOWN | IDCMP_GADGETUP,
  71.             WA_Width, 150,
  72.             WA_Height, 150,
  73.             WA_MinWidth, 50,
  74.             WA_MinHeight, 50,
  75.             WA_MaxWidth, ~0,
  76.             WA_MaxHeight, ~0,
  77.             WA_NoCareRefresh, TRUE,
  78.             TAG_DONE ) )
  79.             {
  80.             BOOL terminated = FALSE;
  81.             struct IntuiMessage *imsg;
  82.  
  83.             while ( !terminated )
  84.             {
  85.                 Wait( 1 << win->UserPort->mp_SigBit );
  86.                 while ( imsg = (struct IntuiMessage *)GetMsg( win->UserPort ) )
  87.                 {
  88.                 switch ( imsg->Class )
  89.                 {
  90.                 case IDCMP_CLOSEWINDOW:
  91.                     terminated = TRUE;
  92.                     break;
  93.  
  94.                 case IDCMP_GADGETUP:
  95.                     printf("Gadget up\n");
  96.                     break;
  97.  
  98.                 case IDCMP_GADGETDOWN:
  99.                     printf("Gadget down\n");
  100.                     break;
  101.                 }
  102.                 ReplyMsg( (struct Message *)imsg );
  103.                 }
  104.             }
  105.             CloseWindow( win );
  106.             }
  107.             DisposeObject( gad );
  108.         }
  109.         FreeClass( specialrelclass );
  110.         }
  111.         CloseLibrary( IntuitionBase );
  112.     }
  113.     CloseLibrary( GfxBase );
  114.     }
  115. }
  116.  
  117.  
  118. /* initSpecialRelClass()
  119.  *
  120.  * Initialize a simple private subclass of gadgetclass that
  121.  * knows about GM_LAYOUT.
  122.  *
  123.  */
  124.  
  125. Class *initSpecialRelClass( void )
  126. {
  127.     Class *cl;
  128.  
  129.     /* Create a private class: */
  130.     if ( cl = MakeClass( NULL, "gadgetclass", NULL, 0, 0 ) )
  131.     {
  132.     cl->cl_Dispatcher.h_SubEntry = NULL;
  133.     cl->cl_Dispatcher.h_Entry = dispatchSpecialRel;
  134.     cl->cl_Dispatcher.h_Data = NULL;
  135.     }
  136.     return ( cl );
  137. }
  138.  
  139. /* dispatchSpecialRel()
  140.  *
  141.  * boopsi dispatcher for the special relativity class.
  142.  *
  143.  */
  144.  
  145. ULONG __saveds __asm
  146. dispatchSpecialRel( register __a0 Class *cl,
  147.             register __a2 Object *o,
  148.             register __a1 Msg msg )
  149. {
  150.     ULONG retval = 1;
  151.     Object *newobj;
  152.  
  153.     switch ( msg->MethodID )
  154.     {
  155.     case OM_NEW:
  156.     if ( retval = (ULONG)(newobj = (Object *) DoSuperMethodA( cl, o, msg )) )
  157.     {
  158.         /* Set special relativity */
  159.         ((struct Gadget *)newobj)->Flags |= GFLG_RELSPECIAL;
  160.         /* Attempt to allocate a frame.  If I can't, then
  161.          * delete myself and fail.
  162.          */
  163.         if ( ! ( ((struct Gadget *)newobj)->GadgetRender =
  164.         NewObject( NULL, "frameiclass", TAG_DONE ) ) )
  165.         {
  166.         CoerceMethod( cl, o, OM_DISPOSE );
  167.         retval = NULL;
  168.         }
  169.     }
  170.     break;
  171.  
  172.     case GM_LAYOUT:
  173.     layoutSpecialRel( (struct Gadget *)o, ((struct gpLayout *)msg)->gpl_GInfo,
  174.         ((struct gpLayout *)msg)->gpl_Initial );
  175.     break;
  176.  
  177.     case GM_RENDER:
  178.     renderSpecialRel( (struct Gadget *)o, ((struct gpRender *) msg)->gpr_RPort,
  179.         ((struct gpRender *) msg)->gpr_GInfo );
  180.     break;
  181.  
  182.     case GM_GOACTIVE:
  183.     return( GMR_MEACTIVE );
  184.     break;
  185.  
  186.     case GM_HANDLEINPUT:
  187.     retval = handleSpecialRel( (struct Gadget *)o, (struct gpInput *)msg );
  188.     break;
  189.  
  190.     case OM_DISPOSE:
  191.     DisposeObject( ((struct Gadget *)o)->GadgetRender );
  192.     /* fall through to default */
  193.     default:
  194.     retval = (ULONG) DoSuperMethodA( cl, o, msg );
  195.     }
  196.     return( retval );
  197. }
  198.  
  199.  
  200. /* renderSpecialRel()
  201.  *
  202.  * Simple routine to draw my imagery based on my selected state.
  203.  *
  204.  */
  205. void
  206. renderSpecialRel( struct Gadget *gad, struct RastPort *rp, struct GadgetInfo *gi )
  207. {
  208.     DrawImageState( rp, gad->GadgetRender, gad->LeftEdge, gad->TopEdge,
  209.     (gad->Flags & GFLG_SELECTED) ? IDS_SELECTED : IDS_NORMAL,
  210.     gi ? gi->gi_DrInfo : NULL );
  211. }
  212.  
  213.  
  214. /* layoutSpecialRel()
  215.  *
  216.  * Lay myself out based on my domain dimensions.  Refigure my own size,
  217.  * then inform my image of the size change.
  218.  *
  219.  */
  220. void
  221. layoutSpecialRel( struct Gadget *gad, struct GadgetInfo *gi, ULONG initial )
  222. {
  223.     if ( gi->gi_Requester )
  224.     {
  225.     /* Center it within the requester */
  226.     gad->Width = gi->gi_Domain.Width / 2;
  227.     gad->Height = gi->gi_Domain.Height / 2;
  228.     gad->LeftEdge = gad->Width / 2;
  229.     gad->TopEdge = gad->Height / 2;
  230.     }
  231.     else
  232.     {
  233.     /* Center it within the window, after accounting for
  234.      * the window borders
  235.      */
  236.     gad->Width = ( gi->gi_Domain.Width -
  237.         gi->gi_Window->BorderLeft - gi->gi_Window->BorderRight ) / 2;
  238.     gad->Height = ( gi->gi_Domain.Height -
  239.         gi->gi_Window->BorderTop - gi->gi_Window->BorderBottom ) / 2;
  240.     gad->LeftEdge = ( gad->Width / 2 ) + gi->gi_Window->BorderLeft;
  241.     gad->TopEdge = ( gad->Height / 2 ) + gi->gi_Window->BorderTop;
  242.     }    
  243.     SetAttrs( gad->GadgetRender,
  244.     IA_Width, gad->Width,
  245.     IA_Height, gad->Height,
  246.     TAG_DONE );
  247. }
  248.  
  249.  
  250. /* handleSpecialRel()
  251.  *
  252.  * Routine to handle input to the gadget.  Behaves like a basic
  253.  * hit-select gadget.
  254.  *
  255.  */
  256. LONG
  257. handleSpecialRel( struct Gadget *gad, struct gpInput *msg )
  258. {
  259.     WORD selected = 0;
  260.     struct RastPort *rp;
  261.     LONG retval = GMR_MEACTIVE;
  262.  
  263.     /* Could send IM_HITTEST to image instead */
  264.     if ( ( msg->gpi_Mouse.X >= 0 ) &&
  265.     ( msg->gpi_Mouse.X < gad->Width ) &&
  266.     ( msg->gpi_Mouse.Y >= 0 ) &&
  267.     ( msg->gpi_Mouse.Y < gad->Height ) )
  268.     {
  269.     selected = GFLG_SELECTED;
  270.     }
  271.  
  272.     if ((msg->gpi_IEvent->ie_Class == IECLASS_RAWMOUSE) &&
  273.     (msg->gpi_IEvent->ie_Code == SELECTUP))
  274.     {
  275.     /* gadgetup, time to go */
  276.     if ( selected )
  277.     {
  278.         retval = GMR_NOREUSE | GMR_VERIFY;
  279.     }
  280.     else
  281.     {
  282.         retval = GMR_NOREUSE;
  283.     }
  284.     /* and unselect the gadget on our way out... */
  285.     selected = 0;
  286.     }
  287.  
  288.     if ( ( gad->Flags & GFLG_SELECTED ) != selected )
  289.     {
  290.     gad->Flags ^= GFLG_SELECTED;
  291.     if ( rp = ObtainGIRPort( msg->gpi_GInfo ) )
  292.     {
  293.         DoMethod( (Object *)gad, GM_RENDER, msg->gpi_GInfo, rp, GREDRAW_UPDATE );
  294.         ReleaseGIRPort( rp );
  295.     }
  296.     }
  297.  
  298.     return( retval );
  299. }
  300.