#include <conio.h>
#include <dos.h>
#include <bios.h>
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#define GOR_MENU 3
#define VERT_MENU 5
#define INVERSE BLACK|GREEN<<4
#define NORMAL BLACK|LIGHTGRAY<<4
#define ARROW_DOWN 20480
#define ARROW_UP 18432
#define ARROW_RIGHT 19712
#define ARROW_LEFT 19200
#define ARROW_ENTER 7181
#define ARROW_ESC 283
#define ARROW_DEL 21248
#define ARROW_AltX 11520
#define ARROW_F10 17408
#define ARROW_F2 15360
#define ARROW_F3 15616
#define ARROW_F4 15872
#define TAB -8
#define DEL -3
#define ESC -2
#define F2 -4
#define F3 -5
#define F4 -6
#define F10 -7
#define AltX -10
char *text_menu1[GOR_MENU] = {
" Меню \0",
"Сортировка\0",
"Помощь\0"
};
char text_menu[GOR_MENU] [VERT_MENU][15]={
{
"Создать \0",
"Открыть F3\0",
"Сохранить F2\0",
"Сохр. как \0",
"Выход AltX\0",
},
{
"По алфавиту \0",
"По цене \0",
},
{
"Справка \0",
"О программе \0",NULL
}
};
struct menu {
int count;
int active_col;
} main_menu;
struct popup {
int count;
int border;
int x, y;
int number;
int active_row;
} vert_menu[GOR_MENU];
void draw_doubleborder(int startx,int starty,int endx,int endy);
void draw_border(int startx,int starty,int endx,int endy);
void print_statusbar(void);
void display_vmenu(popup v_menu);
void display_gmenu(void);
void display_row(popup v_menu, int mode);
int get_resp();
int get_popup(int num);
void init_popup(popup &v_menu,int cnt, int b, int x, int y, int num);
void goto_xy(int x,int y);
void display_col(int mode);
int get_resp()
{
int choice_popup= ESC, key;
display_col(INVERSE);
while( choice_popup == ESC) {//(key != ARROW_ENTER) || (key != ARROW_DOWN)) {
while( !(key = bioskey(0)) );
switch(key) {
case ARROW_RIGHT:
display_col(NORMAL);
if(main_menu.active_col == GOR_MENU-1) main_menu.active_col = 0;
else main_menu.active_col++;
display_col(INVERSE);
break;
case ARROW_LEFT:
display_col(NORMAL);
if(main_menu.active_col == 0) main_menu.active_col = GOR_MENU-1;
else main_menu.active_col—;
display_col(INVERSE);
break;
case ARROW_ENTER:
case ARROW_DOWN:
choice_popup = get_popup(main_menu.active_col);
break;
case ARROW_ESC:
display_col(NORMAL);
return -2;
}
}
display_col(NORMAL);
return main_menu.active_col*10 + choice_popup;
}
int get_popup(int number)
{
int arrow_choice, key;
void *buf;
buf = malloc(12*vert_menu[number].count*2);
gettext(vert_menu[number].x-1, vert_menu[number].y-1, vert_menu[number].x +12,
vert_menu[number].y + vert_menu[number].count, buf);
display_vmenu(vert_menu[number]);
display_row(vert_menu[number], INVERSE);
while(key != ARROW_ENTER) {
while( !(key = bioskey(0)) );
switch(key) {
case ARROW_DOWN:
display_row(vert_menu[number], NORMAL);
if(vert_menu[number].active_row == vert_menu[number].count-1)
vert_menu[number].active_row = 0;
else
vert_menu[number].active_row++;
display_row(vert_menu[number], INVERSE);
break;
case ARROW_UP:
display_row(vert_menu[number], NORMAL);
if(vert_menu[number].active_row == 0)
vert_menu[number].active_row = vert_menu[number].count-1;
else
vert_menu[number].active_row—;
display_row(vert_menu[number], INVERSE);
break;
case ARROW_ENTER:
break;
case ARROW_ESC:
puttext(vert_menu[number].x-1, vert_menu[number].y-1, vert_menu[number].x +12,
vert_menu[number].y + vert_menu[number].count, buf);
free(buf);
return -2;
}
}
puttext(vert_menu[number].x-1, vert_menu[number].y-1, vert_menu[number].x +12,
vert_menu[number].y + vert_menu[number].count, buf);
free(buf);
return vert_menu[number].active_row;
}
void display_gmenu(void)
{
int i, x = 0;
textattr(BLACK|LIGHTGRAY<<4);
goto_xy(0, 0);
for(i=0;i<80;i++)
cprintf(" ");
for(i=0; i<main_menu.count; i++) {
x += 3;
goto_xy(x, 0);
cprintf(text_menu1[i]);
x += strlen(text_menu1[i]);
}
}
//
void display_col(int mode)
{
int i, x = 3;
textattr(mode);
for(i=0; i<main_menu.active_col; i++) {
x += 3;
x += strlen(text_menu1[i]);
}
goto_xy(x, 0);
cprintf(text_menu1[i]);
}
//Вывод строки вертикального меню——————————————
void display_row(popup v_menu, int mode)
{
textattr(mode);
gotoxy(v_menu.x, v_menu.y+v_menu.active_row);
cprintf(text_menu[v_menu.number][v_menu.active_row]);
}
//Отображает вертикальное меню———————————————
void display_vmenu(popup v_menu)
{
register int i;
int y = v_menu.y;
textattr(BLACK|LIGHTGRAY<<4);
for(i=0; i<v_menu.count; i++,y++) {
gotoxy(v_menu.x, y);
// cprintf("%d %d",v_menu.number,i);
cprintf(text_menu[v_menu.number][i]);
}
draw_border(v_menu.x-1, v_menu.y-1,v_menu.x+12, v_menu.y+v_menu.count);
}
//Выводит строку состояния и двойную рамку главного окна——————-
void print_statusbar(void)
{
draw_doubleborder(1,2,80,24);
goto_xy(27, 1);
cprintf(" Рейтинг студентов ИТФ ");
textattr(RED|LIGHTGRAY<<4);
goto_xy(1, 24);
cprintf(" Клавиши курсора Enter F4 Del ");
textattr(BLACK|LIGHTGRAY<<4);
goto_xy(18, 24);
cprintf("перемещение");
goto_xy(38, 24);
cprintf("изменить");
goto_xy(53, 24);
cprintf("добавить");
goto_xy(69, 24);
cprintf("удалить");
}
//Рисует одинарную рамку по указанным координатам—————————
void draw_border(int startx,int starty,int endx,int endy)
{
register int i;
textattr(BLACK|LIGHTGRAY<<4);
for(i=startx+1;i<endx;i++) {
gotoxy(i,starty);
cprintf("-");
gotoxy(i,endy);
cprintf("-");
}
for(i=starty+1;i<endy;i++) {
gotoxy(startx,i);
cprintf("¦");
gotoxy(endx,i);
cprintf("¦");
}
gotoxy(startx,starty); cprintf("-"); // ‘-‘ == 218
gotoxy(startx,endy ); cprintf("L"); // ‘¬’ == 191
gotoxy(endx ,starty); cprintf("¬"); // ‘L’ == 192
gotoxy(endx ,endy ); cprintf("-"); // ‘-‘ == 217
}
//Рисует двойную рамку по указанным координатам——————————
void draw_doubleborder(int startx,int starty,int endx,int endy)
{
register int i;
textattr(WHITE|CYAN<<4);
for(i=startx+1;i<endx;i++) {
gotoxy(i,starty);
cprintf("=");
gotoxy(i,endy);
cprintf("=");
}
for(i=starty+1;i<endy;i++) {
gotoxy(startx,i);
cprintf("¦");
gotoxy(endx,i);
cprintf("¦");
}
gotoxy(startx,starty); cprintf("г"); // ‘-‘ == 218
gotoxy(startx,endy ); cprintf("L"); // ‘¬’ == 187
gotoxy(endx ,starty); cprintf("¬"); // ‘L’ == 192
gotoxy(endx ,endy ); cprintf("-"); // ‘-‘ == 188
}
//Функция инициализирует вертикальные меню———————————-
void init_popup(popup &v_menu,int c, int b, int x, int y, int num)
{
int i;
v_menu.count = c;
v_menu.border = b;
v_menu.x = x;
v_menu.y = y;
v_menu.number = num;
v_menu.active_row = 0;
}
//Функция устанавливает позицию курсора в указанное место——————-
void goto_xy(int x,int y)
{
union REGS r;
r.h.ah=2; /* функция установки курсора */
r.h.dl=x; /* координата колонки */
r.h.dh=y; /* координата строки */
r.h.bh=0; /* видео страница */
int86(0x10,&r,&r);
}
