home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Misc / CBMDevKit3.dms / CBMDevKit3.adf / intuition / relspecial.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-11-17  |  7.4 KB  |  303 lines

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