home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 1997 March / VPR9703A.ISO / VPR_DATA / DOGA / SOURCES / POLYEDIT.LZH / MODEL / MENU.C < prev    next >
C/C++ Source or Header  |  1996-07-25  |  9KB  |  418 lines

  1. /*
  2.  *        メニュー表示
  3.  *
  4.  *        Copyright    Koabayashi    1994.7.9
  5.  */
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include <stdlib.h>
  9. #include <assert.h>
  10.  
  11. #include "ml.h"
  12.  
  13. #include "view.h"
  14. #include "menu.h"
  15.  
  16. #include "graph.h"
  17. #include "input.h"
  18. #include "model.h"
  19.  
  20. #define    MENU_STEP    15
  21.  
  22. #ifdef WINDOWS
  23. extern void SetWindowsMenu(int no);
  24. #endif
  25. extern int    QuitFlag;
  26.  
  27. MenuClass    *Menu[MAX_MENU] ;
  28. MenuClass    *MenuStack[MENU_LEVELS][MAX_MENU] ;
  29. int            MenuPos[MAX_MENU+1];
  30. int            MenuStackPtr ;
  31. int            CurrentX, CurrentY;
  32.  
  33. static    int        PopUpMenu( int, int, int, ItemName*, int*, int*, int );
  34. static    void    PrintMenuLine( int, int, char*, int, int, int, int );
  35. static    void    QueryMenuEnable(int);
  36.  
  37. /*    メニュー初期化    */
  38. void    MenuInit()
  39. {
  40.     int        i ;
  41.  
  42.     for( i = 0 ; i < MAX_MENU ; i++ )
  43.         Menu[i] = NULL ;
  44.     MenuStackPtr = 0 ;
  45. }
  46.  
  47. static    short    CheckMark[] = {
  48.     0x0100, 0x0200, 0x0200, 0x0400, 0x0400, 0x4800, 0x2800, 0x1000,
  49. };
  50.  
  51. /*    タイトルバーの表示    */
  52. void    DrawTitleBar()
  53. {
  54. #ifndef WINDOWS
  55.     int        i ;
  56.  
  57.     graph_fill( 0, 0, DISPLAY_X-1, MENU_WIDTH-2, FRAME_COLOR );
  58.     graph_line( 0, MENU_WIDTH-1, DISPLAY_X-1, MENU_WIDTH-1, 0 );
  59.  
  60.     MenuPos[0] = 0;
  61.     for( i = 0 ; i < MAX_MENU ; i++ )
  62.     {
  63.         MenuPos[i+1] = MenuPos[i];
  64.         if ( Menu[i] != NULL ) {
  65.             graph_puts( Menu[i]->title, MenuPos[i] + FontH, 0, FRAME_COLOR<<4 );
  66.             MenuPos[i+1] += (strlen(Menu[i]->title)+2) * FontH;
  67.         }
  68.     }
  69.     DrawCursorPos();
  70. #endif
  71. }
  72.  
  73. /*    メニューイベントの呼び出し    */
  74. void    CallMenu( x, y )
  75. int        x, y ;
  76. {
  77.     int        i, n ;
  78.     int        exec ;
  79.     DataStruct    *top ;
  80.  
  81. #if 0
  82.     x /= MENU_STEP * FontH ;
  83. #endif
  84.     for (n = x, i = 0, x = -1; i < MAX_MENU; i++) {
  85.         if (MenuPos[i] <= n && n < MenuPos[i+1]) {
  86.             x = i;
  87.             break;
  88.         }
  89.     }
  90.     exec = -1 ;
  91.     if ( 0 <= x && x < MAX_MENU && Menu[x] != NULL && Menu[x]->items > 0 ) {
  92.         QueryMenuEnable(x);
  93.         n = PopUpMenu( MenuPos[x], MenuPos[x+1]-MenuPos[x], FontV+3, Menu[x]->item, Menu[x]->exec, Menu[x]->check, Menu[x]->items );
  94.         if ( n < 0  || (Menu[x]->check[n] & MENU_DISABLE) != 0)
  95.             return ;
  96.         exec = Menu[x]->exec[n] ;
  97.         if ( exec >= 0 )
  98.         {
  99.             top = StackTop();
  100.             StackPushInt( n );
  101.             CallFunction( exec, 1, top+1 );
  102.             StackRelease( top );
  103.         }
  104.     } else {
  105.         WaitMouseOff();
  106.     }
  107. }
  108.  
  109. void    ExecMenu(int x, int y)
  110. {
  111.     DataStruct    *top ;
  112.     if (0 <= x && x < MAX_MENU && Menu[x] != NULL
  113.      && 0 <= y && y < Menu[x]->items && Menu[x]->exec[y] >= 0) {
  114.         top = StackTop();
  115.         StackPushInt( y );
  116.         CallFunction( Menu[x]->exec[y], 1, top+1 );
  117.         StackRelease( top );
  118.     }
  119. }
  120.  
  121. static    int        PopUpMenu( x, w, y, item, exec, check, items )
  122. int            x, w, y ;
  123. ItemName    *item ;
  124. int            *exec ;
  125. int            *check;
  126. int            items ;
  127. {
  128.     int        ret, i, n, len, len1, len2 ;
  129.     int        mx, my ;
  130.     int        x1, y1, x2, y2 ;
  131.     char     *p;
  132.     int        height[MAX_ITEM+1];
  133.  
  134.     len1 = len2 = 0;
  135.     height[0] = 0;
  136.     for( i = 0 ; i < items ; ++i )
  137.     {
  138.         if (item[i][0] == '-' && item[i][1] == '-' && item[i][2] == '-') {
  139.             height[i+1] = height[i] + 5;
  140.         } else {
  141.             height[i+1] = height[i] + FontV + 1;
  142.         }
  143.         if ((p = strchr(item[i], '\t')) != NULL) {
  144.             int l1 = p - item[i];
  145.             if (l1 > 4 && p[-4] == '(' && p[-3] == '&' && p[-1] == ')') {
  146.                 l1 -= 4;
  147.             }
  148.             if (len1 < l1) {
  149.                 len1 = l1;
  150.             }
  151.             if (len2 < strlen(p+1)) {
  152.                 len2 =  strlen(p+1);
  153.             }
  154.         } else {
  155.             int l1 = strlen(item[i]);
  156.             if (l1 > 4 && item[i][l1-4] == '(' && item[i][l1-3] == '&' && item[i][l1-1] == ')') {
  157.                 l1 -= 4;
  158.             }
  159.             if ( len1 < l1) {
  160.                 len1 = l1;
  161.             }
  162.         }
  163.     }
  164.     if (len2 > 0) {
  165.         len = len1 + 1 + len2;
  166.     } else {
  167.         len = len1;
  168.     }
  169.  
  170.     x1 = x + 4 ;
  171.     x2 = x1 + (len+2) * FontH ;
  172.  
  173.     if (x2 > DISPLAY_X-1) {
  174.         x1 -= (x2 - (DISPLAY_X-1));
  175.         x2 -= DISPLAY_X-1;
  176.     }
  177.     y1 = y - 1 ;
  178.     y2 = y + height[items] + 1;
  179.     if (graph_push(x1, y1, x2-x1+1, y2-y1+1) == FALSE) {
  180.         ViewCursor( OFF );
  181.     }
  182. #ifdef    X68K
  183.     graph_fill( x1+1, y1+1, x2-1, y2-1, TMP_COLOR );
  184. #endif
  185.     graph_fill( x1+1, y1+1, x2-1, y2-1, FRAME_COLOR );
  186.     graph_box( x1, y1, x2, y2, TRUE );
  187.  
  188.     for( i = 0 ; i < items ; ++i )
  189.         PrintMenuLine( x+FontH, y+height[i], item[i], len, len2, FRAME_COLOR<<4, check[i] );
  190.     ret = -1 ;
  191.  
  192.     do
  193.     {
  194.         WaitInput();
  195.         mx = MouseX ;
  196.         my = MouseY ;
  197.         if ( my < y && ( mx < x || x+w < mx ) )
  198.         {
  199.             ret = -1 ;
  200.             break ;
  201.         }
  202. #if 0
  203.         n = ( my - y ) / FontV ;
  204. #else
  205.         for (n = 0; n < items; n++) {
  206.             if ((my-y) < height[n+1]) {
  207.                 break;
  208.             }
  209.         }
  210. #endif
  211.         if ( my < y || items <= n )
  212.             n = -1 ;
  213.         if ( n != ret )
  214.         {
  215.             if ( ret >= 0 && (check[ret] & MENU_DISABLE) == 0)
  216.             {
  217.                 if ( exec[ret] >= 0 )
  218.                     PrintMenuLine( x+FontH, y+height[ret], item[ret], len, len2, FRAME_COLOR<<4, check[ret] );
  219.             }
  220.             if ( n >= 0 && (check[n] & MENU_DISABLE) == 0)
  221.             {
  222.                 if ( exec[n] >= 0 )
  223.                     PrintMenuLine( x+FontH, y+height[n], item[n], len, len2, FRAME_COLOR, check[n] );
  224.             }
  225.             ret = n ;
  226.         }
  227.         if (QuitFlag) {
  228.             return -1;
  229.         }
  230.     }
  231.     while( MouseLeft || MouseRight );
  232.  
  233.     if (graph_pop() == FALSE) {
  234.         ViewFrame();
  235.         ViewLineAll( x1, y1, x2, y2, TRUE );
  236.         ViewCursor( ON );
  237.     }
  238.     return ret ;
  239. }
  240.  
  241. static    void    PrintMenuLine( x, y, msg, len, len2, atr, check )
  242. int        x, y ;
  243. char    *msg ;
  244. int        len, len2 ;
  245. int        atr ;
  246. int        check ;
  247. {
  248.     int i, len1;
  249.     char *p, *q;
  250.     char    buf[100] ;
  251.     char    *format =
  252.     " %s                                                                  ";
  253.  
  254.     if (msg[0] == '-' && msg[1] == '-' && msg[2] == '-') {
  255.         x = x-FontH + 4 ;
  256.         y = y + 2;
  257.         graph_line( x, y-1, x + (len+2) * FontH, y-1, 0);
  258.         graph_line( x, y,   x + (len+2) * FontH, y,   7);
  259.         return;
  260.     }
  261.     if (len2 == 0) {
  262. #if 0
  263.         sprintf( buf, format, msg );
  264.         buf[len+1] = '\0' ;
  265.         if (buf[len-3] == '(' && buf[len-2] == '&' && buf[len] == ')') {
  266.             buf[len-3] = '\0';
  267.         }
  268. #endif
  269.         int l;
  270.         l = strlen(msg);
  271.         if (l > 4 && msg[l-4] == '(' && msg[l-3] == '&' && msg[l-1] == ')') {
  272.             l -= 4;
  273.         }
  274.         buf[0] = ' ';
  275.         strncpy(buf+1, msg, l);
  276.         memset(buf+1+l, ' ', len - l+2);
  277.         buf[len+1] = '\0' ;
  278.     } else {
  279.         len1 = len - len2 - 1;
  280.         p = buf;
  281.         q = msg;
  282.         *p++ = ' ';
  283.         for (i = 0; *q && *q != '\t'; i++) {
  284.             *p++ = *q++;
  285.         }
  286.         if (i > 4 && p[-4] == '(' && p[-3] == '&' && p[-1] == ')') {
  287.             i -= 4;
  288.             p -= 4;
  289.         }
  290.         if (*q != '\t') {
  291.             for (; i < len; i++) {
  292.                 *p++ = ' ';
  293.             }
  294.             *p = '\0';
  295.         } else {
  296.             for (; i < len1 + 1; i++) {
  297.                 *p++ = ' ';
  298.             }
  299.             q++;
  300.             for (i = 0; *q && *q != '\t'; i++) {
  301.                 *p++ = *q++;
  302.             }
  303.             for (; i < len2; i++) {
  304.                 *p++ = ' ';
  305.             }
  306.             *p = '\0';
  307.         }
  308.     }
  309.     if (check & MENU_DISABLE) {
  310. #if 0
  311.         graph_puts( buf, x, y, (atr & 0xf0) | BG_COLOR );
  312. #else
  313.         graph_puts( buf, x+1, y+1, (atr & 0xf0) | 7 );
  314.         graph_puts( buf, x, y,     (atr & 0xf0) | BG_COLOR | 0x100);
  315. #endif
  316.     } else {
  317.         graph_puts( buf, x, y, atr );
  318.     }
  319.     if (check & MENU_CHECK) {
  320.         graph_pattern( x + FontH - 8, y + (FontV-8)/2, atr, CheckMark, 8, 8 );
  321.     }
  322. }
  323.  
  324. /*    メニューの設定    */
  325. void    SetMenu( menu, no )
  326. MenuClass    *menu ;
  327. int        no ;
  328. {
  329.     assert( 0 <= no && no < MAX_MENU );
  330.     if ( Menu[no] != NULL )
  331.         ObjectFree( (Object*)(Menu[no]) );
  332.     Menu[no] = (MenuClass*)ObjectAlloc( sizeof( MenuClass ), MenuClassID );
  333.     *(Menu[no]) = *menu ;
  334. #ifdef WINDOWS
  335.     SetWindowsMenu(no);
  336. #endif
  337. }
  338.  
  339. /*    子メニューに行く    */
  340. void    PushMenu()
  341. {
  342.     int        i ;
  343.  
  344.     assert( MenuStackPtr < MENU_LEVELS - 1 );
  345.     for( i = 0 ; i < MAX_MENU ; i++ )
  346.     {
  347.         MenuStack[MenuStackPtr][i] = Menu[i] ;
  348.         Menu[i] = NULL ;
  349.     }
  350.     MenuStackPtr++ ;
  351. #ifdef WINDOWS
  352.     SetWindowsMenu(-1);
  353. #endif
  354. }
  355.  
  356. /*    親メニューに戻る    */
  357. void    PopMenu()
  358. {
  359.     int        i ;
  360.  
  361.     assert( MenuStackPtr > 0 );
  362.     MenuStackPtr-- ;
  363. #ifdef WINDOWS
  364.     SetWindowsMenu(-1);
  365. #endif
  366.     for( i = 0 ; i < MAX_MENU ; i++ )
  367.     {
  368.         if ( Menu[i] != NULL )
  369.             ObjectFree( (Object*)(Menu[i]) );
  370.         Menu[i] = MenuStack[MenuStackPtr][i] ;
  371. #ifdef WINDOWS
  372.         SetWindowsMenu(i);
  373. #endif
  374.     }
  375. }
  376.  
  377. static    void    QueryMenuEnable(int x)
  378. {
  379.     int y;
  380.     for (y = 0; y < Menu[x]->items; ++y) {
  381.         if (Menu[x]->query[y] >= 0) {
  382.             DataStruct *top;
  383.  
  384.             CurrentX = x;
  385.             CurrentY = y;
  386.             top = StackTop();
  387.             StackPushInt( x );
  388.             StackPushInt( y );
  389.             CallFunction( Menu[x]->query[y], 2, top+2 );
  390.             StackRelease( top );
  391.             CurrentX = CurrentY = -1;
  392.         }
  393.     }
  394. }
  395.  
  396. void    CurrentMenuItem(char *str)
  397. {
  398.     if (CurrentX >= 0 && CurrentY >= 0) {
  399.         strncpy(Menu[CurrentX]->item[CurrentY], str, ITEM_LEN);
  400.         Menu[CurrentX]->item[CurrentY][ITEM_LEN] = '\0';
  401.     }
  402. }
  403.  
  404. void    CurrentMenuFunction(int ident)
  405. {
  406.     if (CurrentX >= 0 && CurrentY >= 0) {
  407.         Menu[CurrentX]->exec[CurrentY] = ident;
  408.     }
  409. }
  410.  
  411. void    CurrentMenuEnable(int check)
  412. {
  413.     if (CurrentX >= 0 && CurrentY >= 0) {
  414.         Menu[CurrentX]->check[CurrentY] = check;
  415.     }
  416. }
  417.  
  418.