; #C000+#2800=#E800 ; Буферы User-данных array_user1 equ 0E800h ; 26*2 массив указ. на ком-строки array_user2 equ array_user1+(26*2) ; 72*56 описатель пунктов меню ; + 1 байт под конец описателя array_user3 equ array_user2+(72*26)+1 ; 71*26 массив ком-строк ; остаток банки после всего массива #0944 байт. ;----------------------------------------------------------- ; Вызов Меню Пользователя ;----------------------------------------------------------- user_menu: ld a,(enable_mnu_file) ; флаг наличия mnu-файла or a ret z ; нет ld hl,user_table ; описатель меню (mod1) call put_user_menu ; отрисовка меню call get_fire ; защита от "залипания" бутонов call event_user_menu ; обработчик событий меню ; ld hl,what ld a,(hl) cp evCommand ret nz ld (hl),evRunComLine ; событие "отработать ком-строку" jp get_fire ;----------------------------------------------------------- ; Прорисовка меню пользователя. ; Положение меню определяется шириной и числом пунктов. ; Таблица меню: ; Положение окна меню: ; +0 - Xo левый край ; +1 - Xi правый край ; +2 - Yo левый угол ; +3 - Yi правый угол ; +4 - Положение пункта меню: ; +0 - Xo левое ; +1 - Xi правое ; +2 - Y полож. ; +3 - hot-буква ;----------------------------------------------------------- ; вход: hl=описатель меню ;----------------------------------------------------------- put_user_menu: ld a,1 ld (CurMBox),a ; номер пункта меню push iy ld iy,BoxTabl ; Generes MenuBox mouse table ld ix,BoxData ld a,(page_sys_screen) ; стр. user-данных out (SLOT3),a ld e,(hl) inc hl ld d,(hl) inc hl ld (usermenu_title+1),de ; адрес заголовка окна ld a,(hl) ; адрес описателя тек. меню ld (ix+0),a ; сохр. адрес описателя inc hl ld h,(hl) ld (ix+1),h ; ld l,a call GetLenB1 ; get in DE len Y,X MenuBox ; X центровка меню ld a,80 ; ширина окна sub e srl a ; /2 ld (iy+0),a ; Xo полож. окна меню ld b,a inc a ld (ix+2),a ; Xo полож. пункта меню ld a,e ; ширина окна (без тени) sub 2 ld (ix+5),a ; ширина окна без рамки ld a,e add a,b ; + Xo полож. окна меню ld (iy+1),a ; X правый край окна меню dec a ld (ix+3),a ; Xi правый край пункта меню ; Y центровка меню ld a,30 ; высота окна sub d srl a ; /2 ld (iy+2),a ; Yo полож. окна меню ld (ix+4),a ; Temp Y posit for element box ld b,a ld a,d ; высота окна (без тени) add a,b ; Yi (+ Y полож. окна меню) ld (iy+3),a call SaveBox ; сохр. экран под будущим окном in a,(SLOT3) push af ld a,(page_dial_screen) ; Page buffer out (SLOT3),a ; начало вставки окна с тенью в буфер ld hl,LC000+MaxDialWin ld bc,4 add iy,bc ; адрес описателя меню exx ld hl,LC000 ld a,(ix+5) ; ширина окна inc a inc a add a,a ld e,a ld d,0 add hl,de exx ld a,(color_array+15) ; цвет верт. меню ld c,a ; центровка заголовка push hl ld de,(usermenu_title+1) ; адрес заголовка окна ld a,(de) ; длина заголовка ld b,a ld a,(ix+5) ; ширина окна sub b srl a ; /2 add a,a ; учесть атрибуты (результат всегда четный) ld e,a ld d,0 add hl,de ld (usermenu_addr+1),hl ; адрес вставки pop hl ; рамка окна ld (hl),"╔" ; левый верх. угол inc hl ld (hl),c ; цвет inc hl ld b,(ix+5) ; ширина окна ld a,"═" ld (hl),a inc hl ld (hl),c inc hl djnz $-4 ld (hl),"╗" ; правый верх. угол inc hl ld (hl),c inc hl ; push hl usermenu_title: ld de,0 ; адрес титла окна usermenu_addr: ld hl,0 ; адрес вставки ld a,(de) ld b,a ; длина строки inc de ld (hl)," " inc hl inc hl ld a,(de) ld (hl),a inc hl inc hl ; атрибут inc de djnz $-5 ld (hl)," " pop hl ; ld b,3 call copy_cell exx ld a,(hl) inc hl add hl,de exx ld (hl),a inc hl ld e,(ix+0) ;; de=адрес списка пунктов ld d,(ix+1) ; цикл вывода пунктов меню usermenu_loop: inc (ix+4) ; увеличить Y-полож. пункта меню call get_user_byte ; взять байт из стр. user-данных cp -2 ; разделитель jr nz,usermenu1__ ; вставить разделитель пунктов inc de ld (hl),"╟" inc hl ld (hl),c inc hl ld b,(ix+5) ; ширина пункта ld a,"─" ld (hl),a inc hl ld (hl),c inc hl djnz $-4 ld (hl),"╢" jr usermenu3__ usermenu1__: cp -1 ; конец описателя ? jp z,usermenu4__ ; да ld a,(ix+2) ld (iy+0),a ;+0 Xo coord inc iy ld a,(ix+3) ld (iy+0),a ;+1 Xi coords inc iy ld a,(ix+4) ld (iy+0),a ;+2 Y coords inc iy ld (hl),"║" inc hl ld (hl),c inc hl ld b,2 ; 2 пробела в начале пункта ld (hl)," " inc hl ld (hl),c inc hl djnz $-5 inc b ; b=1 call get_user_byte ; взять байт из стр. user-данных usermenu2__: inc de cp "&" call z,Bhotkey2__ ; вставить hot-букву ld (hl),a ; Put name element inc hl ld (hl),c inc hl inc b call get_user_byte ; взять байт из стр. user-данных or a ; конец имени ? jr nz,usermenu2__ inc de ; de=ячейка скен-кода пункта call get_user_byte ; взять байт из стр. user-данных ld (iy+0),a ;+3 скен-код hot-клавиши inc iy inc de ld a,(ix+5) ; ширина тек. пункта dec a sub b ld b,a ld (hl)," " ; заполнить остаток пункта inc hl ld (hl),c inc hl djnz $-5 ld (hl),"║" usermenu3__: inc hl ld (hl),c inc hl exx ld a,(hl) inc hl inc hl exx ld (hl),a inc hl ld (hl),color_shadow ; цвет тени inc hl exx ld a,(hl) inc hl inc hl add hl,de exx ld (hl),a inc hl ld (hl),color_shadow ; цвет тени inc hl jp usermenu_loop ; назад в цикл ; usermenu4__: ld (iy+0),80h ; конец таблицы пунктов ld (hl),"╚" inc hl ld (hl),c inc hl ld b,(ix+5) ld a,"═" ld (hl),a inc hl ld (hl),c inc hl djnz $-4 ld (hl),"╝" inc hl ld (hl),c inc hl ; вставить 2 тени угла "┘" ld b,2 call print_shadow ; вставить нижнюю тень ld b,4 call copy_cell ; скопир. ячейки ld b,(ix+5) ; Full Len box inc b inc b call print_shadow pop af out (SLOT3),a call PutBox pop iy jp USetBoxI ; Set box invert ;------------------------------------------------- ; Установить цвет hot-буквы пункта user-меню ;------------------------------------------------- Bhotkey2__: call get_user_byte ; взять байт из стр. user-данных ld (hl),a ; hot-букву в буфер inc hl inc de push de ld a,(color_array+17) ; цвет hot-буквы меню and 0Fh ld e,a ld a,(color_array+15) ; цвет верт. меню and 0F0h or e ld (hl),a ; атрибут pop de inc hl call get_user_byte ; взять байт из стр. user-данных inc de inc b ret ;----------------------------------------------------------- ; Вычислить ширину текущего окна верт. меню ; ; вход: hl=описатель меню ; выход: de=высота/ширина окна ;---------------------------------------------------------- GetLenB1: ld de,0207h ; Y/X размеры ld b,e dec b GetL1: ld a,(hl) inc hl cp -1 ; конец описателя ? ret z cp -2 ; разделитель пунктов ? jr z,AddLn GetL2: inc b GetL3: ld a,(hl) inc hl cp "&" ; hot-буква jr z,GetL3 or a ; конец названия пункта ? jr nz,GetL2 ; нет inc hl ; пройти скен-код ld a,b cp e jr c,AddLn ld e,b AddLn: inc d ld b,6 ; b=e-1 jr GetL1 ; Взять байт из страницы user-данных ; вход: de=адрес данных get_user_byte: in a,(SLOT3) push af ld a,(page_sys_screen) ; стр. user-данных out (SLOT3),a ld a,(de) ex af,af' pop af out (SLOT3),a ; восст. стр. ex af,af' ret ;----------------------------------------------------------- ; ; Обработчик событий Меню Пользователя ; ;----------------------------------------------------------- event_user_menu: call handle_event ; читаем событие ld hl,what ld de,event_user_menu push de ld a,(hl) ;+0 узнать событие inc hl cp evMouseFr ; нажаты бутоны мышки jp z,user_menu_mouse cp evKeyboard ; нажаты обычные клавиши jr z,user_menu_keys cp evCombKey ; нажаты курс. клавиши и служ. jr z,user_menu_ckeys ret ; user_menu_exit: call CloseBx ; закрыть меню pop de ; восст. баланс стека ld hl,what ld (hl),evNothing ; "нет событий" ret ;------------------------------------------------- ; Обычные клавиши ;------------------------------------------------- user_menu_keys: ld a,(hl) ;+1 код клавиши cp 1Bh ; Esc jr z,user_menu_exit cp 0Dh ; Enter jr nz,user_menu_keys1 ld a,(CurMBox) ld b,a ld ix,BoxTabl ; поиск пункта меню ld de,4 add ix,de djnz $-2 jp UBxEnt ; user_menu_keys1: inc hl ld a,(hl) ;+2 скен-код клавиши ld ix,BoxTabl ; рабочая таблица меню ld bc,4 ld h,b user_menu_keys2: inc h add ix,bc bit 7,(ix+0) ret nz ; конец таблицы пунктов cp (ix+3) ; скен-код hot-клавиши jr nz,user_menu_keys2 jp UBxHotEx ;------------------------------------------------- ; Курсорные клавиши и F10 ;------------------------------------------------- user_menu_ckeys: inc hl ld a,(hl) ;+2 what cp 44h ; F10 jr z,user_menu_exit cp 58h ; вверх jr z,UMBup cp 52h ; вниз jr z,UMBdown cp 54h ; влево jr z,UMBhome cp 56h ; вправо jr z,UMBend cp 59h ; PageUp jr z,UMBhome cp 53h ; PageDown jr z,UMBend cp 57h ; Home jr z,UMBhome cp 51h ; End jr z,UMBend ret ; Курсор вверх UMBup: ld a,(CurMBox) dec a jr nz,UMBupNxt ld ix,BoxTabl ; рабочая таблица меню ld bc,4 ld a,b dec a UMBupLp:inc a ; поиск последнего элемента add ix,bc bit 7,(ix+0) jr z,UMBupLp UMBupNxt: ld (CurMBox),a ld b,a ld ix,BoxTabl ; рабочая таблица меню ld de,4 add ix,de djnz $-2 push ix call ResBoxI call USetBoxI pop ix ret ; Курсор вниз UMBdown:ld a,(CurMBox) inc a ld ix,BoxTabl ; рабочая таблица меню ld bc,4 ld h,b ; тест на последний элемент UMBdnLp:inc h add ix,bc bit 7,(ix+0) jr z,UMBdnLp cp h jr nz,$+4 ; Home в начало списка UMBhome:ld a,1 jr UMBupNxt ; End в конец списка UMBend: ld a,(CurMBox) ld h,a ld ix,BoxTabl ; рабочая таблица меню ld bc,4 ld a,b dec a UMBendLp: inc a ; поиск последнего элемента add ix,bc bit 7,(ix+0) jr z,UMBendLp cp h jr nz,UMBupNxt ret ;------------------------------------------------- ; События мышки ;------------------------------------------------- user_menu_mouse: ld e,(hl) ;+1 X coord inc hl ld d,(hl) ;+2 Y coord ; проверка на коорд. мышки и окна ld ix,BoxTabl ; рабочая таблица ld a,e cp (ix+0) jp c,user_menu_exit ; < Xo cp (ix+1) jp nc,user_menu_exit ; > Xi ld a,d cp (ix+2) jp c,user_menu_exit ; < Yo cp (ix+3) jp nc,user_menu_exit ; > Yi ld bc,4 ld h,b usermenu_mouse_loop: inc h add ix,bc bit 7,(ix+0) ; конец описателя меню ? ret nz ; да ld a,d cp (ix+2) jr nz,usermenu_mouse_loop ld a,e ; поиск пункта меню cp (ix+0) jr c,usermenu_mouse_loop ; < Xo cp (ix+1) jr nc,usermenu_mouse_loop ; > Xi UBxHotEx: ld a,(CurMBox) cp h jr z,UBxEnt ; уст. пункт меню ld a,h ld (CurMBox),a push af call ResBoxI call USetBoxI pop af halt halt halt halt ; выполн. пункта по или мышке UBxEnt: dec a ld hl,what ld (hl),evCommand ; уст. событие "команда" ; скопир. ком-строку в буфер add a,a ld e,a ld d,0 ld a,(page_sys_screen);; ; стр. user-данных out (SLOT3),a;; ld hl,array_user1 ; таблица указателей на ком-строки add hl,de ld e,(hl) inc hl ld d,(hl) ex de,hl ; hl=откуда ld de,work_buffer+127;255 ; куда call copy_string ; скопир. строку (с нулем) ; закрыть меню call CloseBx pop de ret ; выйти из меню ;------------------------------------------------- ; Инвертирование пункта меню ;------------------------------------------------- USetBoxI: ld c,0 ld a,(CurMBox) dec a add a,a ;1+1=2 jp SetBoxI1