home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 3 / TheARMClub_PDCD3.iso / hensa / programming / desklib / examples / DeskLib / Examples / Widget5 / !Widget5 / c / MixWin < prev    next >
Encoding:
Text File  |  1995-05-05  |  13.2 KB  |  442 lines

  1. /************************************************************************
  2.  *                                                                      *
  3.  *        File: MixWin.c                                                *
  4.  *                                                                      *
  5.  *     Purpose: Provides user interface to mix two images process       *
  6.  *                                                                      *
  7.  ************************************************************************/
  8.  
  9. #include "DeskLib:WimpSWIs.h"          /* Low-level WIMP commands         */
  10. #include "DeskLib:Window.h"            /* Window handling automation      */
  11. #include "DeskLib:Core.h"              /* usefull core functions          */
  12. #include "DeskLib:Error.h"             /* Error despatcher                */
  13. #include "DeskLib:Event.h"             /* Event despatcher                */
  14. #include "DeskLib:EventMsg.h"          /* Wimp Message event dispatcher   */
  15. #include "DeskLib:File.h"              /* Low level file handling         */
  16. #include "DeskLib:Msgs.h"              /* Message translation code        */
  17. #include "DeskLib:Resource.h"          /* Handles finding resource files  */
  18. #include "DeskLib:Sound.h"             /* Beep!                           */
  19. #include "DeskLib:Template.h"          /* Template loading and caching    */
  20. #include "DeskLib:Icon.h"              /* Icon handling automation        */
  21. #include "DeskLib:Screen.h"            /* Caching screen info             */
  22. #include "DeskLib:Sprite.h"            /* Sprite handling routines        */
  23. #include "DeskLib:File.h"              /* OS file IO                      */
  24. #include "DeskLib:KeyCodes.h"          /* Codes for wimp returned keys    */
  25. #include "DeskLib:Hourglass.h"         /* control hourglass               */
  26. #include "DeskLib:Coord.h"
  27.  
  28. #include "SpriteWin.h"
  29. #include "CheckBanks.h"
  30. #include "Process.h"
  31. #include "Widget5.h"
  32. #include "Misc.h"
  33. #include "Configure.h"
  34.  
  35. #include <stdlib.h>
  36. #include <stdio.h>
  37. #include <string.h>
  38.  
  39. #define initial_SLIDER  13
  40. #define base_SLIDER 5
  41. #define idletime_SLIDER 0
  42.  
  43. #define icon_IMAGE1 8
  44. #define icon_IMAGE2 9
  45. #define icon_REALTIME 10
  46.  
  47. #define default_IMAGE1PERCENT 50
  48.  
  49. extern window_handle db;
  50.  
  51. typedef struct {
  52.    int source1;
  53.    int source2;
  54.    int dest;
  55.    int slidericon;
  56.    int arearight;
  57.    int arealeft; /* left + slidersize */
  58.    int ptroffset;
  59.    unsigned int oldidletime;
  60.    window_handle window;
  61. } mix_block;
  62.  
  63. static BOOL Click_mixwin(event_pollblock *event, void *reference);
  64. static BOOL Null_updateslider(event_pollblock *event, void *reference);
  65. static BOOL Null_checksourcebanks(event_pollblock *event, void *reference);
  66. static BOOL UserDrag_updateslider(event_pollblock *event, void *reference);
  67. static void close_mixwin(BOOL ok, BOOL keepopen, mix_block *block);
  68. BOOL update_imagepercents(window_handle window, int image1percent);
  69. void update_slider(mix_block *block, int image1percent, BOOL copyblock);
  70. void NoMemProcess(void);
  71.  
  72. /******************************************************************************
  73.  *                            extern routines                                 *
  74.  ******************************************************************************/
  75.  
  76. extern void MixWin_Init(void)
  77. {
  78.  /*
  79.   * initialisation to be done on startup
  80.   */
  81.  
  82. }
  83.  
  84. /******************************************************************************/
  85.  
  86. extern void MixWin_Open(int source1, int source2, int dest, wimp_point *openpos)
  87. {
  88.   mix_block *block;
  89.   char text[20];
  90.  
  91.  /*
  92.   * allocate memory for range info block and return if fails
  93.   */
  94.   block = malloc(sizeof(mix_block));
  95.   if(block == NULL){
  96.      NoMemProcess();
  97.      return;
  98.   }
  99.  
  100.  /*
  101.   * initialise window and block
  102.   */
  103.   block->window = Window_Create("MixProcess", template_TITLEMIN);
  104.   block->source1 = source1;
  105.   block->source2 = source2;
  106.   block->dest = dest;
  107.  
  108.  /*
  109.   * initialise both source image bank numbers
  110.   */
  111.   Msgs_Lookup("txt.image", text, 19);
  112.   Icon_printf(block->window, 1, "%s %i", text, block->source1);
  113.   Icon_printf(block->window, 3, "%s %i", text, block->source2);
  114.  
  115.   block->slidericon = initial_SLIDER;
  116.  
  117.  /*
  118.   * setup realtime icon
  119.   */
  120.   Icon_Deselect(block->window, icon_REALTIME);
  121.   if(block->source2 == block->dest)
  122.      Icon_Shade(block->window, icon_REALTIME);
  123.   else
  124.      Icon_SetSelect(block->window, icon_REALTIME, realtime); /* default state */
  125.  
  126.   Event_Claim(event_NULL, event_ANY, event_ANY, Null_checksourcebanks, block);
  127.   Event_Claim(event_CLICK, block->window, event_ANY, Click_mixwin, block);
  128.  
  129.   update_imagepercents(block->window, default_IMAGE1PERCENT);
  130.   update_slider(block, default_IMAGE1PERCENT, FALSE);
  131.  
  132.   Window_ShowPos(block->window, openpos);
  133.   
  134. }
  135.  
  136. /******************************************************************************
  137.  *                              Click handlers                                *
  138.  ******************************************************************************/
  139.  
  140. static BOOL Click_mixwin(event_pollblock *event, void *reference)
  141. {
  142.   mix_block *block = reference;
  143.   convert_block convert;
  144.   window_state  state;
  145.   drag_block    dragdata;
  146.   icon_block    bicon, sicon;
  147.   int ptroffset;
  148.  
  149.   if(event->data.mouse.icon == block->slidericon){
  150.  
  151.     /*
  152.      * start drag of slider
  153.      */
  154.      block->oldidletime = idletime;
  155.      idletime = idletime_SLIDER;
  156.  
  157.      Event_Claim(event_NULL, event_ANY, event_ANY, Null_updateslider, block);
  158.      Event_Claim(event_USERDRAG, event_ANY, event_ANY, UserDrag_updateslider, block); 
  159.  
  160.     /*
  161.      * get slider and background icon positions in workarea coords
  162.      */
  163.      Wimp_GetIconState(block->window, base_SLIDER, &bicon);
  164.      Wimp_GetIconState(block->window, block->slidericon, &sicon);
  165.  
  166.     /*
  167.      * setup convert block for workarea to screen coord conversion
  168.      */
  169.      Wimp_GetWindowState(block->window, &state);
  170.      convert.screenrect = state.openblock.screenrect;
  171.      convert.scroll     = state.openblock.scroll;
  172.  
  173.     /*
  174.      * setup drag block
  175.      */
  176.      dragdata.window    = block->window;
  177.      dragdata.type      = drag_INVISIBLE;
  178.      dragdata.screenrect= state.openblock.screenrect;   /* dragged box not used */
  179.  
  180.     /*
  181.      * set drag area to be right hand edge of background and
  182.      * lefthand edge + size of slider bar
  183.      */
  184.      dragdata.parent.min.x = bicon.workarearect.min.x + 4 +
  185.         /* size of slider */ (sicon.workarearect.max.x - sicon.workarearect.min.x);
  186.      dragdata.parent.max.x = bicon.workarearect.max.x - 4;
  187.      Coord_RectToScreen(&dragdata.parent, &convert);
  188.  
  189.     /*
  190.      * move drag area to left by amount pointer is to left of slider bar right edge
  191.      */
  192.      ptroffset = event->data.mouse.pos.x -
  193.                  Coord_XToScreen(sicon.workarearect.max.x, &convert);
  194.      dragdata.parent.min.x += ptroffset;
  195.      dragdata.parent.max.x += ptroffset;
  196.  
  197.     /*
  198.      * set up area in block
  199.      */
  200.      block->arealeft = dragdata.parent.min.x;
  201.      block->arearight = dragdata.parent.max.x;
  202.      block->ptroffset = ptroffset;
  203.  
  204.     /*
  205.      * prevent y movement
  206.      */
  207.      dragdata.parent.min.y = event->data.mouse.pos.y;
  208.      dragdata.parent.max.y = event->data.mouse.pos.y;
  209.  
  210.      Wimp_DragBox(&dragdata);
  211.  
  212.      return(TRUE);
  213.   }
  214.  
  215.  
  216.   switch(event->data.mouse.icon)
  217.   {
  218.     
  219.     case 11: /* Close */
  220.        close_mixwin(FALSE, FALSE, block);
  221.        break;
  222.  
  223.     case 12: /* Mix */
  224.        close_mixwin(TRUE, event->data.mouse.button.data.adjust, block);
  225.        break;
  226.       
  227.   }
  228.   return(TRUE);
  229. }
  230.  
  231. /******************************************************************************
  232.  *                                null handlers                               *
  233.  ******************************************************************************/
  234.  
  235. static BOOL Null_updateslider(event_pollblock *event, void *reference)
  236. {
  237.   mouse_block ptrinfo;
  238.   mix_block *block = reference;
  239.   int image1percent;
  240.   int image2percent;
  241.   int backgroundlength;
  242.  
  243.   Wimp_GetPointerInfo(&ptrinfo);
  244.  
  245.  /*
  246.   * calculate percentages of position of pointer in restricted movable area
  247.   */
  248.   backgroundlength = block->arearight - block->arealeft;
  249.   image1percent = ((block->arearight - ptrinfo.pos.x) * 100) / backgroundlength;
  250.   image2percent = ((ptrinfo.pos.x - block->arealeft) * 100) / backgroundlength;
  251.  
  252.  /*
  253.   * use the value closest to the pointer to calculate the other
  254.   */
  255.   if(image1percent < 50)
  256.      image1percent = 100 - image2percent;
  257.  
  258.   if(update_imagepercents(block->window, image1percent))
  259.      update_slider(block, image1percent, TRUE);
  260.  
  261.   return(TRUE);
  262. }
  263.  
  264. /******************************************************************************/
  265.  
  266. static BOOL Null_checksourcebanks(event_pollblock *event, void *reference)
  267. {
  268.   mix_block *block = reference;
  269.  
  270.  /*
  271.   * close process window if any of the source banks become free
  272.   */
  273.   if( SpriteWin_FreeImage(block->source1) || SpriteWin_FreeImage(block->source2) )
  274.      close_mixwin(FALSE, FALSE, block);
  275.  
  276.   return(FALSE);
  277. }
  278.  
  279. /******************************************************************************
  280.  *                             userdrag handlers                              *
  281.  ******************************************************************************/
  282.  
  283. static BOOL UserDrag_updateslider(event_pollblock *event, void *reference)
  284. {
  285.   mix_block *block = reference;
  286.  
  287.   Wimp_DragBox((drag_block *) -1);
  288.   Event_Release(event_USERDRAG, event_ANY, event_ANY, UserDrag_updateslider, block);
  289.   Event_Release(event_NULL, event_ANY, event_ANY, Null_updateslider, block);
  290.  
  291.  /*
  292.   * if realtime is on then update destination
  293.   */
  294.   if(Icon_GetSelect(block->window, icon_REALTIME))
  295.      close_mixwin(TRUE, TRUE, block);
  296.  
  297.  /*
  298.   * reset wimp_poll idletime
  299.   */
  300.   idletime = block->oldidletime;
  301.  
  302.   return(TRUE);
  303. }
  304.  
  305. /******************************************************************************
  306.  *                               close handlers                               *
  307.  ******************************************************************************/
  308.  
  309. static void close_mixwin(BOOL ok, BOOL keepopen, mix_block *block)
  310. {
  311.   wimp_point *size;
  312.   int image1percent;
  313.  
  314.   if(ok == TRUE){
  315.  
  316.     /*
  317.      * process the image
  318.      */
  319.      size = SpriteWin_GetSize(block->source1);
  320.  
  321.     /*
  322.      * create destination if not created and return if creation fails
  323.      */
  324.      if( SpriteWin_FreeImage(block->dest) ){
  325.  
  326.         if( !SpriteWin_Create(size, block->dest) )
  327.            return;
  328.      }
  329.  
  330.      image1percent = Icon_GetInteger(block->window, icon_IMAGE1);
  331.      Process_Mix(block->source1, block->source2, block->dest, image1percent, size);
  332.  
  333.     /*
  334.      * refresh destination image
  335.      */
  336.      SpriteWin_RefreshWin(block->dest);
  337.      
  338.   }
  339.  
  340.   if(keepopen == FALSE){
  341.  
  342.      Event_Release(event_NULL, event_ANY, event_ANY, Null_checksourcebanks, block);
  343.      Window_Delete(block->window);
  344.      free(block);
  345.   }
  346.  
  347. }
  348.  
  349. /******************************************************************************
  350.  *                           menu choice handlers                             *
  351.  ******************************************************************************/
  352.  
  353. /******************************************************************************
  354.  *                             misc routines                                  *
  355.  ******************************************************************************/
  356.  
  357. BOOL update_imagepercents(window_handle window, int image1percent)
  358. {
  359.   char text[10];
  360.   BOOL updatedicons;
  361.  
  362.   updatedicons = FALSE;
  363.  
  364.  /*
  365.   * update the icons if the numbers have changed
  366.   */
  367.   sprintf(text, "%i%%", image1percent);
  368.   if(strcmp(text, Icon_GetTextPtr(window, icon_IMAGE1)) != 0){
  369.      Icon_SetText(window, icon_IMAGE1, text);
  370.      updatedicons = TRUE;
  371.  
  372.      sprintf(text, "%i%%", 100 - image1percent);
  373.      Icon_SetText(window, icon_IMAGE2, text);
  374.  
  375.   }
  376.  
  377.   return(updatedicons);
  378. }
  379.  
  380. /******************************************************************************/
  381.  
  382. void update_slider(mix_block *block, int image1percent, BOOL copyblock)
  383. {
  384.   icon_block bicon;
  385.   icon_createblock sicon;
  386.   int movablelength;
  387.   int righttoedge;
  388.   int sliderlength;
  389.   int backgroundlength;
  390.   window_redrawblock r;
  391.  
  392.  /*
  393.   * get slider and background icon positions in workarea coords
  394.   */
  395.   Wimp_GetIconState(block->window, base_SLIDER, &bicon);
  396.   Wimp_GetIconState(block->window, block->slidericon, &sicon.icondata);
  397.  
  398.  /*
  399.   * setup redraw block to remove old slider position
  400.   */
  401.   r.window = block->window;
  402.   r.rect = sicon.icondata.workarearect;
  403.   r.rect.max.x += 4;
  404.  
  405.  /*
  406.   * calculate new slider position
  407.   */
  408.   sliderlength = sicon.icondata.workarearect.max.x - sicon.icondata.workarearect.min.x;
  409.   backgroundlength = (bicon.workarearect.max.x - 4) - (bicon.workarearect.min.x + 4);
  410.   movablelength = backgroundlength - sliderlength;
  411.                   
  412.   righttoedge = (movablelength * image1percent) / 100;
  413.  
  414.   sicon.icondata.workarearect.max.x = bicon.workarearect.max.x - 4 - righttoedge;
  415.   sicon.icondata.workarearect.min.x = sicon.icondata.workarearect.max.x - sliderlength;
  416.  
  417.  /*
  418.   * remove and refresh old slider
  419.   */
  420.   sicon.window = block->window;
  421.   Wimp_DeleteIcon(block->window, block->slidericon);
  422.   Wimp_ForceRedraw(&r);
  423.  
  424.  /*
  425.   * add and redraw new slider
  426.   */
  427.   Wimp_CreateIcon(&sicon, &(block->slidericon));
  428.   Wimp_SetIconState(block->window, block->slidericon, 0, 0); /* forceredraw slider */
  429.   
  430. }
  431.  
  432. /******************************************************************************/
  433.  
  434. void NoMemProcess(void)
  435. {
  436.   char err_msg[128];
  437.  
  438.   Msgs_Lookup("err.nomemproc", err_msg, 127);
  439.   Error_Report(1,err_msg);
  440.  
  441. }
  442.