home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / Reference / DevCon / Orlando_1993 / Devcon93.4 / ListView / listview.c next >
Encoding:
C/C++ Source or Header  |  1993-01-08  |  10.6 KB  |  331 lines

  1. ;/*
  2. SC RESOPT PARM=REGISTERS UCHAR CONSTLIB STREQ ANSI NOSTKCHK NOICONS OPT OPTPEEP listview.c
  3. Slink LIB:c.o listview.o TO ListView LIB LIB:sc.lib SC SD
  4. Quit
  5. */
  6.  
  7. /*
  8. COPYRIGHT: Unless otherwise noted, all files are Copyright (c) 1992-1993
  9. Commodore-Amiga, Inc.  All rights reserved.
  10.  
  11. DISCLAIMER: This software is provided "as is".  No representations or
  12. warranties are made with respect to the accuracy, reliability, performance,
  13. currentness, or operation of this software, and all use is at your own risk.
  14. Neither commodore nor the authors assume any responsibility or liability
  15. whatsoever with respect to your use of this software.
  16. */
  17.  
  18. /* listview.c - a simple program showing how to use listview rendering
  19.  * callback functions
  20.  */
  21.  
  22.  
  23. /****************************************************************************/
  24.  
  25.  
  26. #include <exec/types.h>
  27. #include <intuition/intuition.h>
  28. #include <intuition/gadgetclass.h>
  29. #include <utility/hooks.h>
  30. #include <libraries/gadtools.h>
  31. #include <graphics/gfxmacros.h>
  32. #include <string.h>
  33. #include <dos.h>
  34.  
  35. #include <clib/exec_protos.h>
  36. #include <clib/intuition_protos.h>
  37. #include <clib/alib_protos.h>
  38. #include <clib/gadtools_protos.h>
  39. #include <clib/graphics_protos.h>
  40.  
  41. #include <pragmas/exec_pragmas.h>
  42. #include <pragmas/intuition_pragmas.h>
  43. #include <pragmas/gadtools_pragmas.h>
  44. #include <pragmas/graphics_pragmas.h>
  45.  
  46.  
  47. /****************************************************************************/
  48.  
  49.  
  50. typedef unsigned long (*HOOKFUNC)();
  51.  
  52.  
  53. /****************************************************************************/
  54.  
  55.  
  56. static struct TextAttr topazAttr =
  57. {
  58.     "topaz.font",
  59.      8,
  60.      FS_NORMAL,
  61.      FPF_ROMFONT
  62. };
  63.  
  64.  
  65. /*****************************************************************************/
  66.  
  67.  
  68. extern struct Library *SysBase;
  69. struct Library        *GfxBase;
  70. struct Library        *IntuitionBase;
  71. struct Library        *GadToolsBase;
  72. struct Library        *UtilityBase;
  73.  
  74. struct Screen         *screen;
  75. struct Window         *window;
  76. struct DrawInfo       *drawInfo;
  77. APTR                   visualInfo;
  78.  
  79.  
  80. /*****************************************************************************/
  81.  
  82.  
  83. static UWORD GhostPattern[2] =
  84. {
  85.      0x4444,
  86.      0x1111,
  87. };
  88.  
  89.  
  90. /* Apply a ghosting pattern to a given rectangle in a rastport */
  91. static VOID Ghost(struct RastPort *rp, UWORD pen, UWORD x0, UWORD y0, UWORD x1, UWORD y1)
  92. {
  93.     SetABPenDrMd(rp,pen,0,JAM1);
  94.     SetAfPt(rp,GhostPattern,1);
  95.     RectFill(rp,x0,y0,x1,y1);
  96.     SetAfPt(rp,NULL,0);
  97. }
  98.  
  99.  
  100. /*****************************************************************************/
  101.  
  102.  
  103. /* Erase any part of "oldExtent" which is not covered by "newExtent" */
  104. VOID FillOldExtent(struct RastPort *rp,
  105.                    struct Rectangle *oldExtent,
  106.                    struct Rectangle *newExtent)
  107. {
  108.     if (oldExtent->MinX < newExtent->MinX)
  109.         RectFill(rp,oldExtent->MinX,
  110.                     oldExtent->MinY,
  111.                     newExtent->MinX-1,
  112.                     oldExtent->MaxY);
  113.  
  114.     if (oldExtent->MaxX > newExtent->MaxX)
  115.         RectFill(rp,newExtent->MaxX+1,
  116.                     oldExtent->MinY,
  117.                     oldExtent->MaxX,
  118.                     oldExtent->MaxY);
  119.  
  120.     if (oldExtent->MaxY > newExtent->MaxY)
  121.         RectFill(rp,oldExtent->MinX,
  122.                     newExtent->MaxY+1,
  123.                     oldExtent->MaxX,
  124.                     oldExtent->MaxY);
  125.  
  126.     if (oldExtent->MinY < newExtent->MinY)
  127.         RectFill(rp,oldExtent->MinX,
  128.                     oldExtent->MinY,
  129.                     oldExtent->MaxX,
  130.                     newExtent->MinY-1);
  131. }
  132.  
  133.  
  134. /*****************************************************************************/
  135.  
  136.  
  137. /* This function is called whenever an item of the listview needs to be drawn
  138.  * by gadtools. The function must fill every pixel of the area described in
  139.  * the LVDrawMsg structure. This function does the exact same rendering as
  140.  * the built-in rendering function in gadtools, except that it render the
  141.  * normal items using the highlight text pen instead of simply text pen.
  142.  */
  143. static ULONG __asm RenderHook(register __a1 struct LVDrawMsg *msg,
  144.                               register __a2 struct Node *node)
  145. {
  146. struct RastPort   *rp;
  147. UBYTE              state;
  148. struct TextExtent  extent;
  149. ULONG              fit;
  150. WORD               x,y;
  151. WORD               slack;
  152. ULONG              apen;
  153. ULONG              bpen;
  154. UWORD             *pens;
  155. STRPTR             name;
  156.  
  157.     geta4();
  158.  
  159.     if (msg->lvdm_MethodID != LV_DRAW)
  160.         return(LVCB_UNKNOWN);
  161.  
  162.     rp    = msg->lvdm_RastPort;
  163.     state = msg->lvdm_State;
  164.     pens  = msg->lvdm_DrawInfo->dri_Pens;
  165.  
  166.     apen = pens[FILLTEXTPEN];
  167.     bpen = pens[FILLPEN];
  168.     if ((state == LVR_NORMAL) || (state == LVR_NORMALDISABLED))
  169.     {
  170.         apen = pens[HIGHLIGHTTEXTPEN];    /* this is normally TEXTPEN */
  171.         bpen = pens[BACKGROUNDPEN];
  172.     }
  173.     SetABPenDrMd(rp,apen,bpen,JAM2);
  174.  
  175.     name = node->ln_Name;
  176.  
  177.     fit = TextFit(rp,name,strlen(name),&extent,NULL,1,
  178.                   msg->lvdm_Bounds.MaxX-msg->lvdm_Bounds.MinX-3,
  179.                   msg->lvdm_Bounds.MaxY-msg->lvdm_Bounds.MinY+1);
  180.  
  181.     slack = (msg->lvdm_Bounds.MaxY - msg->lvdm_Bounds.MinY) - (extent.te_Extent.MaxY - extent.te_Extent.MinY);
  182.  
  183.     x = msg->lvdm_Bounds.MinX - extent.te_Extent.MinX + 2;
  184.     y = msg->lvdm_Bounds.MinY - extent.te_Extent.MinY + ((slack+1) / 2);
  185.  
  186.     extent.te_Extent.MinX += x;
  187.     extent.te_Extent.MaxX += x;
  188.     extent.te_Extent.MinY += y;
  189.     extent.te_Extent.MaxY += y;
  190.  
  191.     Move(rp,x,y);
  192.     Text(rp,name,fit);
  193.  
  194.     SetAPen(rp,bpen);
  195.     FillOldExtent(rp,&msg->lvdm_Bounds,&extent.te_Extent);
  196.  
  197.     if ((state == LVR_NORMALDISABLED) || (state == LVR_SELECTEDDISABLED))
  198.     {
  199.         Ghost(rp,pens[BLOCKPEN],msg->lvdm_Bounds.MinX, msg->lvdm_Bounds.MinY,
  200.                                 msg->lvdm_Bounds.MaxX, msg->lvdm_Bounds.MaxY);
  201.     }
  202.  
  203.     return(LVCB_OK);
  204. }
  205.  
  206.  
  207. /*****************************************************************************/
  208.  
  209.  
  210. /* Main entry point. Init the universe, and do the event loop */
  211. LONG main(VOID)
  212. {
  213. BOOL                 quit;
  214. struct IntuiMessage *intuiMsg;
  215. struct Gadget       *gadgetList;
  216. struct Hook          renderHook;
  217. struct List          list;
  218. struct Node          nodes[5];
  219. struct NewGadget     ng;
  220.  
  221.     renderHook.h_Entry = (HOOKFUNC)RenderHook;
  222.  
  223.     nodes[0].ln_Name = "First Node";
  224.     nodes[1].ln_Name = "Second Node";
  225.     nodes[2].ln_Name = "Third Node";
  226.     nodes[3].ln_Name = "Fourth Node";
  227.     nodes[4].ln_Name = "Fifth Node";
  228.     NewList(&list);
  229.     AddTail(&list,&nodes[0]);
  230.     AddTail(&list,&nodes[1]);
  231.     AddTail(&list,&nodes[2]);
  232.     AddTail(&list,&nodes[3]);
  233.     AddTail(&list,&nodes[4]);
  234.  
  235.     /* open all basic libraries in case we need 'em later */
  236.     if (IntuitionBase = OpenLibrary("intuition.library", 39))
  237.     {
  238.         GfxBase       = OpenLibrary("graphics.library", 39);
  239.         GadToolsBase  = OpenLibrary("gadtools.library", 39);
  240.         UtilityBase   = OpenLibrary("utility.library", 39);
  241.     }
  242.  
  243.     /* check if we got everything we need */
  244.     if (IntuitionBase && GfxBase && GadToolsBase && UtilityBase)
  245.     {
  246.         if (screen = LockPubScreen(NULL))
  247.         {
  248.             if (drawInfo = GetScreenDrawInfo(screen))
  249.             {
  250.                 if (visualInfo = GetVisualInfoA(screen,NULL))
  251.                 {
  252.                     gadgetList = NULL;
  253.  
  254.                     ng.ng_LeftEdge   = 10;
  255.                     ng.ng_TopEdge    = screen->WBorTop + screen->Font->ta_YSize + 1 + 16;
  256.                     ng.ng_Width      = 200;
  257.                     ng.ng_Height     = 120;
  258.                     ng.ng_GadgetText = "A List Of Things";
  259.                     ng.ng_TextAttr   = &topazAttr;
  260.                     ng.ng_Flags      = 0;
  261.                     ng.ng_VisualInfo = visualInfo;
  262.  
  263.                     if (CreateGadget(LISTVIEW_KIND,CreateContext(&gadgetList),&ng,
  264.                                      GTLV_Labels,       &list,
  265.                                      GTLV_ShowSelected, NULL,
  266.                                      GTLV_ScrollWidth,  19,
  267.                                      GTLV_ItemHeight,   12,
  268.                                      GTLV_CallBack,     &renderHook,
  269.                                      GTLV_Selected,     0,
  270.                                      GTLV_MaxPen,       255,
  271.                                      TAG_DONE))
  272.                     {
  273.                         if (window = OpenWindowTags(NULL,
  274.                                           WA_InnerWidth,   220,
  275.                                           WA_InnerHeight,  150,
  276.                                           WA_IDCMP,        IDCMP_CLOSEWINDOW | IDCMP_REFRESHWINDOW | LISTVIEWIDCMP,
  277.                                           WA_DepthGadget,  TRUE,
  278.                                           WA_DragBar,      TRUE,
  279.                                           WA_CloseGadget,  TRUE,
  280.                                           WA_SimpleRefresh,TRUE,
  281.                                           WA_Activate,     TRUE,
  282.                                           WA_Title,        "ListView Tester",
  283.                                           WA_PubScreen,    screen,
  284.                                           WA_AutoAdjust,   TRUE,
  285.                                           WA_Gadgets,      gadgetList,
  286.                                           TAG_DONE))
  287.                         {
  288.                             GT_RefreshWindow(window,NULL);
  289.  
  290.                             quit = FALSE;
  291.                             while (!quit)
  292.                             {
  293.                                 WaitPort(window->UserPort);
  294.                                 if (intuiMsg = (struct IntuiMessage *)GT_GetIMsg(window->UserPort))
  295.                                 {
  296.                                     if (intuiMsg->Class == IDCMP_REFRESHWINDOW)
  297.                                     {
  298.                                         GT_BeginRefresh(window);
  299.                                         GT_EndRefresh(window,TRUE);
  300.                                     }
  301.                                     else if (intuiMsg->Class == IDCMP_CLOSEWINDOW)
  302.                                     {
  303.                                         quit = TRUE;
  304.                                     }
  305.                                     GT_ReplyIMsg(intuiMsg);
  306.                                 }
  307.                             }
  308.  
  309.                             CloseWindow(window);
  310.                         }
  311.                     }
  312.                     FreeGadgets(gadgetList);
  313.                     FreeVisualInfo(visualInfo);
  314.                 }
  315.                 FreeScreenDrawInfo(screen,drawInfo);
  316.             }
  317.             UnlockPubScreen(NULL,screen);
  318.         }
  319.     }
  320.  
  321.     if (IntuitionBase)
  322.     {
  323.         CloseLibrary(UtilityBase);
  324.         CloseLibrary(GadToolsBase);
  325.         CloseLibrary(GfxBase);
  326.         CloseLibrary(IntuitionBase);
  327.     }
  328.  
  329.     return(0);
  330. }
  331.