kolibrios-fun/programs/develop/libraries/box_lib/trunk/checkbox.asm
IgorA aba76d1871 fix mouse redraw in 'checkbox'
git-svn-id: svn://kolibrios.org@8568 a494cfbc-eb01-0410-851d-a64ba20cac60
2021-02-02 22:32:19 +00:00

151 lines
6.6 KiB
NASM
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;Последная модификация 02.02.2021
;файл создан 13.02.2009 <Lrz> На код применена GPL2 лицензия
;Checkbox
;Инициализация checkbox
align 16
init_checkbox:
;подсчитаем кол-во символов в длинне выводимой строки.
pushad
mov ebp,dword [esp+36] ;загружаем указатель на структуру, указатель мы передаем в стеке
mov ebx,dword ch_text_margin ;eax=0
mov esi,dword ch_text_ptr ;указатель на строчку
lodsb ;в al первый символ из строки
test al,al
jz .ex_loop
@@:
add ebx,6 ;ширина символа
lodsb
test al,al
jnz @b
.ex_loop:
mov dword ch_sz_str,ebx ;запишем длинну строки с учетом отступа от квадратика
or dword ch_text_color,0x80000000 ;добавляем бит для вывода ASCIIZ-строки
;на случай если пользователь забыл его самостоятельно поставить в структуре
popad
ret 4
align 16
check_box_draw:
pushad ;сохраним все регистры
mov ebp,dword [esp+36] ;загружаем указатель на структуру, указатель мы передаем в стеке
mcall SF_DRAW_RECT,ch_left_s,ch_top_s,ch_border_color ;рисуем рамку чек бокса, фактически рисуем прямоугольник и закрашиваем фон внутри цветом рамки бокса
mov edx,dword ch_color ;загружаем цвет фона
add ebx,1 shl 16 - 2
add ecx,1 shl 16 - 2
mcall ;закрашиваем внутренности чекбокса фоном
test dword ch_flags,2 ;достать значение бита из переменной и поместить в флаг CF
jz @f ;в если CF=1, то выполним следующую процедуру иначе перейти на нижнюю @@
call check_box_draw_ch ;нарисовать включенный чек бокс
@@:
;----------------------------
;расчет куда будет произведен вывод текста
;----------------------------
; mov ebx,dword ch_left_s ;загрузить значение (х shl 16 + длинна) для чек бокса
; add ebx,dword ch_text_margin ;добавим размер стороны и расстояние на котором начнется вывод текста
; shl ebx,16 ;сдвинем на 16 разрядов в лево (умножим на 65536)
; add ebx,dword ch_left_s ;cкорректируем позицию Х. Т.е. сейчас в верхней части ebx у нас точка начала вывода текста по Х
; mov eax,word ch_top_s ;загрузим значение по (y shl 16 + длинна) для чек бокса
; shr eax,16 ;сдвинем на 16 разрядов в лево (умножим на 65536)
; add eax,dword ch_top_s ;cкорректируем позицию Х. Т.е. сейчас в верхней части ebx у нас точка начала вывода текста по Y
; Оптимизация для ЦП
mov ebx,dword ch_left_s ;загрузить значение (х shl 16 + длинна) для чек бокса
mov eax,dword ch_top_s ;загрузим значение по (y shl 16 + длинна) для чек бокса
mov ecx,eax
add ebx,dword ch_text_margin ;добавим размер стороны и расстояние на котором начнется вывод текста
shr eax,16 ;сдвинем на 16 разрядов в право (разделим на 65536) в ax верхная точка
shl ebx,16 ;сдвинем на 16 разрядов в лево (умножим на 65536)
sub ecx,8 ;корретировка учитываем высоту шрифта
test dword ch_flags,ch_flag_bottom ;проверим, нужно ли выводить вверху надпись
jnz .bottom
test dword ch_flags,ch_flag_middle ;проверим, нужно ли выводить в центр надпись
jz .top ;остался только top
shr cx,1 ;разделим на 2
.bottom:
add ax,cx
.top:
add ebx,dword ch_left_s ;cкорректируем позицию Х. Т.е. сейчас в верхней части ebx у нас точка начала вывода текста по Х
mov bx,ax
;ebx х shl 16 +y координаты вывода строчки
mov ecx,dword ch_text_color ;загрузим цвет надписи + flags
mov edx,dword ch_text_ptr ;укажем адрес от куда нужно выводить строку
mcall SF_DRAW_TEXT
popad ;восстановить значения регистров из стека
ret 4 ;выйдем из процедуры и удалим из стека указатель на структуру (4 байта)
check_box_clear_ch: ;очистка чек бокса
mov edx,dword ch_color ;цвет внутри чек бокса
jmp @f ;безусловный прыжок на нижнюю метку @@
check_box_draw_ch: ;нарисовать включенный чек бокс
mov edx,dword ch_border_color ;загрузить цвет
@@:
;Отобразить включеный checkbox
mov ebx,dword ch_left_s ;загружаем х shl 16 + длинна по Х
mov ecx,dword ch_top_s ;загружаем Y shl 16 + длинна по Y
add ebx,2 shl 16 - 4 ;после этих изменений (X+2) shl 16 +длинна по (Х-2)
add ecx,2 shl 16 - 4 ;после этих изменений (Y+2) shl 16 +длинна по (Y-2)
mcall SF_DRAW_RECT ;отобразить квадрат внутри checkbox
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Обработчик mouse
;При попадании мышки + нажата клавиша в область checkbox состояние бокса должно менятся активный - не активный.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
align 16
check_box_mouse: ;обработка мыши
pushad
mov ebp,dword [esp+36] ;загружаем указатель на структуру, указатель мы передаем в стеке
mcall SF_MOUSE_GET,SSF_BUTTON_EXT ;проверяем состояние клавиш мышки. Было ли событие нажатая клавиша на мышке.
and eax, 3 shl 8 ;проверяем левую и правую кнопки
jz .end ;обработка закончилась
; Да событие: нажатие клавиши мышки произошло.
@@:
mcall SF_MOUSE_GET,SSF_WINDOW_POSITION ;получить координаты курсора относительно окна
;на выходе в eax x shl 16 + y
;сравнение верхней точки по Y
mov ecx,dword ch_top_s ;y shl 16 +длинна по y
mov ebx,ecx
shr ebx,16 ;bx = координата по y
cmp ax,bx
jb .end ;указатель мышки меньше начальной координаты по y чем координата по Y у бокса
;сравнение нижней точки по Y
add cx,bx ;сложим длинну по y и координату верхней точки по y поличим координату нижней точки по Y
cmp ax,cx
ja .end ;указатель мышки больше конечной координаты по y чем координата по Y у бокса
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
shr eax,16 ;сместим координату по Х в нижную часть регистра т.е. в ax
;сравнение по начальной точке Х
mov ecx,dword ch_left_s ;загрузить значение (х shl 16 + длинна) для чек бокса
mov ebx,ecx
shr ebx,16 ;bx = координата по X
cmp ax,bx
jb .end ;указатель мышки меньше начальной координаты по X чем координата по X у бокса
;сравнение конечной точки по X
add bx,cx ;сложим длинну по x и координату точки по х получим координату конечной точки по Х
add bx,word ch_sz_str ;добавим длинну строки текста с отступом предвартиельно записав их в момент инициализации
cmp ax,bx
ja .end ;указатель мышки больше конечной координаты по х чем координата по Х у бокса
;если все проверки были успешно пройдены мы обязаны поменять состояние бокса
btc dword ch_flags,1 ;перенос 2-го бита в cf и инверсия его
jnc .enable_box ;если CF=1 то отобразим включенный бокс и выйдем
push dword .end ;фокус-покус, вернемся после вызова check_box_clear_ch на метку check_box_mouse.end
jmp check_box_clear_ch ;выключить чек бокс т.е. на месте закрашенного прямоугольника отобразить цвет фона.
.enable_box:
call check_box_draw_ch ;отобразить включенный чек бокс
.end:
popad ;восстановить регистры из стека
ret 4 ;выйти и восстановим стек