home *** CD-ROM | disk | FTP | other *** search
/ Power Programming / powerprogramming1994.iso / progtool / microcrn / issue_44.arc / MICROCAD.ARC / MSMENU.CPP < prev    next >
Text File  |  1988-09-27  |  6KB  |  210 lines

  1. // Figure 3 for "A Little CAD with C++"
  2. // Copyright 1988 Bruce Eckel
  3. // Permission required to distribute source
  4.  
  5. // file: msmenu.cpp
  6. #include        <stdio.h>
  7. #include    <stdlib.h>
  8. #include    <conio.h>
  9. #include    <msmouse.h>
  10. // flash graphics declarations:
  11. #include        <fg.h>      
  12. #include        <string.h>
  13. #include        "msmenu.hpp"
  14.  
  15. msmenu::msmenu(struct menu_s * mp) {
  16.     char buf[15];
  17.     count = 0;
  18.     // attach the menu pointer to this object:
  19.     m = mp;   
  20.     // Store the size of the menu:
  21.     height = 0;
  22.     struct menu_s * mm = m;
  23.     // look for end marker:
  24.     while ( mm->item_number != -1) {
  25.         height++;
  26.         mm++;
  27.     }
  28.     int ss, i;
  29.     for(i = 0, width = 0; i < height; i++)
  30.         if ((ss = strlen(mp[i].name)) > width)
  31.             // find the largest element:
  32.             width = ss;  
  33.  
  34.     // graphic width:
  35.     xsize = width * CHARWIDTH;   
  36.     // graphic height:
  37.     ysize = height * LINESIZE;   
  38.  
  39.     sizing_box[FG_X1] = 0; 
  40.     sizing_box[FG_Y1] = 0; 
  41.     sizing_box[FG_X2] = xsize + LINESIZE;
  42.     sizing_box[FG_Y2] = ysize + LINESIZE;  
  43.     msize = sizing_box[FG_X2] 
  44.         - sizing_box[FG_X1] + 1;
  45.     msize *= sizing_box[FG_Y2] 
  46.         - sizing_box[FG_Y1] + 1;
  47.     msize *= sizeof(fg_color_t);
  48.     // allocate memory for graphics storage:
  49.     color_p = new fg_color_t[msize];
  50.     blank_p = new fg_color_t[msize];
  51.     // save blank image of menu size:
  52.     fg_readbox(sizing_box, blank_p);  
  53.     // initialize mouse:
  54.     msm_init();                
  55.     // turn mouse cursor on:
  56.     msm_showcursor();            
  57. }
  58.     
  59. msmenu::~msmenu() {
  60.     delete color_p;
  61.     delete blank_p;
  62.     // turn mouse cursor off:
  63.     msm_hidecursor();            
  64.     // terminate use of mouse:
  65.     msm_term();                
  66. }
  67.  
  68. void msmenu::drawmenu(int x,int y) {
  69.   struct menu_s * elem = m;
  70.   for (int i = 0; i < height; i++) {
  71.     fg_puts (FG_WHITE, FG_MODE_SET, ~0, FG_ROT0,
  72.         x,y, elem->name, fg_displaybox);
  73.     elem++;
  74.     y -= LINESIZE;
  75.   }
  76. }
  77.  
  78. /* The following patterns were created from the
  79.    commented block of ones and zeros using the
  80.    tool MSCURSOR.CPP (Figure 13) */
  81.  
  82. static int default_cur[] = {
  83. 0xffff,        /* 0000000000000000 */
  84. 0xdfff,        /* 0010000000000000 */
  85. 0xcfff,        /* 0011000000000000 */
  86. 0xc7ff,        /* 0011100000000000 */
  87. 0xc3ff,        /* 0011110000000000 */
  88. 0xc1ff,        /* 0011111000000000 */
  89. 0xc0ff,        /* 0011111100000000 */
  90. 0xc07f,        /* 0011111110000000 */
  91. 0xc03f,        /* 0011111111000000 */
  92. 0xc01f,        /* 0011111111100000 */
  93. 0xc1ff,        /* 0011111000000000 */
  94. 0xdcff,        /* 0010001100000000 */
  95. 0xfcff,        /* 0000001100000000 */
  96. 0xfe7f,        /* 0000000110000000 */
  97. 0xfe7f,        /* 0000000110000000 */
  98. 0xffff,        /* 0000000000000000 */
  99. 0x0, 0x2000, 0x3000, 0x3800, 0x3c00, 0x3e00, 
  100. 0x3f00, 0x3f80, 0x3fc0, 0x3fe0, 0x3e00, 
  101. 0x2300, 0x300, 0x180, 0x180, 0x0, 
  102. };
  103.  
  104. static int menu_cur[] = {
  105. 0xffff,        /* 0000000000000000 */
  106. 0xffff,        /* 0000000000000000 */
  107. 0xffff,        /* 0000000000000000 */
  108. 0xffff,        /* 0000000000000000 */
  109. 0xffef,        /* 0000000000010000 */
  110. 0xdfe7,        /* 0010000000011000 */
  111. 0x6fe3,        /* 1001000000011100 */
  112. 0xb7e1,        /* 0100100000011110 */
  113. 0xc000,        /* 0011111111111111 */
  114. 0xb7e1,        /* 0100100000011110 */
  115. 0x6fe3,        /* 1001000000011100 */
  116. 0xdfe7,        /* 0010000000011000 */
  117. 0xffef,        /* 0000000000010000 */
  118. 0xffff,        /* 0000000000000000 */
  119. 0xffff,        /* 0000000000000000 */
  120. 0xffff,        /* 0000000000000000 */
  121. 0x0, 0x0, 0x0, 0x0, 0x10, 0x2018, 
  122. 0x901c, 0x481e, 0x3fff, 0x481e, 
  123. 0x901c, 0x2018, 0x10, 0x0, 0x0, 0x0, 
  124. };
  125.  
  126. static int cross_cur[] = {
  127. 0xffff,        /* 0000000000000000 */
  128. 0xffff,        /* 0000000000000000 */
  129. 0xffff,        /* 0000000000000000 */
  130. 0xfeff,        /* 0000000100000000 */
  131. 0xfeff,        /* 0000000100000000 */
  132. 0xfeff,        /* 0000000100000000 */
  133. 0xfeff,        /* 0000000100000000 */
  134. 0xfeff,        /* 0000000100000000 */
  135. 0x0,        /* 1111111111111111 */
  136. 0xfeff,        /* 0000000100000000 */
  137. 0xfeff,        /* 0000000100000000 */
  138. 0xfeff,        /* 0000000100000000 */
  139. 0xfeff,        /* 0000000100000000 */
  140. 0xffff,        /* 0000000000000000 */
  141. 0xffff,        /* 0000000000000000 */
  142. 0xffff,        /* 0000000000000000 */
  143. 0x0, 0x0, 0x0, 0x100, 0x100, 0x100, 
  144. 0x100, 0x100, 0xffff, 0x100, 0x100, 
  145. 0x100, 0x100, 0x0, 0x0, 0x0, 
  146. };
  147.  
  148. /* the first two numbers are the x and y 
  149.    coordinates of the "hot spot", with the 
  150.    upper left corner = 0,0: */
  151.  
  152. void msmenu::default_cursor() {
  153.     msm_setgraphcur(-1,-1,default_cur);
  154. }
  155.  
  156. void msmenu::menu_cursor() {
  157.     msm_setgraphcur(-16,-8,menu_cur);
  158. }
  159.  
  160. void msmenu::cross_cursor() {
  161.     msm_setgraphcur(-8,-8,cross_cur);
  162. }
  163.  
  164. int 
  165. msmenu::get_selection(unsigned x, unsigned yy) {
  166.     unsigned int u,v, startv;
  167.     unsigned y = yy;
  168.     fg_box_t    read_box;
  169.     translate_coords(&x,&y);
  170.     read_box[FG_X1] = x;
  171.     read_box[FG_Y1] = y - ysize + LINESIZE;
  172.     read_box[FG_X2] = x + xsize;  
  173.     read_box[FG_Y2] = y + LINESIZE;
  174.  
  175.     msm_hidecursor();
  176.     // use special cursor:
  177.     menu_cursor();
  178.     fg_readbox(read_box, color_p);
  179.     // blank section out:
  180.     fg_writebox(read_box, blank_p);  
  181.     // call a private function:
  182.     drawmenu(x,y);   
  183.     // trial-and-error:
  184.     msm_setcurpos(x - 35 , yy -22);  
  185.     msm_showcursor();  
  186.     msm_setareax(x -35, x - 35);
  187.     msm_setareay(yy - 22,
  188.                  yy - 22 + ysize - LINESIZE );
  189.     startv = yy - 22;
  190.     wait_left_pressed(&u,&v);
  191.     wait_left_released(&u,&v);
  192.  
  193.     // put everything back the way it was:
  194.     msm_setareax(fg_displaybox[FG_X1], 
  195.                  fg_displaybox[FG_X2]);
  196.     msm_setareay(fg_displaybox[FG_Y1],
  197.                  fg_displaybox[FG_Y2]);
  198.     msm_hidecursor();
  199.     // Restore old cursor:
  200.     default_cursor(); 
  201.     // restore original position:
  202.     msm_setcurpos(x, yy);  
  203.     // restore screen:
  204.     fg_writebox(read_box, color_p); 
  205.     msm_showcursor();
  206.     // calculate which item was selected:
  207.     return m[(v - startv)/LINESIZE].item_number;
  208. }    
  209.     
  210.