home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 1997 March / VPR9703A.ISO / VPR_DATA / DOGA / SOURCES / POLYEDIT.LZH / MODEL / MENULIB.C < prev    next >
C/C++ Source or Header  |  1996-08-01  |  14KB  |  530 lines

  1. /*
  2.  *        メニュー表示
  3.  *
  4.  *        Copyright    Koabayashi    1994.7.9
  5.  */
  6. #include <stdio.h>
  7. #include <string.h>
  8.  
  9. #include "ml.h"
  10. #include "strclass.h"
  11.  
  12. #include "menu.h"
  13.  
  14. static    ExecData    SysConst[] = {
  15.     { TYPE_FUNC,    0,        -1,            },
  16.     { TYPE_INT,        0,        MENU_CHECK,            },
  17.     { TYPE_INT,        0,        MENU_DISABLE,            },
  18.     { TYPE_INT,        0,        0,            },
  19. };
  20.  
  21. int        MenuClassID ;
  22.  
  23. static    int        SetMenuData( int, int, DataStruct* );
  24. static    int        SetMenuPosition( int, int, DataStruct* );
  25. static    int        GetMenuPosition( int, int, DataStruct* );
  26. static    int        FuncInsertMenu( int, int, DataStruct* );
  27. static    int        FuncMenuItems( int, int, DataStruct* );
  28. static    int        FuncUpdateTitleBar( int, int, DataStruct* );
  29. static    int        FuncUpdateAttribute( int, int, DataStruct* );
  30. static    int        FuncUpdateObject( int, int, DataStruct* );
  31. static    int        FuncPushMenu( int, int, DataStruct* );
  32. static    int        FuncPopMenu( int, int, DataStruct* );
  33. static    int        FuncMenuTitle( int, int, DataStruct* );
  34. static    int        FuncMenuItem( int, int, DataStruct* );
  35. static    int        FuncMenuFunction( int, int, DataStruct* );
  36. static    int        FuncMenuQuery( int, int, DataStruct* );
  37. static    int        FuncMenuEnable( int, int, DataStruct* );
  38. static    int        FuncCurrentMenuItem( int, int, DataStruct* );
  39. static    int        FuncCurrentMenuFunction( int, int, DataStruct* );
  40. static    int        FuncCurrentMenuEnable( int, int, DataStruct* );
  41.  
  42. /*    初期化    */
  43. void    MenuLibInit()
  44. {
  45.     MenuClassID = NewClass( "Menu", 0 );
  46.     NewFunction( MenuClassID, "MenuPosition", SetMenuPosition );
  47.     NewFunction( 0, "MenuPosition", GetMenuPosition );
  48.     NewFunction( 0, "Menu", SetMenuData );
  49.     NewFunction( MenuClassID, "InsertMenu", FuncInsertMenu);
  50.     NewFunction( MenuClassID, "MenuItems", FuncMenuItems);
  51.     NewFunction( 0, "UpdateTitleBar", FuncUpdateTitleBar );
  52.     NewFunction( 0, "UpdateAttribute", FuncUpdateAttribute );
  53.     NewFunction( 0, "UpdateObject", FuncUpdateObject );
  54.     NewFunction( 0, "PushMenu", FuncPushMenu );
  55.     NewFunction( 0, "PopMenu", FuncPopMenu );
  56.  
  57.     NewFunction( MenuClassID, "MenuTitle", FuncMenuTitle);
  58.     NewFunction( MenuClassID, "MenuItem", FuncMenuItem);
  59.     NewFunction( MenuClassID, "MenuFunction", FuncMenuFunction);
  60.     NewFunction( MenuClassID, "MenuQuery", FuncMenuQuery);
  61.     NewFunction( MenuClassID, "MenuEnable", FuncMenuEnable);
  62.  
  63.     NewFunction( ClassName("String"), "MenuItem", FuncCurrentMenuItem);
  64.     NewFunction( 0, "MenuFunction", FuncCurrentMenuFunction);
  65.     NewFunction( 0, "MenuEnable", FuncCurrentMenuEnable);
  66.  
  67.     NewConst( "SEPARATE_MENU", (DataStruct*)&SysConst[0] );
  68.     NewConst( "MENU_CHECK", (DataStruct*)&SysConst[1] );
  69.     NewConst( "MENU_DISABLE", (DataStruct*)&SysConst[2] );
  70.     NewConst( "MENU_NOCHECK", (DataStruct*)&SysConst[3] );
  71.     NewConst( "MENU_ENABLE", (DataStruct*)&SysConst[3] );
  72. }
  73.  
  74. /*    メニューオブジェクトの設定    */
  75. static    int        SetMenuData( ident, args, buf )
  76. int        ident ;
  77. int        args ;
  78. DataStruct    *buf ;
  79. {
  80.     int        i, j ;
  81.     MenuClass    *menu ;
  82.  
  83.     menu = (MenuClass*)ObjectAlloc( sizeof( MenuClass ), MenuClassID );
  84.  
  85.     /*    タイトル名    */
  86.     if ( args == 0 )
  87.         ExecError( "引数の数が違います。(Menu)" );
  88.     if ( buf[0].type != TYPE_OBJECT || ObjectCheck( &buf[0], ClassName( "String" ) ) == FALSE )
  89.         ExecError( "%d番目の引数の型が違います。(Menu)", 1 );
  90.     strncpy( menu->title, ((StringClass*)buf[0].od.ptr)->str, TITLE_LEN );
  91.     menu->title[TITLE_LEN] = '\0' ;
  92. #ifndef WINDOWS
  93.     i = strlen(menu->title);
  94.     if (i > 5 && menu->title[i-1] == ')' && menu->title[i-3] == '&' && menu->title[i-4] == '(') {
  95.         menu->title[i-4] = '\0';
  96.     }
  97. #endif
  98.  
  99.     /*    項目数    */
  100.     /*    項目名    */
  101.     buf = buf + 1 ;
  102.     args -- ;
  103.     for( i = j = 0 ; i + 1 < args ; i += 2, j++)
  104.     {
  105.         if ( buf[i].type != TYPE_OBJECT ||
  106.             ObjectCheck( &buf[i], ClassName( "String" ) ) == FALSE )
  107.         {
  108.             ExecError( "%d番目の引数の型が違います。(Menu)", i+2 );
  109.         }
  110.         strncpy( menu->item[j], ((StringClass*)buf[i].od.ptr)->str, ITEM_LEN );
  111.         menu->item[j][ITEM_LEN] = '\0' ;
  112.         if ( buf[i+1].type != TYPE_FUNC )
  113.             ExecError( "%d番目の引数の型が違います。(Menu)", i+3 );
  114.         menu->exec[j] = buf[i+1].funcd.ident ;
  115.         if (i + 2 < args && buf[i+2].type == TYPE_FUNC) {
  116.             menu->query[j] = buf[i+2].funcd.ident;
  117.             i++;
  118.         } else {
  119.             menu->query[j] = -1;
  120.         }
  121.         if (i + 2 < args && buf[i+2].type == TYPE_INT) {
  122.             menu->check[j] = buf[i+2].id.i;
  123.             i++;
  124.         } else {
  125.             menu->check[j] = 0;
  126.         }
  127.     }
  128.     menu->items = j;
  129.  
  130.     buf = StackAlloc( 1 );
  131.     buf->type = TYPE_OBJECT ;
  132.     buf->od.ptr = (Object*)menu ;
  133.  
  134.     return RETURN_RETURN ;
  135. }
  136.  
  137. /*    メニューの設定    */
  138. static    int        SetMenuPosition( ident, args, buf )
  139. int        ident ;
  140. int        args ;
  141. DataStruct    *buf ;
  142. {
  143.     int        n ;
  144.  
  145.     ArgCheck( "MenuPosition", args, buf, TYPE_OBJECT, TYPE_INT, TYPE_NOASN );
  146.  
  147.     n = buf[1].id.i ;
  148.     if ( n < 0 || MAX_MENU <= n )
  149.     {
  150.         ExecError( "2番目の引数の値が不正です。(SetPosition)" );
  151.     }
  152.  
  153.     SetMenu( (MenuClass*)buf[0].od.ptr, n );
  154.     DrawTitleBar();
  155.  
  156.     return RETURN_VOID ;
  157. }
  158.  
  159. /*    メニューの設定    */
  160. static    int        GetMenuPosition( ident, args, buf )
  161. int        ident ;
  162. int        args ;
  163. DataStruct    *buf ;
  164. {
  165.     int        n ;
  166.     MenuClass *menu;
  167.  
  168.     ArgCheck( "MenuPosition", args, buf, TYPE_INT, TYPE_NOASN );
  169.     n = buf[0].id.i;
  170.  
  171.     if (n < 0 || n >= MAX_MENU || Menu[n] == NULL) {
  172.         StackPushBoolean(FALSE);
  173.     } else {
  174.         menu = (MenuClass*)ObjectAlloc( sizeof( MenuClass ), MenuClassID );
  175.         *menu = *(Menu[n]);
  176.         buf = StackAlloc( 1 );
  177.         buf->type = TYPE_OBJECT ;
  178.         buf->od.ptr = (Object*)menu ;
  179.     }
  180.     return RETURN_RETURN ;
  181. }
  182.  
  183. static    int        FuncUpdateTitleBar( ident, args, buf )
  184. int        ident ;
  185. int        args ;
  186. DataStruct    *buf ;
  187. {
  188.     DrawTitleBar();
  189.     return RETURN_VOID ;
  190. }
  191.  
  192. static    int        FuncUpdateAttribute( ident, args, buf )
  193. int        ident ;
  194. int        args ;
  195. DataStruct    *buf ;
  196. {
  197.     DrawAttrSelect();
  198.     return RETURN_VOID ;
  199. }
  200.  
  201. static    int        FuncUpdateObject( ident, args, buf )
  202. int        ident ;
  203. int        args ;
  204. DataStruct    *buf ;
  205. {
  206.     DrawObjSelect();
  207.     return RETURN_VOID ;
  208. }
  209.  
  210. static    int        FuncPushMenu( ident, args, buf )
  211. int        ident ;
  212. int        args ;
  213. DataStruct    *buf ;
  214. {
  215.     if ( MenuStackPtr < MENU_LEVELS - 1 )
  216.         PushMenu();
  217.     else
  218.         ExecError( "メニューのレベルが深すぎます(PushMenu)" );
  219.     return RETURN_VOID ;
  220. }
  221.  
  222. static    int        FuncPopMenu( ident, args, buf )
  223. int        ident ;
  224. int        args ;
  225. DataStruct    *buf ;
  226. {
  227. #if 0
  228.     if ( MenuStackPtr > 0 )
  229.     {
  230.         PopMenu();
  231.         DrawTitleBar();
  232.     }
  233.     else
  234.         ExecError( "メニューのレベルは最上位です(PopMenu)" );
  235.     return RETURN_VOID ;
  236. #else
  237.     if (MenuStackPtr > 0) {
  238.         PopMenu();
  239.         DrawTitleBar();
  240.         StackPushBoolean( TRUE );
  241.     } else {
  242.         StackPushBoolean( FALSE );
  243.     }
  244.     return RETURN_RETURN;
  245. #endif
  246. }
  247.  
  248. static    int        FuncMenuItems( ident, args, buf )
  249. int        ident ;
  250. int        args ;
  251. DataStruct    *buf ;
  252. {
  253.     int i, j;
  254.     MenuClass *menu;
  255.     StringClass *p;
  256.     menu = (MenuClass*)(buf[0].od.ptr);
  257.     StackPushInt(menu->items);
  258.     return RETURN_RETURN;
  259. }
  260.  
  261.  
  262. static    int        FuncInsertMenu( ident, args, buf )
  263. int        ident ;
  264. int        args ;
  265. DataStruct    *buf ;
  266. {
  267.     int i, j;
  268.     MenuClass *omenu, *menu;
  269.     StringClass *p;
  270.     omenu = (MenuClass*)(buf[0].od.ptr);
  271.  
  272.     if (buf[1].type != TYPE_INT || args < 4) {
  273.         ExecError( "引数の型が異なります(InsertMenu)" );
  274.     }
  275.     menu = (MenuClass*)ObjectAlloc( sizeof( MenuClass ), MenuClassID );
  276.     *menu = *omenu;
  277.     j = buf[1].id.i;
  278.     if (j < 0 || j >= menu->items || menu->items >= MAX_ITEM-1) {
  279.         ExecError( "引数の範囲が無効です(InsertMenu)" );
  280.     }
  281.     for (i = menu->items; i > j; --i) {
  282.         strcpy(menu->item[i], menu->item[i-1]);
  283.         menu->exec[i] = menu->exec[i-1];
  284.         menu->query[i] = menu->query[i-1];
  285.         menu->check[i] = menu->check[i-1];
  286.     }
  287.     menu->items++;
  288.  
  289.     if (buf[2].type != TYPE_OBJECT ||
  290.         ObjectCheck( &buf[2], ClassName( "String" ) ) == FALSE )
  291.     {
  292.         ExecError( "%d番目の引数の型が違います。(Menu)", 2 );
  293.     }
  294.     strncpy( menu->item[j], ((StringClass*)buf[2].od.ptr)->str, ITEM_LEN );
  295.     menu->item[j][ITEM_LEN] = '\0' ;
  296.  
  297.     if ( buf[3].type != TYPE_FUNC )
  298.         ExecError( "%d番目の引数の型が違います。(Menu)", 3 );
  299.     menu->exec[j] = buf[3].funcd.ident ;
  300.  
  301.     i = 4;
  302.     if (i < args && buf[i].type == TYPE_FUNC) {
  303.         menu->query[j] = buf[i].funcd.ident;
  304.         i++;
  305.     } else {
  306.         menu->query[j] = -1;
  307.     }
  308.     if (i < args && buf[i].type == TYPE_INT) {
  309.         menu->check[j] = buf[i].id.i;
  310.         i++;
  311.     } else {
  312.         menu->check[j] = 0;
  313.     }
  314.  
  315.     buf = StackAlloc( 1 );
  316.     buf->type = TYPE_OBJECT ;
  317.     buf->od.ptr = (Object*)menu ;
  318.  
  319.     return RETURN_RETURN;
  320. }
  321.  
  322. static    int        FuncMenuTitle( ident, args, buf )
  323. int        ident ;
  324. int        args ;
  325. DataStruct    *buf ;
  326. {
  327.     MenuClass *menu, *nmenu;
  328.     StringClass *p;
  329.     menu = (MenuClass*)(buf[0].od.ptr);
  330.     if (args == 1) {
  331.         p = StringAlloc(strlen(menu->title));
  332.         strcpy(p->str, menu->title);
  333.         buf = StackAlloc( 1 );
  334.         buf->type = TYPE_OBJECT ;
  335.         buf->od.ptr = (Object*)p ;
  336.     } else {
  337.         ArgCheck( "MenuTitle", args, buf, TYPE_OBJECT, TYPE_OBJECT, TYPE_NOASN );
  338.         if (ObjectCheck( &buf[1], ClassName( "String" ) ) == FALSE ) {
  339.             ExecError( "引数の型が異なります(MenuTitle)" );
  340.         }
  341.         nmenu = (MenuClass*)ObjectAlloc( sizeof( MenuClass ), MenuClassID );
  342.         p = (StringClass*)buf[1].od.ptr;
  343.         *nmenu = *menu;
  344.         buf = StackAlloc( 1 );
  345.         buf->type = TYPE_OBJECT ;
  346.         buf->od.ptr = (Object*)nmenu ;
  347.  
  348.         strncpy( nmenu->title, p->str, TITLE_LEN );
  349.         nmenu->title[TITLE_LEN] = '\0' ;
  350.     }
  351.     return RETURN_RETURN;
  352. }
  353.  
  354. static    int        FuncMenuItem( ident, args, buf )
  355. int        ident ;
  356. int        args ;
  357. DataStruct    *buf ;
  358. {
  359.     int n;
  360.     MenuClass *menu, *nmenu;
  361.     StringClass *p;
  362.     menu = (MenuClass*)(buf[0].od.ptr);
  363.     if (args < 2 || buf[1].type != TYPE_INT)
  364.         ExecError( "引数の型が異なります(MenuItem)" );
  365.     n = buf[1].id.i;
  366.     if (n < 0 || n >= menu->items) {
  367.         StackPushBoolean(FALSE);
  368.     } else if (args == 2) {
  369.         p = StringAlloc(strlen(menu->item[n]));
  370.         strcpy(p->str, menu->item[n]);
  371.         buf = StackAlloc( 1 );
  372.         buf->type = TYPE_OBJECT ;
  373.         buf->od.ptr = (Object*)p ;
  374.     } else {
  375.         if (ObjectCheck( &buf[2], ClassName( "String" ) ) == FALSE ) {
  376.             ExecError( "引数の型が異なります(MenuItem)" );
  377.         }
  378.         nmenu = (MenuClass*)ObjectAlloc( sizeof( MenuClass ), MenuClassID );
  379.         *nmenu = *menu;
  380.         strncpy( nmenu->item[n], ((StringClass*)buf[2].od.ptr)->str, ITEM_LEN );
  381.         nmenu->item[n][ITEM_LEN] = '\0';
  382.         buf = StackAlloc( 1 );
  383.         buf->type = TYPE_OBJECT ;
  384.         buf->od.ptr = (Object*)nmenu ;
  385.  
  386.     }
  387.     return RETURN_RETURN;
  388. }
  389.  
  390. static    int        FuncMenuFunction( ident, args, buf )
  391. int        ident ;
  392. int        args ;
  393. DataStruct    *buf ;
  394. {
  395.     int n;
  396.     MenuClass *menu, *nmenu;
  397.     menu = (MenuClass*)(buf[0].od.ptr);
  398.     if (args < 2 || buf[1].type != TYPE_INT)
  399.         ExecError( "引数の型が異なります(MenuFunction)" );
  400.     n = buf[1].id.i;
  401.     if (n < 0 || n >= menu->items) {
  402.         StackPushBoolean(FALSE);
  403.     } else if (args == 2) {
  404.         buf = StackAlloc( 1 );
  405.         buf->type = TYPE_FUNC ;
  406.         buf->funcd.ident = menu->exec[n];
  407.     } else {
  408.         if (buf[2].type != TYPE_FUNC) {
  409.             ExecError( "引数の型が異なります(MenuFunction)" );
  410.         }
  411.         nmenu = (MenuClass*)ObjectAlloc( sizeof( MenuClass ), MenuClassID );
  412.         *nmenu = *menu;
  413.         nmenu->exec[n] = buf[2].funcd.ident;
  414.         buf = StackAlloc( 1 );
  415.         buf->type = TYPE_OBJECT ;
  416.         buf->od.ptr = (Object*)nmenu ;
  417.  
  418.     }
  419.     return RETURN_RETURN;
  420. }
  421.  
  422. static    int        FuncMenuQuery( ident, args, buf )
  423. int        ident ;
  424. int        args ;
  425. DataStruct    *buf ;
  426. {
  427.     int n;
  428.     MenuClass *menu, *nmenu;
  429.     menu = (MenuClass*)(buf[0].od.ptr);
  430.     if (args < 2 || buf[1].type != TYPE_INT)
  431.         ExecError( "引数の型が異なります(MenuFunction)" );
  432.     n = buf[1].id.i;
  433.     if (n < 0 || n >= menu->items) {
  434.         StackPushBoolean(FALSE);
  435.     } else if (args == 2) {
  436.         buf = StackAlloc( 1 );
  437.         buf->type = TYPE_FUNC ;
  438.         buf->funcd.ident = menu->query[n];
  439.     } else {
  440.         if (buf[2].type != TYPE_FUNC) {
  441.             ExecError( "引数の型が異なります(MenuFunction)" );
  442.         }
  443.         nmenu = (MenuClass*)ObjectAlloc( sizeof( MenuClass ), MenuClassID );
  444.         *nmenu = *menu;
  445.         nmenu->query[n] = buf[2].funcd.ident;
  446.         buf = StackAlloc( 1 );
  447.         buf->type = TYPE_OBJECT ;
  448.         buf->od.ptr = (Object*)nmenu ;
  449.  
  450.     }
  451.     return RETURN_RETURN;
  452. }
  453.  
  454. static    int        FuncMenuEnable( ident, args, buf )
  455. int        ident ;
  456. int        args ;
  457. DataStruct    *buf ;
  458. {
  459.     int n;
  460.     MenuClass *menu, *nmenu;
  461.     menu = (MenuClass*)(buf[0].od.ptr);
  462.     if (args < 2 || buf[1].type != TYPE_INT)
  463.         ExecError( "引数の型が異なります(MenuCheck)" );
  464.     n = buf[1].id.i;
  465.     if (n < 0 || n >= menu->items) {
  466.         StackPushBoolean(FALSE);
  467.     } else if (args == 2) {
  468.         buf = StackAlloc( 1 );
  469.         buf->type = TYPE_INT ;
  470.         buf->funcd.ident = menu->check[n];
  471.     } else {
  472.         if (buf[2].type != TYPE_INT) {
  473.             ExecError( "引数の型が異なります(MenuCheck)" );
  474.         }
  475.         nmenu = (MenuClass*)ObjectAlloc( sizeof( MenuClass ), MenuClassID );
  476.         *nmenu = *menu;
  477.         nmenu->check[n] = buf[2].id.i;
  478.         buf = StackAlloc( 1 );
  479.         buf->type = TYPE_OBJECT ;
  480.         buf->od.ptr = (Object*)nmenu ;
  481.     }
  482.     return RETURN_RETURN;
  483. }
  484.  
  485. static    int        FuncCurrentMenuItem( int ident, int args, DataStruct *buf )
  486. {
  487.     if (args == 0 && CurrentX >= 0 && CurrentY >= 0) {
  488.         StringClass *p = StringAlloc(strlen(Menu[CurrentX]->item[CurrentY]));
  489.         strcpy(p->str, Menu[CurrentX]->item[CurrentY]);
  490.         buf = StackAlloc( 1 );
  491.         buf->type = TYPE_OBJECT ;
  492.         buf->od.ptr = (Object*)p ;
  493.         return RETURN_RETURN;
  494.     } else {
  495.         ArgCheck( "MenuItem", args, buf, TYPE_OBJECT, TYPE_NOASN );
  496.  
  497.         CurrentMenuItem(((StringClass*)buf[0].od.ptr)->str);
  498.         return RETURN_VOID;
  499.     }
  500. }
  501.  
  502. static    int        FuncCurrentMenuFunction( int ident, int args, DataStruct *buf )
  503. {
  504.     if (args == 0 && CurrentX >= 0 && CurrentY >= 0) {
  505.         buf = StackAlloc( 1 );
  506.         buf->type = TYPE_FUNC ;
  507.         buf->funcd.ident = Menu[CurrentX]->exec[CurrentY];
  508.         return RETURN_RETURN;
  509.     } else {
  510.         ArgCheck( "MenuFunction", args, buf, TYPE_FUNC, TYPE_NOASN );
  511.  
  512.         CurrentMenuFunction(buf[0].funcd.ident);
  513.         return RETURN_VOID;
  514.     }
  515. }
  516.  
  517. static    int        FuncCurrentMenuEnable( int ident, int args, DataStruct *buf )
  518. {
  519.     if (args == 0 && CurrentX >= 0 && CurrentY >= 0) {
  520.         StackPushInt(Menu[CurrentX]->check[CurrentY]);
  521.         return RETURN_RETURN;
  522.     } else {
  523.         ArgCheck( "MenuEnable", args, buf, TYPE_INT, TYPE_NOASN );
  524.  
  525.         CurrentMenuEnable(buf[0].id.i);
  526.         return RETURN_VOID;
  527.     }
  528. }
  529.  
  530.