home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 1 / ARM_CLUB_CD.iso / contents / education / a / biology1 / !Biology1 / c / Choices next >
Text File  |  1991-12-03  |  5KB  |  184 lines

  1. /* Choices.c */
  2.  
  3. #include <string.h>
  4. #include <stdlib.h>
  5. #include <ctype.h>
  6.  
  7. #include "wimp.h"
  8. #include "wimpt.h"
  9. #include "data.h"
  10.  
  11. #include "input.h"
  12.  
  13. #include "keys.h"
  14. #include "texticon.h"
  15. #include "utils.h"
  16.  
  17. extern int correct_ans_num;
  18. extern int standard_line;
  19. extern subtopic *test;
  20.  
  21. typedef struct
  22.   { wimp_i icon;
  23.     char *string;
  24.   } text_icon;
  25.  
  26. typedef struct
  27.   { struct choice *next;
  28.     struct text   *choice;
  29.   } choice;
  30.  
  31. struct iconlist
  32.   { struct iconlist *next;
  33.     wimp_i handle;
  34.     char *text;
  35.   };
  36.  
  37. /* Capitalizes 1st char, lower case the rest & returns str */
  38. char *set_case (char *str)
  39.   { char *ptr = str;
  40.     while (*ptr && !isalpha(*ptr))
  41.         ptr++;
  42.     *ptr = toupper (*ptr);
  43.     while (*ptr)
  44.       { ptr++;
  45.         *ptr = tolower (*ptr);
  46.       }
  47.     return (str);
  48.   }
  49.  
  50. int ct_lines (text t)
  51.   { int i, no;
  52.  
  53.     for (i=0, no=1; t[i] != '\0'; i++)
  54.         if (t[i] == '\n')
  55.             no++;
  56.     return (no);
  57.   }
  58.  
  59.  
  60. int  max_wide (text t, int lines)
  61.   { int i, j, max;
  62.  
  63.     if (lines == 1)
  64.         return (strlen (t));
  65.     for (i = max = 0; i < lines; i++)
  66.       { for (j = 0; t[j] != '\0'; j++)
  67.           { if (t[j] == '\n')
  68.                 max = max (j, max);
  69.           }
  70.       }                                   
  71.     return (max);
  72.   }
  73.  
  74. void make_icon_ch (text_icon *res, wimp_w w, int line, text t,
  75.                    int lines, int width, BOOL force_redraw)
  76. /* Some dodgy 'hardwiring' in here */
  77.   { wimp_icreate ic;
  78.  
  79.     res->string = t;
  80.     
  81.     ic.w  = w;
  82.     ic.i.box.x0 = 4 + (standard_line - width) * 8  ;       /* centred */
  83.     ic.i.box.x1 = ic.i.box.x0 + (width * 8 + 4) * 2;
  84.     ic.i.box.y1 = - line * 8 * 4;
  85.     ic.i.box.y0 = ic.i.box.y1 - lines * 40 - 12;
  86.     ic.i.flags  = wimp_ITEXT | wimp_IBORDER | wimp_IFILLED |
  87.                   wimp_INDIRECT | wimp_IVCENTRE | wimp_IHCENTRE |
  88.                   wimp_IBTYPE * wimp_BCLICKDEBOUNCE |
  89.                   wimp_IFORECOL * 7 |
  90.                   15 << 28; /* wimp_IBACKCOL * 15 signed const overflow */
  91.     ic.i.data.indirecttext.buffer = res->string;
  92.     ic.i.data.indirecttext.validstring = "L40";
  93.     ic.i.data.indirecttext.bufflen = strlen (res->string) + 1;
  94.  
  95.     wimpt_noerr (texticon_create_icon (&ic, &res->icon));
  96.  
  97.     if (force_redraw)
  98.       { wimp_redrawstr r;
  99.        
  100.         r.w = w;
  101.         memcpy (&r.box, &ic.i.box, sizeof (wimp_box));
  102.         wimpt_noerr (wimp_force_redraw (&r));
  103.       }
  104.   }
  105.  
  106. void *prompt_choice (wimp_w wnd, int line, question *curr_quest,
  107.                      int quest_no, int test_type)
  108.   { int        ct, limit, range, ch_line;
  109.     int        max_lines, max_width, width, lines, text_width[5];
  110.     int        chosen[5];
  111.     BOOL       choice_displayed[10];
  112.     text_icon  choice_item[5];
  113.     text       choice_str;
  114.     text       temp_ans;
  115.     wimp_i     ch_icon[5];
  116.                           
  117.     for (ct = 0; ct < 10; choice_displayed[ct++] = FALSE)
  118.         ;
  119.     if ( test_type == 3)
  120.       { range = 10;
  121.         limit = 5;
  122.         choice_displayed[quest_no] = TRUE;  /* flag current answer as displayed */
  123.       }
  124.     else
  125.       { range = curr_quest->no_choice;
  126.         limit = range + 1;
  127.       }                         
  128.     correct_ans_num = rand () % limit;
  129.     if (test_type == 7)
  130.       { temp_ans = malloc (strlen (curr_quest->ans) + 1);
  131.         strcpy (temp_ans, curr_quest->ans);
  132.         set_case (curr_quest->ans);        
  133.       }
  134.     max_lines = ct_lines (curr_quest->ans);
  135.     max_width = max_wide (curr_quest->ans, max_lines);
  136.     text_width[correct_ans_num] = max_width;
  137.     for (ct = 0; ct < limit; ct++)
  138.       { if (ct != correct_ans_num)
  139.           { do {
  140.                  chosen[ct] = rand () % range;
  141.                } while (choice_displayed[chosen[ct]]);
  142.             choice_displayed[chosen[ct]] = TRUE;
  143.             if (range == 10)
  144.                 choice_str = test->question[chosen[ct]].ans;
  145.             else
  146.                 choice_str = curr_quest->choice[chosen[ct]];
  147.             lines = ct_lines (choice_str);
  148.             max_lines = max (lines, max_lines);
  149.             width = max_wide (choice_str, lines);
  150.             max_width = max (width, max_width);
  151.             text_width[ct] = width;
  152.           }
  153.       }
  154.     if (max_width > 25)
  155.       { for (ct = 0; ct < limit; text_width[ct++] = max_width)
  156.             ;
  157.       }
  158.     for (ct = 0, ch_line = line; ct < limit; ct++)
  159.       { if (ct == correct_ans_num)       
  160.           { make_icon_ch (&choice_item[ct], wnd, ch_line, curr_quest->ans,
  161.                           max_lines, text_width[ct], FALSE);
  162.           }
  163.         else
  164.           { if (range == 10)
  165.                 choice_str = test->question[chosen[ct]].ans;
  166.             else
  167.                 choice_str = curr_quest->choice[chosen[ct]];
  168.             make_icon_ch (&choice_item[ct], wnd, ch_line, choice_str,
  169.                           max_lines, text_width[ct], FALSE); 
  170.           }
  171.         ch_line += 3;     
  172.         ch_icon[ct] = choice_item[ct].icon;
  173.         input_icon (wnd, ch_icon[ct], NULL, -100+ct);
  174.       }                                
  175.     if (test_type == 7)
  176.       { strcpy (curr_quest->ans, temp_ans);   /* restore value */
  177.         free (temp_ans);
  178.       }
  179.     return (concat_choice_wakeup (wnd, ch_icon, limit));
  180.   }  
  181.  
  182.  
  183.  
  184.