home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / FLTK-1.0.6 / test / demo.cxx < prev    next >
Encoding:
C/C++ Source or Header  |  1999-02-22  |  9.1 KB  |  337 lines

  1. //
  2. // "$Id: demo.cxx,v 1.8 1999/02/22 21:09:13 mike Exp $"
  3. //
  4. // Main demo program for the Fast Light Tool Kit (FLTK).
  5. //
  6. // Copyright 1998-1999 by Bill Spitzak and others.
  7. //
  8. // This library is free software; you can redistribute it and/or
  9. // modify it under the terms of the GNU Library General Public
  10. // License as published by the Free Software Foundation; either
  11. // version 2 of the License, or (at your option) any later version.
  12. //
  13. // This library is distributed in the hope that it will be useful,
  14. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16. // Library General Public License for more details.
  17. //
  18. // You should have received a copy of the GNU Library General Public
  19. // License along with this library; if not, write to the Free Software
  20. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  21. // USA.
  22. //
  23. // Please report all bugs and problems to "fltk-bugs@easysw.com".
  24. //
  25.  
  26. #include <stdio.h>
  27. #include <string.h>
  28. #include <stdlib.h>
  29. #if defined(WIN32) && !defined(CYGNUS)
  30. #  include <direct.h>
  31. #else
  32. #  include <unistd.h>
  33. #endif
  34. #include <FL/Fl.H>
  35. #include <FL/Fl_Window.H>
  36. #include <FL/Fl_Box.H>
  37. #include <FL/Fl_Button.H>
  38. #include <FL/filename.H>
  39. #include <FL/x.H>
  40.  
  41. /* The form description */
  42.  
  43. void doexit(Fl_Widget *, void *);
  44. void doback(Fl_Widget *, void *);
  45. void dobut(Fl_Widget *, long);
  46.  
  47. Fl_Window *form;
  48. Fl_Button *but[9];
  49.  
  50. void create_the_forms() {
  51.   Fl_Widget *obj;
  52.   form = new Fl_Window(370, 450);
  53.   obj = new Fl_Box(FL_FRAME_BOX,20,390,330,40,"FLTK Demonstration");
  54.   obj->color(FL_GRAY-4);
  55.   obj->labelsize(24);
  56.   obj->labelfont(FL_BOLD);
  57.   obj->labeltype(FL_ENGRAVED_LABEL);
  58.   obj = new Fl_Box(FL_FRAME_BOX,20,50,330,330,0);
  59.   obj->color(FL_GRAY-8);
  60.   obj = new Fl_Button(130,10,110,30,"Exit");
  61.   obj->callback(doexit);
  62.   obj = new Fl_Button(20,50,330,380); obj->type(FL_HIDDEN_BUTTON);
  63.   obj->callback(doback);
  64.   obj = but[0] = new Fl_Button(40,270,90,90);
  65.   obj = but[1] = new Fl_Button(140,270,90,90);
  66.   obj = but[2] = new Fl_Button(240,270,90,90);
  67.   obj = but[5] = new Fl_Button(240,170,90,90);
  68.   obj = but[4] = new Fl_Button(140,170,90,90);
  69.   obj = but[3] = new Fl_Button(40,170,90,90);
  70.   obj = but[6] = new Fl_Button(40,70,90,90);
  71.   obj = but[7] = new Fl_Button(140,70,90,90);
  72.   obj = but[8] = new Fl_Button(240,70,90,90);
  73.   for (int i=0; i<9; i++) {
  74.     but[i]->align(FL_ALIGN_WRAP);
  75.     but[i]->callback(dobut, i);
  76.   }
  77.   form->forms_end();
  78. }
  79.  
  80. /* Maintaining and building up the menus. */
  81.  
  82. typedef struct {
  83.   char name[64];
  84.   int numb;
  85.   char iname[9][64];
  86.   char icommand[9][64];
  87. } MENU;
  88.  
  89. #define MAXMENU    32
  90.  
  91. MENU menus[MAXMENU];
  92. int mennumb = 0;
  93.  
  94. int find_menu(char nnn[])
  95. /* Returns the number of a given menu name. */
  96. {
  97.   int i;
  98.   for (i=0; i<mennumb; i++)
  99.     if (strcmp(menus[i].name,nnn) == 0) return i;
  100.   return -1;
  101. }
  102.  
  103. void create_menu(char nnn[])
  104. /* Creates a new menu with name nnn */
  105. {
  106.   if (mennumb == MAXMENU -1) return;
  107.   strcpy(menus[mennumb].name,nnn);
  108.   menus[mennumb].numb = 0;
  109.   mennumb++;
  110. }
  111.  
  112. void addto_menu(char men[], char item[], char comm[])
  113. /* Adds an item to a menu */
  114. {
  115.   int n = find_menu(men);
  116.   if (n<0) { create_menu(men); n = find_menu(men); }
  117.   if (menus[n].numb == 9) return;
  118.   strcpy(menus[n].iname[menus[n].numb],item);
  119.   strcpy(menus[n].icommand[menus[n].numb],comm);
  120.   menus[n].numb++;
  121. }
  122.  
  123. /* Button to Item conversion and back. */
  124.  
  125. int b2n[][9] = { 
  126.     { -1, -1, -1, -1,  0, -1, -1, -1, -1},
  127.     { -1, -1, -1,  0, -1,  1, -1, -1, -1},
  128.     {  0, -1, -1, -1,  1, -1, -1, -1,  2},
  129.     {  0, -1,  1, -1, -1, -1,  2, -1,  3},
  130.     {  0, -1,  1, -1,  2, -1,  3, -1,  4},
  131.     {  0, -1,  1,  2, -1,  3,  4, -1,  5},
  132.     {  0, -1,  1,  2,  3,  4,  5, -1,  6},
  133.     {  0,  1,  2,  3, -1,  4,  5,  6,  7},
  134.     {  0,  1,  2,  3,  4,  5,  6,  7,  8}
  135.   };
  136. int n2b[][9] = { 
  137.     {  4, -1, -1, -1, -1, -1, -1, -1, -1},
  138.     {  3,  5, -1, -1, -1, -1, -1, -1, -1},
  139.     {  0,  4,  8, -1, -1, -1, -1, -1, -1},
  140.     {  0,  2,  6,  8, -1, -1, -1, -1, -1},
  141.     {  0,  2,  4,  6,  8, -1, -1, -1, -1},
  142.     {  0,  2,  3,  5,  6,  8, -1, -1, -1},
  143.     {  0,  2,  3,  4,  5,  6,  8, -1, -1},
  144.     {  0,  1,  2,  3,  5,  6,  7,  8, -1},
  145.     {  0,  1,  2,  3,  4,  5,  6,  7,  8}
  146.   };
  147.  
  148. int but2numb(int bnumb, int maxnumb)
  149. /* Transforms a button number to an item number when there are
  150.    maxnumb items in total. -1 if the button should not exist. */
  151.  { return b2n[maxnumb][bnumb]; }
  152.  
  153. int numb2but(int inumb, int maxnumb)
  154. /* Transforms an item number to a button number when there are
  155.    maxnumb items in total. -1 if the item should not exist. */
  156.  { return n2b[maxnumb][inumb]; }
  157.  
  158. /* Pushing and Popping menus */
  159.  
  160. char stack[64][32];
  161. char stsize = 0;
  162.  
  163. void push_menu(char nnn[])
  164. /* Pushes a menu to be visible */
  165. {
  166.   int n,i,bn;
  167.   int men = find_menu(nnn);
  168.   if (men < 0) return;
  169.   n = menus[men].numb;
  170.   for (i=0; i<9; i++) but[i]->hide();
  171.   for (i=0; i<n; i++)
  172.   {
  173.     bn = numb2but(i,n-1);
  174.     but[bn]->show();
  175.     but[bn]->label(menus[men].iname[i]);
  176.   }
  177.   strcpy(stack[stsize],nnn);
  178.   stsize++;
  179. }
  180.  
  181. void pop_menu()
  182. /* Pops a menu */
  183. {
  184.   if (stsize<=1) return;
  185.   stsize -= 2;
  186.   push_menu(stack[stsize]);
  187. }
  188.  
  189. /* The callback Routines */
  190.  
  191. void dobut(Fl_Widget *, long arg)
  192. /* handles a button push */
  193. {
  194.   int men = find_menu(stack[stsize-1]);
  195.   int n = menus[men].numb;
  196.   int bn = but2numb( (int) arg, n-1);
  197.   if (menus[men].icommand[bn][0] == '@')
  198.     push_menu(menus[men].icommand[bn]);
  199.   else {
  200.  
  201. #ifdef WIN32
  202.     STARTUPINFO        suInfo;        // Process startup information
  203.     PROCESS_INFORMATION    prInfo;        // Process information
  204.  
  205.     memset(&suInfo, 0, sizeof(suInfo));
  206.     suInfo.cb = sizeof(suInfo);
  207.  
  208.     int icommand_length = strlen(menus[men].icommand[bn]);
  209.  
  210.     char* copy_of_icommand = new char[icommand_length+1];
  211.     strcpy(copy_of_icommand,menus[men].icommand[bn]);
  212.  
  213.     // On WIN32 the .exe suffix needs to be appended to the command
  214.     // whilst leaving any additional parameters unchanged - this
  215.     // is required to handle the correct conversion of cases such as : 
  216.     // `../fluid/fluid valuators.fl' to '../fluid/fluid.exe valuators.fl'.
  217.  
  218.     // skip leading spaces.
  219.     char* start_command = copy_of_icommand;
  220.     while(*start_command == ' ') ++start_command;
  221.  
  222.     // find the space between the command and parameters if one exists.
  223.     char* start_parameters = strchr(start_command,' ');
  224.  
  225.     char* command = new char[icommand_length+6]; // 6 for extra 'd.exe\0'
  226.  
  227.     if (start_parameters==NULL) { // no parameters required.
  228. #  ifdef _DEBUG
  229.       sprintf(command, "%sd.exe", start_command);
  230. #  else
  231.       sprintf(command, "%s.exe", start_command);
  232. #  endif // _DEBUG
  233.     } else { // parameters required.
  234.       // break the start_command at the intermediate space between
  235.       // start_command and start_parameters.
  236.       *start_parameters = 0;
  237.       // move start_paremeters to skip over the intermediate space.
  238.       ++start_parameters;
  239.  
  240. #  ifdef _DEBUG
  241.       sprintf(command, "%sd.exe %s", start_command, start_parameters);
  242. #  else
  243.       sprintf(command, "%s.exe %s", start_command, start_parameters);
  244. #  endif // _DEBUG
  245.     }
  246.  
  247.     CreateProcess(NULL, command, NULL, NULL, FALSE,
  248.                   NORMAL_PRIORITY_CLASS, NULL, NULL, &suInfo, &prInfo);
  249.     
  250.     delete command;
  251.     delete copy_of_icommand;
  252.     
  253. #else // NON WIN32 systems.
  254.  
  255.     int icommand_length = strlen(menus[men].icommand[bn]);
  256.     char* command = new char[icommand_length+5]; // 5 for extra './' and ' &\0' 
  257.  
  258.     sprintf(command, "./%s &", menus[men].icommand[bn]);
  259.     system(command);
  260.  
  261.     delete command;
  262. #endif // WIN32
  263.   }
  264. }
  265.  
  266. void doback(Fl_Widget *, void *) {pop_menu();}
  267.  
  268. void doexit(Fl_Widget *, void *) {exit(0);}
  269.  
  270. int load_the_menu(const char fname[])
  271. /* Loads the menu file. Returns whether successful. */
  272. {
  273.   FILE *fin;
  274.   char line[256], mname[64],iname[64],cname[64];
  275.   int i,j;
  276.   fin = fopen(fname,"r");
  277.   if (fin == NULL)
  278.   {
  279. //    fl_show_message("ERROR","","Cannot read the menu description file.");
  280.     return 0;
  281.   }
  282.   for (;;) {
  283.     if (fgets(line,256,fin) == NULL) break;
  284.     j = 0; i = 0;
  285.     while (line[i] == ' ' || line[i] == '\t') i++;
  286.     if (line[i] == '\n') continue;
  287.     if (line[i] == '#') continue;
  288.     while (line[i] != ':' && line[i] != '\n') mname[j++] = line[i++];
  289.     mname[j] = '\0';
  290.     if (line[i] == ':') i++;
  291.     j = 0; 
  292.     while (line[i] != ':' && line[i] != '\n')
  293.     {
  294.       if (line[i] == '\\') {
  295.     i++;
  296.     if (line[i] == 'n') iname[j++] = '\n';
  297.     else iname[j++] = line[i];
  298.     i++;
  299.       } else
  300.         iname[j++] = line[i++];
  301.     }
  302.     iname[j] = '\0';
  303.     if (line[i] == ':') i++;
  304.     j = 0;
  305.     while (line[i] != ':' && line[i] != '\n') cname[j++] = line[i++];
  306.     cname[j] = '\0';
  307.     addto_menu(mname,iname,cname);
  308.   }
  309.   fclose(fin);
  310.   return 1;
  311. }
  312.  
  313. int main(int argc, char **argv) {
  314.   create_the_forms();
  315.   char buf[256];
  316.   strcpy(buf, argv[0]);
  317.   filename_setext(buf,".menu");
  318.   const char *fname = buf;
  319.   int i = 0;
  320.   if (!Fl::args(argc,argv,i) || i < argc-1)
  321.     Fl::fatal("Usage: %s <switches> <menufile>\n%s",Fl::help);
  322.   if (i < argc) fname = argv[i];
  323.   if (!load_the_menu(fname)) Fl::fatal("Can't open %s",fname);
  324.   strcpy(buf,fname);
  325.   const char *c = filename_name(buf);
  326.   if (c > buf) {buf[c-buf] = 0; chdir(buf);}
  327.   push_menu("@main");
  328.   form->show(argc,argv);
  329.   Fl::run();
  330.   return 0;
  331. }
  332.  
  333. //
  334. // End of "$Id: demo.cxx,v 1.8 1999/02/22 21:09:13 mike Exp $".
  335. //
  336.  
  337.