home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / amiga / utility / misc / toolmana.lha / ToolManager / Source / library / imageobj.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-09-26  |  13.7 KB  |  435 lines

  1. /*
  2.  * imageobj.c  V2.0
  3.  *
  4.  * TMObject, Type: Image
  5.  *
  6.  * (c) 1990-1992 Stefan Becker
  7.  */
  8.  
  9. #include "ToolManagerLib.h"
  10.  
  11. /* extended TMTimerReq structure */
  12. struct TMTimerReqImage {
  13.                         struct TMTimerReq   tmtri_TimerReq;
  14.                         struct Image        tmtri_Image;
  15.                         struct TMImageNode *tmtri_NextImage;
  16.                        };
  17.  
  18. /* extended TMObject structure for TMOBJTYPE_Image objects */
  19. struct TMObjectImage {
  20.                       struct TMObject     io_Object;
  21.                       ULONG               io_Flags;
  22.                       char               *io_File;
  23.                       struct TMImageData *io_Data;
  24.                       UWORD               io_XSize;
  25.                       UWORD               io_YSize;
  26.                       struct Image       *io_Normal;
  27.                       struct Image       *io_Selected;
  28.                      };
  29.  
  30. /* io_Flags */
  31. #define IO_FreeData (1L<<0)
  32. #define IO_DiskObj  (1L<<1)
  33.  
  34. /* Data */
  35. static ULONG IconCount=0;
  36. struct Library *IconBase=NULL;
  37.  
  38. /* Try to open icon.library */
  39. static BOOL GetIconLibrary(void)
  40. {
  41.  /* Library already open or can we open it? */
  42.  if (IconBase || (IconBase=OpenLibrary("icon.library",37)))
  43.   {
  44.    /* Increment Icon counter */
  45.    IconCount++;
  46.  
  47.    /* All OK */
  48.    return(TRUE);
  49.   }
  50.  
  51.  /* Call failed */
  52.  return(FALSE);
  53. }
  54.  
  55. /* Try to close icon.library */
  56. static void FreeIconLibrary(void)
  57. {
  58.  /* Decrement Icon counter and close icon.library if zero */
  59.  if (--IconCount==0) {
  60.   CloseLibrary(IconBase);
  61.   IconBase=NULL;
  62.  }
  63. }
  64.  
  65. /* Create an Image object */
  66. struct TMObject *CreateTMObjectImage(struct TMHandle *handle, char *name,
  67.                                      struct TagItem *tags)
  68. {
  69.  struct TMObjectImage *tmobj;
  70.  
  71.  /* allocate memory for object */
  72.  if (tmobj=AllocateTMObject(sizeof(struct TMObjectImage))) {
  73.   struct TagItem *ti,*tstate;
  74.  
  75.   /* Scan tag list */
  76.   tstate=tags;
  77.   while (ti=NextTagItem(&tstate)) {
  78.  
  79.    DEBUG_PRINTF("Got Tag (0x%08lx)\n",ti->ti_Tag);
  80.  
  81.    switch (ti->ti_Tag) {
  82.     case TMOP_File: tmobj->io_File=(char *) ti->ti_Data;
  83.                     break;
  84.     case TMOP_Data: tmobj->io_Data=(struct TMImageData *) ti->ti_Data;
  85.                     break;
  86.    }
  87.   }
  88.  
  89.   /* Sanity check */
  90.   if (!tmobj->io_File && !tmobj->io_Data) tmobj->io_File=DefaultNoName;
  91.  
  92.   /* File name supplied? */
  93.   if (tmobj->io_File) {
  94.    /* Yes. Read image data from it */
  95.    BPTR fl;
  96.  
  97.    /* Ignore user supplied data */
  98.    tmobj->io_Data=NULL;
  99.  
  100.    /* Try to open as IFF file first */
  101.    if (fl=Lock(tmobj->io_File,ACCESS_READ)) {
  102.     /* Got it. */
  103.     UnLock(fl);
  104.  
  105.     /* Read IFF file */
  106.     if (tmobj->io_Data=ReadIFFData(tmobj->io_File)) {
  107.      /* Got an IFF ILBM/ANIM */
  108.      struct Image *img=&tmobj->io_Data->tmid_Normal;
  109.  
  110.      tmobj->io_XSize=img->Width;
  111.      tmobj->io_YSize=img->Height+1;
  112.      tmobj->io_Normal=img;
  113.  
  114.      /* Get selected image */
  115.      img=&tmobj->io_Data->tmid_Selected;
  116.      if (img->ImageData)
  117.       tmobj->io_Selected=img;
  118.     }
  119.    }
  120.  
  121.    /* Got IFF data? No --> Open icon file */
  122.    if (!(tmobj->io_Data) && GetIconLibrary())
  123.     if (tmobj->io_Data=GetDiskObject(tmobj->io_File)) {
  124.      /* Got an icon */
  125.      struct Image *img=((struct DiskObject *) tmobj->io_Data)
  126.                         ->do_Gadget.GadgetRender;
  127.  
  128.      tmobj->io_Flags|=IO_DiskObj;
  129.      tmobj->io_XSize=img->Width;
  130.      tmobj->io_YSize=img->Height+1;
  131.      tmobj->io_Normal=img;
  132.      tmobj->io_Selected=((struct DiskObject *) tmobj->io_Data)
  133.                          ->do_Gadget.SelectRender;
  134.     }
  135.     else
  136.      FreeIconLibrary();
  137.  
  138.    /* All OK? */
  139.    if (tmobj->io_Data) {
  140.     tmobj->io_Flags|=IO_FreeData; /* Set free resources flag */
  141.     return(tmobj);
  142.    }
  143.   }
  144.   else {
  145.    /* No. User supplied image data directly */
  146.    struct Image *img=&tmobj->io_Data->tmid_Normal;
  147.  
  148.    tmobj->io_XSize=img->Width;
  149.    tmobj->io_YSize=img->Height+1;
  150.    tmobj->io_Normal=img;
  151.  
  152.    /* Get selected image */
  153.    img=&tmobj->io_Data->tmid_Selected;
  154.    if (img->ImageData)
  155.     tmobj->io_Selected=img;
  156.  
  157.    /* All OK */
  158.    return(tmobj);
  159.   }
  160.   FreeMem(tmobj,sizeof(struct TMObjectImage));
  161.  }
  162.  
  163.  /* call failed */
  164.  return(NULL);
  165. }
  166.  
  167. /* Delete an Image object */
  168. BOOL DeleteTMObjectImage(struct TMObjectImage *tmobj)
  169. {
  170.  DEBUG_PRINTF("Delete/Image (0x%08lx)\n",tmobj);
  171.  
  172.  /* Remove links */
  173.  DeleteAllLinksTMObject((struct TMObject *) tmobj);
  174.  
  175.  /* Remove object from list */
  176.  Remove((struct Node *) tmobj);
  177.  
  178.  /* Free resources? */
  179.  if (tmobj->io_Flags&IO_FreeData)
  180.   /* Yes, Icon file? */
  181.   if (tmobj->io_Flags&IO_DiskObj) {
  182.    /* Yes, release data */
  183.    FreeDiskObject((struct DiskObject *) tmobj->io_Data);
  184.    FreeIconLibrary();
  185.   }
  186.   else
  187.    /* No, IFF data -> release it */
  188.    FreeIFFData(tmobj->io_Data);
  189.  
  190.  /* Free object */
  191.  FreeMem(tmobj,sizeof(struct TMObjectImage));
  192.  
  193.  /* All OK. */
  194.  return(TRUE);
  195. }
  196.  
  197. /* Allocate & Initialize a TMLinkImage structure */
  198. struct TMLink *AllocLinkTMObjectImage(struct TMObjectImage *tmobj)
  199. {
  200.  struct TMLinkImage *tml;
  201.  
  202.  /* Allocate memory for link structure */
  203.  if (tml=AllocMem(sizeof(struct TMLinkImage),MEMF_CLEAR|MEMF_PUBLIC)) {
  204.   /* Initialize link structure */
  205.   tml->tmli_Link.tml_Size=sizeof(struct TMLinkImage);
  206.   tml->tmli_Width=tmobj->io_XSize;
  207.   tml->tmli_Height=tmobj->io_YSize;
  208.   tml->tmli_Normal=tmobj->io_Normal;
  209.   tml->tmli_Selected=tmobj->io_Selected;
  210.  }
  211.  
  212.  return(tml);
  213. }
  214.  
  215. /* Send timer request */
  216. static void SendTimerRequest(struct TMTimerReqImage *tmtri, BOOL last)
  217. {
  218.  struct timerequest *tr=&tmtri->tmtri_TimerReq.tmtr_Request;
  219.  
  220.  /* Initialize timer request */
  221.  tr->tr_node.io_Command=TR_ADDREQUEST;
  222.  tr->tr_time.tv_secs=last ? 1 : 0;
  223.  tr->tr_time.tv_micro=last ? 0 : 33333;
  224.  
  225.  /* Send timer request */
  226.  SendIO((struct IORequest *) tr);
  227. }
  228.  
  229. /* Abort timer request */
  230. static void AbortTimerRequest(struct TMTimerReqImage *tmtri)
  231. {
  232.  /* I/O request still active? */
  233.  if (!CheckIO((struct IORequest *) tmtri))
  234.   /* Yes. Abort it */
  235.   AbortIO((struct IORequest *) tmtri);
  236.  
  237.  /* Remove request from port */
  238.  WaitIO((struct IORequest *) tmtri);
  239. }
  240.  
  241. /* Activate an Image object */
  242. void ActivateTMObjectImage(struct TMLinkImage *tmli, void *start)
  243. {
  244.  struct TMObjectImage *tmobj=tmli->tmli_Link.tml_Linked;
  245.  UWORD x=tmli->tmli_LeftEdge;
  246.  UWORD y=tmli->tmli_TopEdge;
  247.  
  248.  DEBUG_PRINTF("Activate/Image (%ld)\n",start);
  249.  
  250.  /* Start animation? */
  251.  switch ((ULONG) start) {
  252.   case NULL:         {
  253.                       struct TMTimerReqImage *tmtri=tmli->tmli_Link.tml_Active;
  254.                       struct TMImageNode *tmin=tmtri->tmtri_NextImage;
  255.  
  256.                       /* Remove timer request */
  257.                       WaitIO((struct IORequest *) tmtri);
  258.  
  259.                       /* Draw next picture? */
  260.                       if (tmin) {
  261.                        /* Yes. Draw next picture */
  262.                        struct Image *img=&tmtri->tmtri_Image;
  263.  
  264.                        /* Set image pointer */
  265.                        img->ImageData=tmin->tmin_Data;
  266.  
  267.                        /* Draw picture */
  268.                        DrawImage(tmli->tmli_RastPort,img,x,y);
  269.  
  270.                        /* Set next picture */
  271.                        tmtri->tmtri_NextImage=tmin->tmin_Next;
  272.  
  273.                        /* Activate timer */
  274.                        SendTimerRequest(tmtri,tmtri->tmtri_NextImage==NULL);
  275.                       } else {
  276.                        /* No. Draw normal picture */
  277.                        DrawImage(tmli->tmli_RastPort,tmli->tmli_Normal,x,y);
  278.  
  279.                        /* Free timer request */
  280.                        FreeMem(tmtri,sizeof(struct TMTimerReqImage));
  281.                        tmli->tmli_Link.tml_Active=NULL;
  282.                       }
  283.                      }
  284.                      break;
  285.   case IOC_DEACTIVE: {
  286.                       struct TMTimerReqImage *tmtri=tmli->tmli_Link.tml_Active;
  287.  
  288.                       /* Anim active? */
  289.                       if (tmtri) {
  290.                        /* Yes. Stop it! Abort timer request */
  291.                        AbortTimerRequest(tmtri);
  292.  
  293.                        /* Free timer request */
  294.                        FreeMem(tmtri,sizeof(struct TMTimerReqImage));
  295.                        tmli->tmli_Link.tml_Active=NULL;
  296.                       }
  297.  
  298.                       /* Draw inactive image */
  299.                       DrawImage(tmli->tmli_RastPort,tmli->tmli_Normal,x,y);
  300.                      }
  301.                      break;
  302.   case IOC_ACTIVE:   {
  303.                       struct TMTimerReqImage *tmtri=tmli->tmli_Link.tml_Active;
  304.                       struct RastPort *rp=tmli->tmli_RastPort;
  305.  
  306.                       /* Anim active? */
  307.                       if (tmtri) {
  308.                        /* Yes. Stop it! Abort timer request */
  309.                        AbortTimerRequest(tmtri);
  310.  
  311.                        /* Draw inactive state */
  312.                        DrawImage(rp,tmli->tmli_Normal,x,y);
  313.  
  314.                        /* Free timer request */
  315.                        FreeMem(tmtri,sizeof(struct TMTimerReqImage));
  316.                        tmli->tmli_Link.tml_Active=NULL;
  317.                       }
  318.  
  319.                       /* Draw selected state. Got a selected image? */
  320.                       if (tmobj->io_Selected)
  321.                        /* Yes, draw it */
  322.                        DrawImage(rp,tmobj->io_Selected,x,y);
  323.                       else {
  324.                        /* No, invert image */
  325.                        SetDrMd(rp,COMPLEMENT);
  326.                        SetAPen(rp,0xff);
  327.                        RectFill(rp,x,y,x+tmobj->io_XSize-1,y+tmobj->io_YSize-2);
  328.                       }
  329.                      }
  330.                      break;
  331.   case IOC_FULLANIM: {
  332.                       struct TMTimerReqImage *tmtri=tmli->tmli_Link.tml_Active;
  333.                       struct RastPort *rp=tmli->tmli_RastPort;
  334.  
  335.                       /* Anim active? */
  336.                       if (tmtri) {
  337.                        /* Yes. Stop it! Abort timer request */
  338.                        AbortTimerRequest(tmtri);
  339.  
  340.                        /* Draw inactive state */
  341.                        DrawImage(rp,tmli->tmli_Normal,x,y);
  342.  
  343.                        /* Free timer request */
  344.                        FreeMem(tmtri,sizeof(struct TMTimerReqImage));
  345.                        tmli->tmli_Link.tml_Active=NULL;
  346.                       }
  347.  
  348.                       /* Start animation after 1st image. Get memory. */
  349.                       if (tmtri=AllocMem(sizeof(struct TMTimerReqImage),
  350.                                          MEMF_PUBLIC)) {
  351.                        /* Got it */
  352.                        struct Image *img=tmobj->io_Selected;
  353.  
  354.                        /* Init timer request */
  355.                        tmtri->tmtri_TimerReq.tmtr_Request=*deftimereq;
  356.                        tmtri->tmtri_Image=*(tmli->tmli_Normal);
  357.                        tmtri->tmtri_TimerReq.tmtr_Link=tmli;
  358.  
  359.                        /* No icon file and more than one picture? */
  360.                        if (!(tmobj->io_Flags & IO_DiskObj) && img)
  361.                         /* Yes. Set anim starting image */
  362.                         tmtri->tmtri_NextImage=tmobj->io_Data->tmid_Data->
  363.                                                 tmin_Next->tmin_Next;
  364.                        else
  365.                         /* Only one picture animation */
  366.                         tmtri->tmtri_NextImage=NULL;
  367.  
  368.                        /* Got a second picture? */
  369.                        if (img)
  370.                         /* Yes, draw it */
  371.                         DrawImage(rp,img,x,y);
  372.                        else {
  373.                         /* No, invert image */
  374.                         SetDrMd(rp,COMPLEMENT);
  375.                         SetAPen(rp,0xff);
  376.                         RectFill(rp,x,y,x+tmobj->io_XSize-1,
  377.                                  y+tmobj->io_YSize-2);
  378.                        }
  379.  
  380.                        /* Send timer request */
  381.                        SendTimerRequest(tmtri,FALSE);
  382.  
  383.                        /* Set active flag */
  384.                        tmli->tmli_Link.tml_Active=tmtri;
  385.                       }
  386.                      }
  387.                      break;
  388.   case IOC_CONTANIM: {
  389.                       struct TMTimerReqImage *tmtri=tmli->tmli_Link.tml_Active;
  390.  
  391.                       /* Anim active? */
  392.                       if (tmtri) {
  393.                        /* Yes. Stop it! Abort timer request */
  394.                        AbortTimerRequest(tmtri);
  395.  
  396.                        /* Free timer request */
  397.                        FreeMem(tmtri,sizeof(struct TMTimerReqImage));
  398.                        tmli->tmli_Link.tml_Active=NULL;
  399.                       }
  400.  
  401.                       /* Start animation after 2nd image */
  402.                       /* Icon file or only one picture? */
  403.                       if ((tmobj->io_Flags & IO_DiskObj) ||
  404.                           !tmobj->io_Selected)
  405.                        /* Yes. Draw normal state */
  406.                        DrawImage(tmli->tmli_RastPort,tmli->tmli_Normal,x,y);
  407.                       else {
  408.                        struct TMImageNode *tmin=tmobj->io_Data->tmid_Data->
  409.                                                  tmin_Next->tmin_Next;
  410.  
  411.                        /* Got more than 2 images and can we allocate memory */
  412.                        /* for timer request? */
  413.                        if (tmin && (tmtri=AllocMem(
  414.                                            sizeof(struct TMTimerReqImage),
  415.                                            MEMF_PUBLIC))) {
  416.                         /* Yes, start anim. Init timer request */
  417.                         tmtri->tmtri_TimerReq.tmtr_Request=*deftimereq;
  418.                         tmtri->tmtri_Image=*(tmli->tmli_Normal);
  419.                         tmtri->tmtri_TimerReq.tmtr_Link=tmli;
  420.                         tmtri->tmtri_NextImage=tmin;
  421.  
  422.                         /* Send timer request */
  423.                         SendTimerRequest(tmtri,FALSE);
  424.  
  425.                         /* Set active flag */
  426.                         tmli->tmli_Link.tml_Active=tmtri;
  427.                        } else
  428.                         /* No. Draw normal state */
  429.                         DrawImage(tmli->tmli_RastPort,tmli->tmli_Normal,x,y);
  430.                       }
  431.                      }
  432.                      break;
  433.  }
  434. }
  435.