home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c100 / 1.ddi / SNAV0111.ZIP / DEMO2.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1990-04-16  |  9.5 KB  |  367 lines

  1. //          ┌───────┐
  2. //    ─────────>│ AVNER │
  3. //    ─────────>│  BEN  │──────> Software Engineering Method
  4. //          └───────┘
  5. //    10 Dov-Hoz st. Tel-Aviv 63416 Israel tel. 972-3-221535
  6.  
  7. // The Screen NAVigator, ver 1.10 April 1990
  8. // Copyright (c) 1989 by Avner Ben
  9. // Snav is not, and never was, free software.
  10. // for conditions for use refer to file "copyrigh.txt"
  11.  
  12. // The Screen Navigator is an object-oriented device-independent
  13. // character-graphics driver package, written in the C++ language,
  14. // distributed in the form of C++ source code.
  15. // For further information refer to the documentation files.
  16.  
  17. // this simple example is intended as a template to be extended and modified
  18. // by the user, provided the above title and copyright notice are unchanged
  19. // and are not ommitted.
  20.  
  21. /***************************************************************************/
  22.  
  23. // demonstration part 2 - source code.
  24. // a simplistic formatted-input driver, implemented with the screen driver
  25. // of demo part 1. Device-specific assumptions made about function key
  26. // values. Implemented are only the methods required by the main demo program.
  27.  
  28. // 28.10.89 avner ben coded.
  29. /////// snav v1.1
  30. // 8.3.90-7.4.90 avner ben:
  31. // *  C++  v2.0  upgrade  *  modified  some  functions to return by value *
  32. // simplified class  char_input using  inheritance *  default screen-driver
  33. // allocation  *  made    class  character_input    generic  * removed char-set
  34. // dependant tests to driver * optimized box redraw in text-window *
  35.  
  36. // site history (this copy):
  37. // __.__.__, _____________: _______________________________.
  38.  
  39. #include <conio.h>
  40. #include <ctype.h>
  41. #ifndef SNAV2_H
  42. #include "snav2.hpp"
  43. #endif
  44. #include "demo2.hpp"
  45.  
  46. extern screen_driver_manager screen_driver;
  47. extern keyboard_driver_manager keyboard_driver;
  48.  
  49. character_input :: character_input(panel *inscr)
  50. {
  51.     private_screen=FALSE;
  52.     scr=inscr;
  53.     cc=' '; fkey=K_C;
  54. }
  55.  
  56. character_input :: character_input(const square_pos &window, int driver_num)
  57. {
  58.     private_screen=TRUE;
  59.     scr=screen_driver.allocate(window,driver_num);
  60.     cc=' '; fkey=K_C;
  61. }
  62.  
  63. character_input :: ~character_input()
  64. {
  65.     if (private_screen) delete scr;
  66. }
  67.  
  68. boolean character_input :: get_position(char * prompt, panel *drawbd, boolean hilite)
  69. {
  70.     if (*prompt)
  71.         { clear(); scr->put_s(prompt); }
  72.     drawbd->posit();
  73.     while (get_c()!='\r') {
  74.         if (cc=='\033')
  75.             { clear(); return(FALSE); }
  76.         if (fkey) switch (fkey) {
  77.             case K_RT :  drawbd->next(&(direction)rt); break;
  78.             case K_UP :  drawbd->next(&(direction)up); break;
  79.             case K_LT :  drawbd->next(&(direction)lt); break;
  80.             case K_DN :  drawbd->next(&(direction)dn); break;
  81.         }
  82.     }
  83.     if (hilite) drawbd->put_attr(VD_REV);
  84.     clear();
  85.     return(TRUE);
  86. }
  87.  
  88. int character_input :: get_number(char *prompt, int imax)
  89. {
  90.     scr->put_s(prompt); next();
  91.     int i=0; char c;
  92.     while (isdigit(get_c()) || i==0) {
  93.         if (cc=='\033') return(0);
  94.         if (isdigit(cc) && i*10+charnum(cc)<=imax) {
  95.             i=i*10+charnum(cc);
  96.             scr->put_c(cc);
  97.             if (i*10>imax) break;
  98.         }
  99.     }
  100.     return(i);
  101. }
  102.  
  103. direction character_input :: get_dir()
  104. {
  105.     scr->put_s("direction (arrw):"); next();
  106.     direction dir(NODIR);
  107.     while (!dir()) {
  108.         get_c();
  109.         switch (fkey) {
  110.             case K_RT :     dir=rt; break;
  111.             case K_UP :     dir=up; break;
  112.             case K_LT :     dir=lt; break;
  113.             case K_DN :     dir=dn; break;
  114.         }
  115.     }
  116.     scr->put_s(dir.name());
  117.     return dir;
  118. }
  119.  
  120. weight_d character_input :: get_wgt()
  121. {
  122.     scr->put_s("weight (h:v):"); next();
  123.     int i[2];
  124.     for (int j=0; j<=1; j++) {
  125.         put_c_stay('1');
  126.         while (get_c()!='\r')
  127.             if (cc>='0' && cc<='3') break;
  128.         if (cc=='\r') cc='1';
  129.         i[j]=charnum(cc);
  130.         scr->put_c(cc);
  131.         if (j<1) scr->put_c(':');
  132.     }
  133.     weight_d result(i[0],i[1]);
  134.     return result;
  135. }
  136.  
  137. boolean character_input :: get_boolean(char *prompt)
  138. {
  139.     scr->put_s(prompt); next();
  140.     put_c_stay('Y');
  141.     for (get_c(); ; get_c())
  142.         if (cc=='Y' || cc=='y' || cc=='\r') {
  143.             scr->put_c('Y'); return(TRUE);
  144.         } else if (cc=='N' || cc=='n') {
  145.             scr->put_c('N'); return(FALSE);
  146.         }
  147. }
  148.  
  149. void character_input :: msg(char *prompt)
  150. {
  151.     clear();
  152.     scr->put_s(prompt); get_c();
  153.     clear();
  154. }
  155.  
  156. character_input *keyboard_driver_manager :: allocate(const square_pos &window,
  157.  int scr_num, int kbd_num)
  158. {
  159.     if (!kbd_num) kbd_num=default_kbd;
  160.  
  161.     switch (kbd_num) {
  162.         case 1 : return new pc_keyboard((square_pos)window, scr_num);
  163.         // insert here other drivers you may have...
  164.         default: return new pc_keyboard((square_pos)window, scr_num);
  165.         // installation default
  166.     }
  167. }
  168.  
  169. character_input *keyboard_driver_manager :: allocate(panel *scr, int kbd_num)
  170. {
  171.     if (!kbd_num) kbd_num=default_kbd;
  172.  
  173.     switch (kbd_num) {
  174.         case 1 : return new pc_keyboard(scr);
  175.         // insert here other drivers you may have...
  176.         default: return new pc_keyboard(scr);
  177.         // installation default
  178.     }
  179. }
  180.  
  181. char pc_keyboard :: get_c()
  182. { // device-specific primitive
  183.  
  184.     if (!(cc=getch())) {                 // pc-specific scan-codes
  185.         cc=' ';
  186.         switch ((cc=getch())) {
  187.             case 'M' :  fkey=K_RT; break;
  188.             case 'H' :  fkey=K_UP; break;
  189.             case 'K' :  fkey=K_LT; break;
  190.             case 'P' :  fkey=K_DN; break;
  191.         }
  192.     } else fkey=K_C;
  193.     return cc;
  194. }
  195.  
  196.  
  197. slide_option :: slide_option(char *text, int posopt, char *help)
  198. {
  199.     s=new char[strlen(text)+1]; strcpy(s,text);
  200.     hlp=new char[strlen(help)+1]; strcpy(hlp,help);
  201.     // convert all but option char to lower-case
  202.     if (posopt<1 || posopt>strlen(text)) posopt=1; posopt-=1;
  203.     letter=s+posopt;
  204.     for (int i=strlen(text)-1; i>=0; i--)
  205.         if (i==posopt) s[i]=toupper(s[i]);
  206.         else s[i]=tolower(s[i]);
  207.     num=0;
  208.     next=last=NULL;
  209. }
  210.  
  211. slide_menu :: slide_menu(panel *parent, panel *help)
  212. { // chops top line off parent screen!
  213.     scr=screen_driver.allocate(parent->ask_window());
  214.     scr->set_limit(up,parent->ask_limit(up));
  215.     parent->move_limit(up,-1);
  216.     explain=help;
  217.     stopt=enopt=cursor=NULL;
  218.     scr->clear();
  219. }
  220.  
  221. slide_menu :: ~slide_menu(void)
  222. {
  223.     delete(scr);
  224.     if (stopt) {
  225.         slide_option *next=stopt->next;
  226.         for (; stopt; stopt=next) {
  227.             next=stopt->next;
  228.             delete(stopt);
  229.         }
  230.     }
  231. }
  232.  
  233. void slide_menu :: append_opt(char *text, int posopt, char *help)
  234. {
  235.     if (!*text) return;
  236.     enopt=new slide_option(text, posopt, help);
  237.     if (!stopt) {
  238.         cursor=stopt=enopt;
  239.         enopt->pos=scr->ask_corner(up);
  240.         scr->put_c('│',&(enopt->pos)); (enopt->pos).move(rt);
  241.         enopt->num=1;
  242.     } else {
  243.         for (slide_option *opt0=stopt; opt0->next; opt0=opt0->next) ;
  244.         opt0->next=enopt; enopt->last=opt0;
  245.         enopt->num=opt0->num+1;
  246.         enopt->pos=opt0->pos;
  247.         (enopt->pos).move(rt,strlen(opt0->s)+1);
  248.     }
  249.     enopt->on(scr);
  250.     point_pos pt=enopt->pos;
  251.     pt.move(rt,strlen(enopt->s));
  252.     scr->put_c('│',&pt);
  253.     pt.move(rt);
  254.     if (!scr->get_attr(VD_REV,&pt))
  255.         while (scr->ask_legal(&pt)) {
  256.             scr->put_attr(VD_REV,&pt); pt.move(rt);
  257.         }
  258. }
  259.  
  260. void slide_menu :: next_opt()
  261. {
  262.     if (!stopt) return;
  263.     cursor->on(scr);
  264.     if (cursor->next) cursor=cursor->next;
  265.     else cursor=stopt;
  266.     cursor->off(scr); cursor->put_help(explain);
  267. }
  268.  
  269. void slide_menu :: prev_opt()
  270. {
  271.     if (!stopt) return;
  272.     cursor->on(scr);
  273.     if (cursor->last) cursor=cursor->last;
  274.     else cursor=enopt;
  275.     cursor->off(scr); cursor->put_help(explain);
  276. }
  277.  
  278. int slide_menu :: select()
  279. {
  280.     if (!stopt) return 0;
  281.     if (!stopt->next) return 1;
  282.     cursor->off(scr); cursor->put_help(explain);
  283.     char c;
  284.     while ((c=getch())!='\r') {
  285.         if (c=='\033') return 0;
  286.         else if (c=='\0') {
  287.             c=getch();
  288.             if (c=='M') next_opt(); // PC-specific fkey values
  289.             else if (c=='K') prev_opt();
  290.         } else {
  291.             c=toupper(c);
  292.             for (slide_option *opt=stopt; opt; opt=opt->next)
  293.                 if (*(opt->letter)==c) {
  294.                     cursor->on(scr);
  295.                     cursor=opt; cursor->off(scr);
  296.                     cursor->put_help(explain);
  297.                     break;
  298.                 }
  299.             if (c==*(cursor->letter)) break; // auto select
  300.         }
  301.     }
  302.     explain->clear();
  303.     return cursor->num;
  304. }
  305.  
  306. #include <stdio.h>
  307. text_window :: text_window(panel *parent, point_pos *pt0, char *title, boolean centered, char *inpline[])
  308. {
  309.     point_pos start;
  310.     if (pt0 && parent->ask_legal(pt0)) start=*pt0;
  311.     else {
  312.         start.sety(parent->ask_limit(up));
  313.         start.setx(parent->ask_limit(lt));
  314.     }
  315.     int len=0;
  316.     for (int numlns=0; inpline[numlns][0]; numlns++)
  317.         if (strlen(inpline[numlns])>len)
  318.             len=strlen(inpline[numlns]);
  319.     if (len+start.x()-1+2>parent->ask_limit(rt))
  320.         len=parent->ask_limit(rt)-start.x()+1-2;
  321.     if (numlns+start.y()-1+2>parent->ask_limit(dn))
  322.         len=parent->ask_limit(dn)-start.y()+1-2;
  323.     box=screen_driver.allocate(square_pos(start,
  324.      point_pos(start.y()+numlns-1+2,start.x()+len-1+2)));
  325.     box->save();
  326.     box->toggle_attr(VD_HI);
  327.     box->enframe(h2v1,title,centered);
  328.     box->toggle_attr(VD_HI);
  329.     point_pos pos=box->ask_corner(up);
  330.     for (int i=0; i<numlns; i++) {
  331.         box->posit(&pos);
  332.         box->put_s(inpline[i]);
  333.         pos.move(dn);
  334.     }
  335. }
  336.  
  337. void text_window :: pause(char *prompt)
  338. {
  339.     if (*prompt) {
  340.         box->move_limit(dn,1);
  341.         point_pos stpos(box->ask_limit(dn),box->ask_limit(lt));
  342.         weight_d wgt=alph->cweight(box->get_c(&stpos));
  343.         int col=box->ask_limit(rt)-strlen(prompt)+1;
  344.         box->reset_color();
  345.         if (col>=box->ask_limit(lt))
  346.             box->put_s(prompt,&point_pos(box->ask_limit(dn),col));
  347.         else box->put_s(prompt,&stpos);
  348.         if (!getch()) getch();
  349.         box->toggle_attr(VD_HI);
  350.         box->arclist(&stpos,box->ask_len(hdim),rt,wgt);
  351.         box->move_limit(dn,-1);
  352.         box->toggle_attr(VD_HI);
  353.     } else if (!getch()) getch();
  354. }
  355.  
  356. void text_window :: put_page(char *inpline[])
  357. {
  358.     box->clear();
  359.     for (int numlns=0; inpline[numlns][0]; numlns++) ;
  360.     point_pos pos(box->ask_limit(up),box->ask_limit(lt));
  361.     for (int i=0; i<numlns; i++) {
  362.         box->posit(&pos);
  363.         box->put_s(inpline[i]);
  364.         pos.move(dn);
  365.     }
  366. }
  367.