home *** CD-ROM | disk | FTP | other *** search
/ APDL Public Domain 1 / APDL_PD1A.iso / program / popups / Docs / ExampleSrc / c / _Magnify next >
Encoding:
Text File  |  1993-05-25  |  7.8 KB  |  247 lines

  1. /*  File:     _Magnify.c
  2.  *  Purpose:  Supplies functionality for a PopUp
  3.  *  Author:   © Copyright 1993 Jason Williams
  4.  *            All rights reserved
  5.  */
  6.  
  7. #include "DeskLib:WimpSWIs.h"
  8. #include "DeskLib:Icon.h"
  9. #include "DeskLib:Keycodes.h"
  10. #include "DeskLib:StringCR.h"
  11. #include "DeskLib:Template.h"
  12.  
  13. #include "Server.h"
  14.  
  15.  
  16. typedef struct
  17. {
  18.   int  mul,    div;                    /* Multiplier and divisor icon values */
  19.   int  minmul, maxmul;                 /* Minimum allowed fraction           */
  20.   int  mindiv, maxdiv;                 /* Maximum allowed fraction           */
  21.   char windowname[12];                 /* Title string for window            */
  22.  
  23.   window_block *window;                /* Internal use only */
  24. } magnify_data;
  25.  
  26.  
  27. /*  First of all, we define a handler_info structure for our PopUp handler
  28.  *  which describes it to the manager. This is referenced externally
  29.  *  by the server to find the procedure to call with events for any PopUp
  30.  *  of this type, etc.
  31.  *  (We also prototype the handler function so we can reference it here)
  32.  */
  33.  
  34. static int Handler_Magnify(int, ctrl_block *, void *, event_pollblock *);
  35.  
  36. handler_info HandlerInfo_Magnify =
  37. {
  38.   "Magnify",                                 /* PopUp type/name string       */
  39.   0x00000003,                                /* Flag word (MENU/STATIC)      */
  40.   Handler_Magnify,                           /* Handler procedure            */
  41.   44                                         /* Instantiation workspace size */
  42. };
  43.  
  44.  
  45. static void CheckMagDiv(magnify_data *ws)
  46. /* Ensures that the parameters mag/div give a value between min and max
  47.  * If not, the value is truncated to min or max as appropriate
  48.  */
  49. {
  50.   if (ws->mul < ws->minmul)  ws->mul = ws->minmul;
  51.   if (ws->div < ws->mindiv)  ws->div = ws->mindiv;
  52.  
  53.   if (ws->mul > ws->maxmul)  ws->mul = ws->maxmul;
  54.   if (ws->div > ws->maxdiv)  ws->div = ws->maxdiv;
  55. }
  56.  
  57.  
  58.  
  59. static void Add(window_handle window, magnify_data *ws,
  60.                 int *value, int increment)
  61. {
  62.   int oldmul = ws->mul, olddiv = ws->div;
  63.  
  64.   *value += increment;
  65.   CheckMagDiv(ws);
  66.  
  67.   if (oldmul != ws->mul)
  68.   {
  69.     Icon_SetInteger(window, 0, ws->mul);   /* Set new value */
  70.     Icon_SetCaret(window, 0);              /* Ensure caret appears correctly */
  71.   }
  72.       
  73.   if (olddiv != ws->div)
  74.   {
  75.     Icon_SetInteger(window, 1, ws->div);
  76.     Icon_SetCaret(window, 1);
  77.   }
  78.  
  79.   if (oldmul != ws->mul || olddiv != ws->div)
  80.     SendState(ws, sizeof(magnify_data));          /* 'instant effect' update */
  81. }
  82.  
  83.  
  84. static void ReadIcons(magnify_data *ws, window_handle window)
  85. {
  86.   ws->mul = Icon_GetInteger(window, 0);
  87.   ws->div = Icon_GetInteger(window, 1);
  88.   CheckMagDiv(ws);
  89. }
  90.  
  91.  
  92. /*  The Handler_ function referenced in the above info struct will handle all
  93.  *  calls from the server during normal operation...
  94.  */
  95.  
  96. static BOOL Handler_Magnify(int reasoncode, ctrl_block *ctrl,
  97.                             void *privateworkspace, event_pollblock *event)
  98. {
  99.   magnify_data *ws = privateworkspace;
  100.  
  101.   switch(reasoncode)
  102.   {
  103.     case REASON_OPEN:
  104.       {
  105.         window_handle windowhandle;
  106.         window_block  *window;
  107.         magnify_data  *info;
  108.  
  109.         info = (magnify_data *) (((int)event) + POPUP_DATA_OFFSET);
  110.         *ws = *info;           /* Copy the window settins into out workspace */
  111.  
  112.         /*  Find the template. NOTE that if you provide a STATIC popup, you
  113.          *  MUST support multiple instantiations, so MUST use Template_Clone()
  114.          *  Also note that if bringing up a MENU LEAF window, we must clone
  115.          *  our template data into the RMA so the WIMP does not crash! ;-(
  116.          */
  117.         if (ctrl->appflags & APPFLAGS_ISSTATIC)
  118.           ws->window = window = Template_Clone("Magnify", 0);
  119.         else
  120.         {
  121.           ws->window = NULL;
  122.           if((ctrl->appflags & APPFLAGS_ISLEAF) == 0)
  123.             window = Template_Find("Magnify");
  124.           else
  125.           {
  126.             window = Template_RMAFind("Magnify");
  127.             window->flags.data.closeicon = FALSE;
  128.             /* (Remove the close icon. NOTE that this is a COPY of the window
  129.              * so does not permanently remove the icon)
  130.              */
  131.           }
  132.         }
  133.  
  134.         if (window == NULL) break;
  135.  
  136.         /*  Create the window, and fill in it's icons with the data given
  137.          *  to us in the pollblock. (DATA_BASE is defined above)
  138.          */
  139.         info->windowname[11] = 0;
  140.         strcpycr(window->title.text,info->windowname);    /* Set window name */
  141.         Wimp_CreateWindow(window, &windowhandle);
  142.  
  143.         CheckMagDiv(ws);
  144.         Icon_SetInteger(windowhandle, 0, ws->mul);
  145.         Icon_SetInteger(windowhandle, 1, ws->div);
  146.  
  147.         if (ctrl->appflags & APPFLAGS_ISSTATIC)
  148.           ShowStaticPopUp(windowhandle, ctrl->openx, ctrl->openy);
  149.  
  150.         ctrl->pollmask.value = ~( (1 << event_CLOSE) |
  151.                                   (1 << event_CLICK) |
  152.                                   (1 << event_KEY)  );
  153.         ctrl->basewindow = windowhandle;     /* Let server know windowhandle */
  154.       }
  155.       return(TRUE);
  156.  
  157.  
  158.     case REASON_CLOSE:                          /* Quietly close our window  */
  159.       Wimp_DeleteWindow(ctrl->basewindow);
  160.       if (ws->window != NULL)                   /* If static, release memory */ 
  161.         Template_Free(&ws->window);             /* used by cloned template   */
  162.       return(TRUE);
  163.  
  164.  
  165.     case REASON_EVENT:                                /* Handle a WIMP Event */
  166.       switch(event->type)
  167.       {
  168.         case event_CLOSE:
  169.           if (event->data.openblock.window == ctrl->basewindow)
  170.           {
  171.             /*  *ONLY* if this is our window, we kill the current menu, kill
  172.              *  our window, and return TRUE to indicate that we have processed
  173.              *  the event (so no other handlers should get it)
  174.              */
  175.             Wimp_CreateMenu((menu_block *) -1, 0, 0);
  176.             Wimp_DeleteWindow(ctrl->basewindow);
  177.             if (ws->window != NULL)             /* If static, release memory */
  178.               Template_Free(&ws->window);       /* used by cloned template   */
  179.  
  180.             KillMe();      /* Tell the PopUp manager that I have closed down */
  181.             return(TRUE);
  182.           }
  183.           break;
  184.  
  185.         case event_CLICK:
  186.          if (event->data.mouse.window == ctrl->basewindow)
  187.           {
  188.             switch(event->data.mouse.icon)
  189.             {
  190.               case 2: /* Mag up   */
  191.                 Add(ctrl->basewindow, ws, &ws->mul, +1);
  192.                 break;
  193.  
  194.               case 3: /* Mag down */
  195.                 Add(ctrl->basewindow, ws, &ws->mul, -1);
  196.                 break;
  197.  
  198.               case 4: /* Div up   */
  199.                 Add(ctrl->basewindow, ws, &ws->div, +1);
  200.                 break;
  201.  
  202.               case 5: /* Div down */
  203.                 Add(ctrl->basewindow, ws, &ws->div, -1);
  204.                 break;              
  205.             }
  206.             return(TRUE);
  207.           }
  208.           break;          
  209.  
  210.         case event_KEY:
  211.          if (event->data.key.caret.window == ctrl->basewindow)
  212.           {
  213.             switch(event->data.key.code)
  214.             {
  215.               case keycode_TAB:
  216.               case keycode_CURSORUP:
  217.               case keycode_CURSORDOWN:
  218.                 ReadIcons(ws, ctrl->basewindow);
  219.                 if (event->data.key.caret.icon == 0)
  220.                   Icon_SetCaret(ctrl->basewindow, 1);
  221.                 else
  222.                   Icon_SetCaret(ctrl->basewindow, 0);
  223.                 break;
  224.  
  225.               case keycode_RETURN:
  226.                 ReadIcons(ws, ctrl->basewindow);
  227.                 if (event->data.key.caret.icon == 0)
  228.                   Icon_SetCaret(ctrl->basewindow, 1);
  229.                 else
  230.                   SendState(ws, sizeof(magnify_data));
  231.                 break;
  232.  
  233.               default:
  234.                 Wimp_ProcessKey(event->data.key.code);
  235.                 break;
  236.             }
  237.             return(TRUE);
  238.           }
  239.           break;
  240.       }
  241.       break;
  242.   }
  243.  
  244.   return(FALSE);          /* If we didn't handle this call, we MUST return 0 */
  245. }
  246.  
  247.