home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 3 / TheARMClub_PDCD3.iso / hensa / programming / desklib / examples / DeskLib / Examples / !TestApp / c / TestApp
Encoding:
Text File  |  1995-07-22  |  12.7 KB  |  368 lines

  1. /*
  2.     ####             #    #     # #
  3.     #   #            #    #       #          The FreeWare C library for 
  4.     #   #  ##   ###  #  # #     # ###             RISC OS machines
  5.     #   # #  # #     # #  #     # #  #   ___________________________________
  6.     #   # ####  ###  ##   #     # #  #                                      
  7.     #   # #        # # #  #     # #  #    Please refer to the accompanying
  8.     ####   ### ####  #  # ##### # ###    documentation for conditions of use
  9.     ________________________________________________________________________
  10.  
  11.     File:    TestApp.c
  12.     Author:  Copyright © 1992, 1993 Jason Williams
  13.     Version: 1.10 (12 Jul 1993)
  14.     Purpose: Demonstrate  (and test ;-)  some of the main DeskLib application
  15.              base routines. Note that 80% of this file is comment(!) and that
  16.              most of the calls used are overkill for such a small application
  17. */
  18.  
  19.  
  20. #include "DeskLib:WimpSWIs.h"          /* Low-level WIMP commands         */
  21. #include "DeskLib:Window.h"            /* Window handling automation      */
  22.  
  23. #include "DeskLib:Dialog.h"            /* High-level dialogue windows     */
  24. #include "DeskLib:Error.h"             /* Error despatcher                */
  25. #include "DeskLib:Event.h"             /* Event despatcher                */
  26. #include "DeskLib:EventMsg.h"          /* Wimp Message event dispatcher   */
  27. #include "DeskLib:File.h"              /* Low level file handling         */
  28. #include "DeskLib:GFX.h"               /* Graphics routines (GFX_Wait)    */
  29. #include "DeskLib:Handler.h"           /* Default/example event handlers  */
  30. #include "DeskLib:Hourglass.h"         /* Hourglass module interfaces     */
  31. #include "DeskLib:Icon.h"              /* Icon handling automation        */
  32. #include "DeskLib:Menu.h"              /* Menu create & show support      */
  33. #include "DeskLib:Msgs.h"              /* Message translation code        */
  34. #include "DeskLib:Resource.h"          /* Handles finding resource files  */
  35. #include "DeskLib:Screen.h"            /* Getting screen size info, etc   */
  36. #include "DeskLib:Sound.h"             /* Sound System control            */
  37. #include "DeskLib:Template.h"          /* Template loading and caching    */
  38. #include "DeskLib:Debug.h"             /* Diagnostic output               */
  39. #include <stdio.h>
  40. #include <string.h>
  41.  
  42. static BOOL     quit      = FALSE;     /* Set to TRUE to quit the app.    */
  43. static menu_ptr mainmenu  = NULL;      /* Pointer to our main menu        */
  44. static menu_ptr item2menu = NULL;      /* Pointer to our main menu        */
  45.  
  46.  
  47. /* Defines for the positions at which items appear on our menus.
  48.  * Note that menu items always start at number 0, so item number 2 is
  49.  * actually the THIRD item in the menu.
  50.  */
  51. #define mainmenu_CHANGETITLE 0
  52. #define mainmenu_ITEM1       1
  53. #define mainmenu_ITEM2       2
  54. #define mainmenu_QUIT        3
  55.  
  56.  
  57. static BOOL AskUser(char *questiontag)
  58. /*  Tests/demonstrates use of Dialog_ calls to show a query window containing
  59.  *  the given bit of text - the given string is a Msgs_ message tag
  60.  */
  61. {
  62.   char   msg[200];
  63.   dialog dlog;
  64.   BOOL   clickedOK;
  65.   
  66.   dlog = Dialog_Create("query", 0);                 /* Create the window    */
  67.  
  68.   Msgs_Lookup(questiontag, msg, 196);               /* Fill in the message  */
  69.   Icon_SetText(Dialog_WindowHandle(dlog), 2, msg);
  70.  
  71.   Dialog_Show(dlog);                                /* Pop up the dialog    */
  72.   Sound_SysBeep();                                  /* And beep 4 attention */
  73.  
  74.   while (Dialog_WaitForClick(dlog) > 1 || Dialog_Persist(dlog))
  75.     /* Busy wait loop */ ;                          /* Wait for OK/Cancel   */
  76.  
  77.   /*  Check: Did they click OK?
  78.    *  The other possibilities are: they didn't click any icon, but just closed
  79.    *  the window (in which case LastClicked will be dialog_NOCHOICE), or
  80.    *  they clicked the cancel icon (icon number 1)
  81.    *  We must remember this before calling Dialog_Destroy, as the dialog
  82.    *  structure will be lost upon a destroy.
  83.    */
  84.   clickedOK = (Dialog_LastClicked(dlog) == 0);
  85.  
  86.   Event_Poll();  /*  Ensure WIMP gets a chance to deselect the icon before we
  87.                   *  kill the window (this is a bug in the RISC OS 3 Wimp)
  88.                   */
  89.  
  90.   Dialog_Destroy(dlog);              /* Remove the dialog, releasing memory */
  91.  
  92.   return(clickedOK);
  93. }
  94.  
  95.  
  96.  
  97. static window_handle menuwindow = NULL;
  98.  
  99. static BOOL ButtonClick(event_pollblock *event, void *reference)
  100. /*  Handler attached to all button click events.
  101.  *  If no other handler specifically handles the click, and it was a menu
  102.  *  click, we will pop up our menu in an appropriate position.
  103.  */
  104. {
  105.   int ypos;
  106.  
  107.   UNUSED( reference);
  108.   
  109.   Debug_Printf( "A mouse-button has been pressed...\n");
  110.  
  111.   if (event->data.mouse.button.data.menu)             /* is a MENU click */
  112.   {
  113.     if (event->data.mouse.window >= 0)
  114.     {
  115.       ypos = event->data.mouse.pos.y;                /* Over a window    */
  116.       menuwindow = event->data.mouse.window;         /* (remember which) */
  117.       Menu_SetFlags(mainmenu, mainmenu_CHANGETITLE, FALSE, FALSE);
  118.                                                      /* Unshade item 0   */
  119.     }
  120.     else
  121.     {
  122.       ypos = -1;                                     /* Over the iconbar */
  123.       menuwindow = NULL;
  124.       Menu_SetFlags(mainmenu, mainmenu_CHANGETITLE, FALSE, TRUE);
  125.                                                      /* Shade item 0     */
  126.     }
  127.  
  128.     Menu_Show(mainmenu, event->data.mouse.pos.x, ypos);
  129.   }
  130.  
  131.   return(TRUE);
  132. }
  133.  
  134.  
  135.  
  136. static BOOL MenuChoice(event_pollblock *event, void *reference)
  137. /*  Handler to take care of the user's menu choices.
  138.  *  For now, we simply beep at practically everything except the 'Quit' option
  139.  */
  140. {
  141.   mouse_block ptr;
  142.  
  143.   UNUSED( reference);
  144.   
  145.   Debug_Printf( "Menu choice... for item %i\n", event->data.selection[0]);
  146.   
  147.   if (menu_currentopen != mainmenu)        /* Only respond to the mainmenu  */
  148.     return(FALSE);
  149.  
  150.   switch(event->data.selection[0])
  151.   {
  152.     case mainmenu_CHANGETITLE:             /* Change the window's titlebar  */
  153.       Sound_SysBeep();                     /* Beep to confirm the choice.   */
  154.       if (menuwindow != NULL)
  155.         Window_SetTitle(menuwindow, "Whee! A New title!");
  156.       break;
  157.  
  158.     case mainmenu_ITEM2:
  159.       switch(event->data.selection[1])
  160.       {
  161.         case 0:
  162.           Menu_SetFlags(item2menu, 0, 1, 0);  /* Tick item 0   */
  163.           Menu_SetFlags(item2menu, 1, 0, 0);  /* Untick item 1 */
  164.           break;
  165.  
  166.         case 1:
  167.           Menu_SetFlags(item2menu, 0, 0, 0);  /* Untick item 0 */
  168.           Menu_SetFlags(item2menu, 1, 1, 0);  /* Tick item 1   */
  169.           break;
  170.  
  171.         case -1:                      /* Instead of choosing a submenu item, */
  172.                                       /* user clicked main item directly     */
  173.           
  174.           Debug_Printf( "TestApp is now going to cause a deliberate divide-by-zero error\n");
  175.           
  176.           AskUser("query.click");
  177.           
  178.           #ifdef DeskLib_DEBUG
  179.           Debug_Printf( "Infinity = %i\n", event->data.mouse.window/0);
  180.           /* 
  181.           This deliberately causes a division by zero error (warned by
  182.           cc during compilation) in the debug version of TestApp.
  183.           This will cause a signal to be raised in the debug-version. 
  184.           This signal will be displayed and the program terminated.
  185.           */
  186.           #endif
  187.  
  188.           break;
  189.       }
  190.       break;
  191.  
  192.     case mainmenu_QUIT:
  193.       quit = TRUE;
  194.       break;
  195.  
  196.     default:
  197.       Sound_SysBeep();                     /* Beep to confirm the choice.   */
  198.       break;
  199.   }
  200.  
  201.   Wimp_GetPointerInfo(&ptr);               /* If ADJUST was used to select, */
  202.   if (ptr.button.data.adjust)              /* then we keep the menu open.   */
  203.     Menu_ShowLast();
  204.  
  205.   return(TRUE);
  206. }
  207.  
  208.  
  209.  
  210. int main( void)
  211. {
  212.   window_handle window1, window2, window3;
  213.   icon_handle   baricon;
  214.   char          appname[64];
  215.   char          menudescription[260];
  216.  
  217.  
  218.   /*  Tell Resource (and thereby Template, Msgs, etc) where our resource
  219.    *  directory is: "<Tester$Dir>"
  220.    */
  221.   Resource_Initialise("Tester");   /* resources in <Tester$Dir> */
  222.  
  223.  
  224.   /*  Load and cache the messages. Find out the application name.
  225.    */
  226.   Msgs_LoadFile("messages");
  227.   Msgs_Lookup("app.name:Tester", appname, 64);
  228.  
  229.  
  230.   /*  Initialise the Wimp and Event Manager.
  231.    *  The task name shown on the task display and error reports is set from
  232.    *  the string "appname" fetched previously from the messages file.
  233.    */
  234.   Event_Initialise(appname);
  235.   EventMsg_Initialise();
  236.  
  237.   Debug_Initialise();
  238.   Debug_InitialiseSignal();
  239.   Debug_Printf( "DeskLib test application started...\n");
  240.   /*  Print some diagnostic iff the debugging version of !TestApp
  241.    *  is being made
  242.    */
  243.  
  244.   /*  Read and remember the current screen mode information
  245.    *  (width and height, eig-factors, delta-x and delta-y, etc.)
  246.    *  This is needed by the Menu code to get menu widths correct.
  247.    */
  248.   Screen_CacheModeInfo();
  249.  
  250.  
  251.   /*  Add a handler function to a "screen mode changing" Wimp message, so
  252.    *  that the information provided by the "Screen" functions is always
  253.    *  correct.
  254.    *  NOTE that the new Handler_ModeChange should also ensure that outline
  255.    *  fonts will work if we change between lo-res and hi-res screen modes.
  256.    */
  257.   EventMsg_Claim(message_MODECHANGE, event_ANY, Handler_ModeChange, NULL);
  258.  
  259.  
  260.   /*  Plonk an icon onto the iconbar
  261.    */
  262.   baricon = Icon_BarIcon("!testapp", iconbar_RIGHT);
  263.  
  264.  
  265.   /*  Place the Handler_ module skeleton default handlers on all 
  266.    *  Redraw and Open-window request events (Application-wide defaults)
  267.    */
  268.   Event_Claim(event_REDRAW, event_ANY, event_ANY, Handler_NullRedraw, NULL);
  269.   Event_Claim(event_OPEN, event_ANY, event_ANY, Handler_OpenWindow, NULL);
  270.  
  271.  
  272.   /*  Load in and cache our window templates from the template file
  273.    *  "<Tester$Dir>.Templates" (Templates utilise the "Resource Directory"),
  274.    *  with support for using outline fonts in the icons if the file specifies
  275.    *  outline fonts.
  276.    */
  277.   Template_Initialise();
  278.   Template_UseOutlineFonts();
  279.   Template_LoadFile("Templates");
  280.  
  281.   /*  Create and open our main windows from the template "mainwindow".
  282.    *  Open the same window three times (3 copies):
  283.    *  1.  on-screen wherever it was positioned in the template manager,
  284.    *  2.  Centered on screen (screen-mode independent)
  285.    *  3.  Under the pointer (over where the program was double-clicked -note
  286.    *      that the window won't appear until after the hourglass test below
  287.    *      so it may not look like it was opened under the pointer!)
  288.    */
  289.   window1 = Window_CreateAndShow("mainwindow", 0, open_WHEREVER);
  290.   window2 = Window_CreateAndShow("mainwindow", 0, open_CENTERED);
  291.   window3 = Window_CreateAndShow("mainwindow", 0, open_UNDERPOINTER);
  292.  
  293.  
  294.   /*  Claim window-close events
  295.    *  Use the Window_Delete() handler rather than the Wimp_CloseWindow() one
  296.    *  so that the window is closed and deleted and all memory and event 
  297.    *  claims are released whenever the user hits the close icon.
  298.    */
  299.   Event_Claim(event_CLOSE, event_ANY, event_ANY, Handler_DeleteWindow, NULL);
  300.  
  301.  
  302.   /*  Add the 3-d "OK" button click handler so that the OK button (icon #2)
  303.    *  in the 3-d window indents for 1/3rd of a second whenever it is clicked
  304.    */
  305.   Event_Claim(event_CLICK, window2, 2, Handler_ClickOK, NULL);
  306.  
  307.  
  308.   /*  Add the Window_HelpHandler message handler so that help requests
  309.    *  for the 3 main windows and the iconbar icon are automatically handled
  310.    */
  311.   Window_AutoHelp(event_ANY, event_ANY);
  312.  
  313.  
  314.   /*  Menu example/test
  315.    *  1. Create two menu structures from messages in the Msgs file.
  316.    *  2. Attach the 'item2menu' as a submenu of the main menu
  317.    *  3. Extend the submenu by adding another two items to it
  318.    *  4. Add a handler to pop up our menu if we get a menu click over
  319.    *     our icon/windows, and another handler to process menu choices.
  320.    */
  321.   Msgs_Lookup("menu.main", menudescription, 260);
  322.   mainmenu  = Menu_New("TestApp", menudescription);
  323.  
  324.   Msgs_Lookup("menu.item2", menudescription, 260);
  325.   item2menu = Menu_New("SubMenu", menudescription);
  326.  
  327.   item2menu = Menu_Extend(item2menu, "~Extension 1,~Extension 2");
  328.  
  329.   Menu_AddSubMenu(mainmenu, 2, item2menu);
  330.  
  331.   Event_Claim(event_CLICK, event_ANY, event_ANY, ButtonClick, NULL);
  332.   Event_Claim(event_MENU,  event_ANY, event_ANY, MenuChoice,  NULL);
  333.  
  334.  
  335.   /*  Test the SWI call interface, and the Hourglass macros by whizzing
  336.    *  through a 0..100 percent count. Also uses GFX_Wait to tie it
  337.    *  to the vsync, so it will take 1 second to go from 0% to 100%
  338.    *
  339.    *  Also test mouse-rectangle restriction
  340.    */
  341.  
  342.   Pointer_RestrictToWindow(window3);
  343.  
  344.   {
  345.     int loop;
  346.     Hourglass_Start(1);
  347.     for (loop = 0; loop < 100; loop++)
  348.     {
  349.       Hourglass_Percentage(loop);
  350.       GFX_Wait();
  351.     }
  352.     Hourglass_Off();
  353.   }
  354.  
  355.   Pointer_Unrestrict();
  356.  
  357.   /*  Main event handling loop. Let Event_ do all the work for us!
  358.    */
  359.   while (!quit)
  360.     Event_Poll();
  361.  
  362.   Template_ClearAll();
  363.  
  364.   /*  Finally, we just exit. The atexit() handlers will clean up after us
  365.    */
  366.   return(0);
  367. }
  368.