home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 3 / AACD03.BIN / CDTools / ClassAct / Examples / BackFill / BackfillExample.c < prev    next >
C/C++ Source or Header  |  1997-07-09  |  11KB  |  398 lines

  1. /*************************************************************************
  2.  * ClassAct Comprehensive Demo Program
  3.  * Copyright © 1995 Osma Ahvenlampi
  4.  *
  5.  */
  6.  
  7. #include <exec/types.h>
  8. #include <exec/memory.h>
  9. #include <intuition/intuition.h>
  10. #include <intuition/gadgetclass.h>
  11. #include <intuition/icclass.h>
  12. #include <libraries/gadtools.h>
  13. #include <graphics/gfxbase.h>
  14. #include <graphics/text.h>
  15. #include <graphics/gfxmacros.h>
  16. #include <utility/tagitem.h>
  17. #include <workbench/startup.h>
  18. #include <workbench/workbench.h>
  19. #include <datatypes/datatypes.h>
  20. #include <datatypes/datatypesclass.h>
  21.  
  22. #include <proto/datatypes.h>
  23. #include <proto/intuition.h>
  24. #include <proto/graphics.h>
  25. #include <proto/exec.h>
  26. #include <proto/dos.h>
  27. #include <proto/diskfont.h>
  28. #include <proto/utility.h>
  29. #include <proto/wb.h>
  30. #include <proto/icon.h>
  31.  
  32. #include <classact.h>
  33. #include <classact_lib.h>
  34. #include <clib/classact_lib_protos.h>
  35.  
  36. /* get LayerHook.lha from Aminet for this */
  37. #include <imagebackfill.h>
  38.  
  39. /*************************************************************************
  40.  * Backfill options
  41.  * We're using the public domain LayerHook here.
  42.  */
  43. struct BackFillOptions Options =
  44. {
  45.     256,256,
  46.     // !!! 0,0,
  47.     TRUE,FALSE,
  48.     0,0,
  49.     TRUE
  50. };
  51.  
  52. struct BackFillInfo BF1, BF2, *Backfill;
  53.  
  54. UBYTE name[256];
  55.  
  56. /*************************************************************************
  57.  * Gadget list
  58.  * This wouldn't be strictly necessary, but it's an easy way of keeping
  59.  * the gadget pointers for when we need to access the gadgets.
  60.  */
  61. typedef enum { G_Backfill = 1, G_Datatype, G_MAX } GadgetIDs;
  62.  
  63. struct Gadget *GL[G_MAX+1];
  64.  
  65. /*************************************************************************
  66.  * App message hook.
  67.  * Workbench App messages can be caught with a callback hook such as this.
  68.  * We'll not worry about the app message type in this hook. Objects dropped
  69.  * on the window or on the icon (while iconified) will be added to the 
  70.  * listview.
  71.  */
  72.  
  73. void __asm __saveds AppMsgFunc(    register __a0 struct Hook *Hook,
  74.                                 register __a2 Object *Window,
  75.                                 register __a1 struct AppMessage *Msg )
  76. {
  77.     struct Window *Win;
  78.     struct WBArg *arg = Msg->am_ArgList;
  79.     Object *dt;
  80.     
  81.     GetAttr( WINDOW_Window, Window, (ULONG *)&Win );
  82.  
  83.     NameFromLock( arg->wa_Lock, name, sizeof(name) );
  84.     AddPart( name, arg->wa_Name, sizeof(name) );
  85.     
  86.     dt = NewDTObject( name, 
  87.                     DTA_GroupID, GID_PICTURE, 
  88.                     ICA_TARGET, ICTARGET_IDCMP,
  89.                     TAG_END );
  90.     
  91.     if (dt)
  92.     {
  93.         SetGadgetAttrs( (struct Gadget *)Hook->h_Data, Win, NULL,
  94.                         LAYOUT_ModifyChild, GL[G_Datatype],
  95.                         CHILD_ReplaceObject, dt,
  96.                         TAG_END );
  97.         GL[G_Datatype] = (struct Gadget *)dt;
  98.         RethinkLayout( (struct Gadget *)Hook->h_Data, Win, NULL, FALSE );
  99.     }
  100. }
  101.  
  102. struct Hook apphook;
  103.  
  104. /*************************************************************************
  105.  * IDCMP hook
  106.  */
  107.  
  108. void __asm __saveds IDCMPFunc(    register __a0 struct Hook *Hook,
  109.                                 register __a2 Object *Window,
  110.                                 register __a1 struct IntuiMessage *Msg )
  111. {
  112.     struct Window *Win;
  113.     
  114.     GetAttr( WINDOW_Window, Window, (ULONG *)&Win );
  115.  
  116.     if (Msg->Class == IDCMP_IDCMPUPDATE)
  117.     {
  118.         if ( GetTagData( DTA_Sync, FALSE, Msg->IAddress ) )
  119.         {
  120.             RefreshGList( (struct Gadget *)Hook->h_Data, Win, NULL, 1 );
  121.         }
  122.     }
  123. }
  124.  
  125. struct Hook idcmphook;
  126.  
  127. /*************************************************************************
  128.  * This function creates our gadgets for the window.
  129.  */
  130. Object *CreateLayout(void)
  131. {
  132.     return VGroupObject, Offset(32,32,32,32),
  133.         LAYOUT_BevelStyle, BVS_THIN,
  134.                     
  135.         /* this tag instructs layout.gadget to defer GM_LAYOUT and GM_RENDER and ask
  136.          * the windowclass to do them. This lessens the load on input.device 
  137.          */
  138.         LAYOUT_DeferLayout, TRUE,
  139.         
  140.         /* this gives us a backfill
  141.          */
  142.         CLASSACT_BackFill, Backfill,
  143.         
  144.         /* this dummy object will be replaced with a datatype when we have a picture
  145.          */
  146.         StartMember, apphook.h_Data = idcmphook.h_Data = LayoutObject, VCentered, HCentered,
  147.             LAYOUT_BevelStyle, BVS_THIN,
  148.             LAYOUT_BevelState, IDS_SELECTED,
  149.             LAYOUT_SpaceOuter, TRUE,
  150.         
  151.             /* We need to install this clearing backfill hook because
  152.              * most of the datatypes really screw up rendering if the
  153.              * background isn't color 0.
  154.              */
  155.             LAYOUT_BackFill, LAYERS_BACKFILL,
  156.             StartImage, GL[G_Datatype] = LabelObject,
  157.                 LABEL_Text, "Please drop picture icons on this window",
  158.             EndImage,
  159.             CHILD_MinHeight, 128,
  160.         EndMember,
  161.         
  162.         StartMember, GL[G_Backfill] = ButtonObject,
  163.             GA_Text, "Use as a backfill",
  164.             GA_ID, G_Backfill,
  165.             GA_RelVerify, TRUE,
  166.         EndMember,
  167.         CHILD_WeightedHeight, 0,
  168.     EndGroup;
  169. }
  170.                 
  171. /*************************************************************************
  172.  * Main Program
  173.  */
  174. int 
  175. main(void)
  176. {
  177.     struct MsgPort *appport;
  178.     struct Screen *Scr;
  179.  
  180.     if (!ButtonBase) /* force it open */
  181.         return 30;
  182.         
  183.     /* By providing a message port you enable windowclass to handle iconification
  184.      * and appwindows. This port can shared by all the windows of your application.
  185.      */
  186.     appport = CreateMsgPort();
  187.     Scr = LockPubScreen(NULL);
  188.  
  189.     if (appport && Scr)
  190.     {
  191.         Object *Window;
  192.         
  193.         apphook.h_Entry = (ULONG (* )())AppMsgFunc;
  194.         apphook.h_SubEntry = NULL;
  195.  
  196.         idcmphook.h_Entry = (ULONG (* )())IDCMPFunc;
  197.         idcmphook.h_SubEntry = NULL;
  198.         
  199.         /* Create a Window object with a Layout. When Window is asked to open itself,
  200.          * it will calculate how much space the Layout needs and size itself accordingly.
  201.          */
  202.     
  203.         Window = WindowObject,
  204.                 
  205.                 /* these tags describe the window 
  206.                  */
  207.         
  208.                 WA_IDCMP, IDCMP_RAWKEY,
  209.                 WA_Top, 20,
  210.                 WA_Left, 20,
  211.                 WA_SizeGadget, TRUE,
  212.                 WA_DepthGadget, TRUE,
  213.                 WA_DragBar, TRUE,
  214.                 WA_CloseGadget, TRUE,
  215.                 WA_Activate, TRUE,
  216.                 
  217.                 WA_Title, "ClassAct backfill/datatype example",
  218.                 WA_ScreenTitle, "ClassAct Copyright 1995 Phantom Development LLC.",
  219.                 
  220.                 /* Add an iconification gadget. If you have this, you must listen to
  221.                  * WMHI_ICONIFY.
  222.                  */
  223.                  
  224.                 WINDOW_IconifyGadget, TRUE,
  225.                 
  226.                 /* This message port lets windowclass handle the icon and appwindow.
  227.                  */
  228.                  
  229.                 WINDOW_AppPort, appport,
  230.                 WINDOW_AppWindow, TRUE,
  231.                 WINDOW_AppMsgHook, &apphook,
  232.                 
  233.                 /* This sets up windowclass to relay IDCMPUPDATE messages to the
  234.                  * application's hook.
  235.                  */
  236.                  
  237.                 WINDOW_IDCMPHook, &idcmphook,
  238.                 WINDOW_IDCMPHookBits, IDCMP_IDCMPUPDATE,
  239.                 
  240.                 /* The windowclass will automatically free the DiskObject used when
  241.                  * iconifying the window. If you do not provide a valid DiskObject,
  242.                  * windowclass will try to use env:sys/def_window.info or the default
  243.                  * project icon.
  244.                  */
  245.                 
  246.                 WINDOW_Icon, GetDiskObject( "BackfillExample" ),
  247.                 WINDOW_IconTitle, "ClassAct Example",
  248.                 
  249.                 /* Below is the layout of the window 
  250.                  */
  251.                 
  252.                 WINDOW_Layout, CreateLayout(),
  253.             EndWindow;
  254.     
  255.         if (Window)
  256.         {
  257.             /* Window pointer cache.
  258.              */
  259.         
  260.             struct Window *Win;
  261.             BOOL changebackfill = FALSE;
  262.         
  263.             if (Win = CA_OpenWindow( Window ))
  264.             {
  265.                 ULONG wsig, asig = 1L << appport->mp_SigBit;
  266.                 BOOL done = FALSE;
  267.                 
  268.                 /* Now that the window has been opened, we can get the signal mask
  269.                  * of its user port. If the program supported iconification and didn't
  270.                  * use a shared IDCMP port between all windows, this signal bit
  271.                  * would have to be re-queried before each Wait().
  272.                  */
  273.                 
  274.                 GetAttr( WINDOW_SigMask, Window, &wsig );
  275.     
  276.                 while (done == FALSE)
  277.                 {
  278.                     ULONG sig = Wait(wsig | asig | SIGBREAKF_CTRL_C);
  279.                     ULONG result;
  280.                     UWORD code;
  281.  
  282.                     if (sig & (wsig | asig))
  283.                     {
  284.                         /* Messages waiting at the window's IDCMP port. Loop at WM_HANDLEINPUT
  285.                          * until all have been processed.
  286.                          */
  287.                     
  288.                         while ((result = CA_HandleInput(Window,&code)) != WMHI_LASTMSG)
  289.                         {
  290.                             /* The return code of this method is two-part. The upper word describes the
  291.                              * class of the message (gadgetup, menupick, closewindow, iconify, etc),
  292.                              * and the lower word is a class-defined ID, currently in use in the
  293.                              * gadgetup and menupick return codes.
  294.                              * Switch on the class, then on the ID.
  295.                              */
  296.                         
  297.                             switch(result & WMHI_CLASSMASK)
  298.                             {
  299.                             case WMHI_GADGETUP:
  300.                             
  301.                                 /* OK, got a gadgetup from something. Lets find out what the something is.
  302.                                  * The code WORD to which a pointer was passed to WM_HANDLEINPUT has been
  303.                                  * set to the Code value from the IDCMP_GADGETUP, in case we need it.
  304.                                  */
  305.                             
  306.                                 switch(result & WMHI_GADGETMASK)
  307.                                 {
  308.                                 case G_Backfill:
  309.                                     changebackfill = TRUE;
  310.                                     break;
  311.                                 }
  312.                                 break;
  313.                                 
  314.                             case WMHI_CLOSEWINDOW:
  315.                                 /* The window close gadget was hit. Time to die...
  316.                                  */
  317.                                 done = TRUE;
  318.                                 break;
  319.                                 
  320.                             case WMHI_ICONIFY:
  321.                                 /* Window requests that it be iconified. Handle this event as
  322.                                  * soon as possible. The window is not iconified automatically to
  323.                                  * give you a chance to make note that the window pointer will be 
  324.                                  * invalid before the window closes. It also allows you to free
  325.                                  * resources only needed when the window is open, if you wish to.
  326.                                  */
  327.                                 if (CA_Iconify( Window ))
  328.                                     Win = NULL;
  329.                                 break;
  330.                                  
  331.                             case WMHI_UNICONIFY:
  332.                                 /* The window should be reopened. If you had free'd something
  333.                                  * on iconify, now is the time to re-allocate it, before calling
  334.                                  * CA_OpenWindow.
  335.                                  */
  336.                                 Win = CA_OpenWindow( Window );
  337.                                 break;
  338.                             }
  339.                         }
  340.                     }
  341.                     else if (sig & SIGBREAKF_CTRL_C)
  342.                     {
  343.                         done = TRUE;
  344.                     }
  345.                     
  346.                     if (changebackfill)
  347.                     {
  348.                         Object *layout;
  349.                     
  350.                         /* This is a quick&dirty demo using an unmodified LayerHook (on Aminet).
  351.                          * This hook can not change its source bitmap on the fly.
  352.                          * Becaue of this, we have to do a bit of a juggling act to
  353.                          * replace the current backfill.
  354.                          */
  355.                         if (Backfill == &BF1)
  356.                         {
  357.                             Backfill = NULL;
  358.                             if (LoadBackgroundImage( &BF2, name, Scr, &Options ))
  359.                             {
  360.                                 Backfill = &BF2;
  361.                             }
  362.                         }
  363.                         else
  364.                         {
  365.                             Backfill = NULL;
  366.                             if (LoadBackgroundImage( &BF1, name, Scr, &Options ))
  367.                             {
  368.                                 Backfill = &BF1;
  369.                             }
  370.                         }
  371.                         if (layout = CreateLayout())
  372.                         {
  373.                             SetAttrs(Window, WINDOW_Layout, layout, TAG_END);
  374.                             /* backfill changed, it's not safe to dispose the old
  375.                              * one. */
  376.                             UnloadBackgroundImage((Backfill == &BF1) ? &BF2 : &BF1);
  377.                         }
  378.                         else
  379.                         {
  380.                             /* layout failed */
  381.                             UnloadBackgroundImage(Backfill);
  382.                         }
  383.                         changebackfill = FALSE;
  384.                     }
  385.                 }
  386.                 /* Close the window and dispose of all attached gadgets 
  387.                  */
  388.                 DisposeObject( Window );
  389.             }
  390.         }
  391.     }
  392.     
  393.     if (appport)
  394.         DeleteMsgPort(appport);
  395.     if (Scr)
  396.         UnlockPubScreen(NULL,Scr);
  397. }
  398.