/*******************************************************************/ // "Меркурий"-"Правда" - open source переводчик // распространяется в соответсвии с лицензией GNU v 2.0 // // менюшка // Анисимов Д.В. сегодня /*******************************************************************/ # include <stdio.h> # include <malloc.h> # include <string.h> # include "mylib.h" # include "video.h" # include "color.h" # include "menu.h1" # define stop() { short key1,key2 ; s_getch(&key1,&key2); } /* ----------------------------------------------------------------------- */ struct t_menuForm { short size_x,size_y, n_punkt, *igrek ; t_Menu *menu ; } ; static char *stek ; static short SP ; static short *mass_iks, *mass_igrek, Ret ; static char Exist=0 ; /* ----------------------------------------------------------------------- */ void init_menu( void ) ; short hor_menu( short y, t_Menu *menu ) ; void s_hor_menu( short y, short *x, t_Menu *menu, short pos=-1 ) ; void s_ver_menu( short y, short x, t_menuForm F, short pos=-1 ) ; short ver_menu( short y, short x, t_Menu *menu ) ; void ver_menu_creat( t_menuForm *f, t_Menu *menu ) ; short sehen_hor_menu( short **x, t_Menu *menu ) ; static short schnell_taste( t_Menu *menu, uchar taste ) ; void sorry( short y, short x ); /* *********************************************************************** */ short menu( void ) { Ret=0 ; if( Exist==0 ) init_menu( ); hor_menu( 0, wort_menu ) ; null_menu( ); SP=0 ; return Ret ; } /* ----------------------------------------------------------------------- */ void init_menu( void ) { stek = (char *)Calloc( 4000,1 ) ; mass_iks = (short *)Calloc( 25,sizeof(short) ) ; mass_igrek = (short *)Calloc( 25,sizeof(short) ) ; SP=0 ; Exist=1 ; } /* ----------------------------------------------------------------------- */ void null_menu( void ) { short *x ; if( Exist==0 ) init_menu( ); sehen_hor_menu( &x,wort_menu ) ; s_hor_menu( 0,x,wort_menu ) ; } /* ----------------------------------------------------------------------- */ /* реакция на кнопки внутри горизонтального меню */ /* ----------------------------------------------------------------------- */ short hor_menu( short y, t_Menu *menu ) { short p=0, // текущий пункт меню flag=0 ; static short key1,key2,key3 ; short size_Menu ; short *x ; size_Menu=sehen_hor_menu( &x,menu ) ; while( 1 ) { s_hor_menu( y,x,menu,p ) ; s_getch( &key1,&key2) ; switch( key2 ) { case S_key_Left: M_LINKS : if( p<=0 ) p=size_Menu-1 ; else p-- ; if( flag==1 && menu[p].flag==F_MENU ) { s_hor_menu( y,x,menu,p ); key3=ver_menu( 1,x[p], (t_Menu *)menu[p].data ) ; } else { key3=0 ; } break ; case S_key_Right: M_RECHTS : if( p>=size_Menu-1 ) p=0 ; else p++ ; if( flag==1 && menu[p].flag==F_MENU ) { s_hor_menu( y,x,menu,p ); key3=ver_menu( 1,x[p], (t_Menu *)menu[p].data ) ; } else { key3=0 ; } break ; case S_key_Down: goto M_ENTER ; case S_key_F10 : return S_key_Esc ; case 0 : switch( key1 ) { schnell : s_hor_menu( y,x,menu,p ); case '\r' : M_ENTER : if( menu[p].flag==4 ) { Ret=((char *)menu[p].data)[0] ; return S_key_Esc ; } if( menu[p].flag==3 ) { menu[p].funk( menu[p].data ) ; return S_key_Esc ; } if( menu[p].flag==2 ) { flag=1 ; key3=ver_menu( 1,x[p], (t_Menu *)menu[p].data ) ; } break ; case S_key_Esc : return S_key_Esc ; default : { short p1 ; p1=schnell_taste( menu,key1 ) ; if( 0<=p1 ) { p=p1 ; goto schnell ; } } break ; } } switch( key3 ) { case S_key_Left : goto M_LINKS ; case S_key_Right: goto M_RECHTS ; case S_key_Esc : return S_key_Esc ; } } } /* ----------------------------------------------------------------------- */ /* реакция на кнопки внутри вертикального меню */ /* ----------------------------------------------------------------------- */ short ver_menu( short y, short x, t_Menu *menu ) { short p=0,ret ; static short key1,key2 ; t_menuForm f ; short i ; ver_menu_creat( &f,menu ) ; s_save( y,x,y+f.size_y+1,x+f.size_x+1 ); while( 1 ) { s_ver_menu( y,x,f,p ) ; s_getch( &key1,&key2 ) ; switch( key2 ) { case S_key_Up: if( p<=0 ) p=f.n_punkt-1 ; else p-- ; break ; case S_key_Down: if( p>=f.n_punkt-1 ) p=0 ; else p++ ; break ; case S_key_Left : ret = S_key_Left ; goto ENDE ; case S_key_Right: ret = S_key_Right ; goto ENDE ; case S_key_F10 : ret = S_key_Esc ; goto ENDE ; case 0 : switch( key1 ) { case '\r' : schnell : i=f.igrek[p] ; if( menu[i].flag==4 ) { Ret=((char *)menu[p].data)[0] ; ret = S_key_Esc ; goto ENDE ; } if( menu[i].flag==3 ) { s_restore( ) ; menu[i].funk( menu[i].data ) ; ret = S_key_Esc ; goto ENDE1 ; } if( menu[i].flag==2 ) { ver_menu( y+i+1,x+f.size_x, (t_Menu *)menu[p].data ) ; break ; } default : { short p1 ; p1=schnell_taste( menu,key1 ) ; if( 0<=p1 ) { p=p1 ; goto schnell ; } } break ; } case S_key_Esc : ret = S_key_Esc ; goto ENDE ; } } ENDE : s_restore( ) ; ENDE1 : return ret ; } /* ----------------------------------------------------------------------- */ short schnell_taste( t_Menu *menu, uchar taste ) { short i,j ; uchar c ; for( i=0 ; menu[i].flag!=0 ; i++ ) { for( j=0 ; ; j++ ) { c=menu[i].name[j] ; if( c==0 ) break ; if( (uchar)'А'<=c && c<=(uchar)'Я' ) { if( c==taste ) return i ; //if( XLAT[c]==XLAT[taste] ) return i ; break ; } } } return -1 ; } /* ----------------------------------------------------------------------- */ short sehen_hor_menu( short **iks, t_Menu *menu ) { short i,j, *a ; *iks=a = mass_iks ; for( j=2,i=0 ; ; i++ ) { if( menu[i].flag==0 ) break ; a[i]=j ; j+=strlen( menu[i].name )+2 ; } return i ; } /* ----------------------------------------------------------------------- */ /* изобразить горизонтальное меню */ /* ----------------------------------------------------------------------- */ void s_hor_menu( short y, short *x, t_Menu *menu, short pos ) { short i ; s_text_yxf( y,0,h_menu_Color,emptystr(80) ) ; for( i=0 ; i<25 ; i++ ) { if( menu[i].flag==0 ) break ; s_text_yxf( y,x[i],h_menu_Color,menu[i].name ) ; } // ------- изобразить текущую позицию горизонтального меню ------- if( 0<=pos ) s_text_yxf( y,x[pos],h_curs_Color,menu[pos].name ) ; } /* ----------------------------------------------------------------------- */ /* изобразить вертикальное меню */ /* ----------------------------------------------------------------------- */ void s_ver_menu( short y, short x, t_menuForm F, short pos ) { short i,c ; s_rame1_F( y,x,y+F.size_y+1,x+F.size_x+1,v_menu_Color ) ; for( i=0 ; i<F.size_y ; i++ ) { if( i==mass_igrek[pos] ) { s_text_yxf( y+1+i,x+1,v_curs_Color,emptystr(F.size_x) ) ; c=v_curs_Color ; } else c=v_menu_Color ; s_text_yxf( y+1+i,x+1,c,F.menu[i].name ) ; } } /* ----------------------------------------------------------------------- */ /* конструктор формы меню */ /* ----------------------------------------------------------------------- */ void ver_menu_creat( t_menuForm *f, t_Menu *menu ) { short i,j,s,*igrek ; for( i=0 ; i<25 ; i++ ) if( menu[i].flag==0 ) break ; f->size_y=i ; igrek = mass_igrek ; for( s=j=0,i=0 ; i<f->size_y ; i++ ) { if( menu[i].flag==0 ) break ; s=max( (unsigned)s, strlen( menu[i].name ) ); if( menu[i].flag==2 || menu[i].flag==3 || menu[i].flag==4 ) igrek[j++]=i ; } f->size_x=s ; f->n_punkt=j ; f->igrek=igrek ; f->menu=menu ; } /* ----------------------------------------------------------------------- */ // переобозвать пункт меню (поставить в него галку) /* ----------------------------------------------------------------------- */ char menu_set( t_Menu *Menu, char *sFind, char *sReplace ) { short i ; for( i=0 ; i<100 ; i++ ) { if( Menu[i].flag==F_ENDE ) break ; if( 0==strcmp(Menu[i].name,sFind) ) { strcpy( Menu[i].name,sReplace ); return 1 ; } if( Menu[i].flag==F_MENU ) if( 1==menu_set( (t_Menu *)Menu[i].data,sFind, sReplace ) ) return 1; } return 0 ; } /* ----------------------------------------------------------------------- */ void menu_set( char *sFind, char *sReplace ) { menu_set( wort_menu, sFind, sReplace ); } /* ----------------------------------------------------------------------- */ // найти пункт меню по его имени /* ----------------------------------------------------------------------- */ t_Menu * menu_find( t_Menu *Menu, char *sFind ) { short i ; for( i=0 ; i<100 ; i++ ) { if( Menu[i].flag==F_ENDE ) break ; if( 0==strcmp(Menu[i].name,sFind) ) return &Menu[i] ; if( Menu[i].flag==F_MENU ) return menu_find( (t_Menu *)Menu[i].data,sFind ); } return NULL ; } /* ----------------------------------------------------------------------- */ t_Menu * menu_find( char *sFind ) { return menu_find( wort_menu, sFind ); } /* ----------------------------------------------------------------------- */ void Sorry( void *d ){ sorry( 10,30 ) ; } /* ----------------------------------------------------------------------- */ void sorry( short y, short x ) { s_save( y,x,y+4,x+20 ) ; s_rame1_f( y,x,y+4,x+20,0x70 ) ; s_text_yxf( y+1,x+1,0x70," Извините ") ; s_text_yxf( y+2,x+1,0x70," эта функция еще ") ; s_text_yxf( y+3,x+1,0x70," не реализована ") ; stop( ) ; s_restore( ) ; }