kolibrios/programs/develop/libraries/box_lib/branch/checkbox.mac
Alexey Teplov ( f999b6faa8 some optimisation
git-svn-id: svn://kolibrios.org@1652 a494cfbc-eb01-0410-851d-a64ba20cac60
2010-10-11 10:31:26 +00:00

200 lines
9.6 KiB
Plaintext
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.

;Последная модификация 03.10.2010
;файл создан 13.02.2009 <Lrz> На код применена GPL2 лицензия
;Макрос для системной библиотеки box_lib.obj
;Checkbox
macro use_checkbox_draw
{
check_box_draw:
pushad ;сохраним все регистры
mov ebp,dword [esp+36] ;загружаем указатель на структуру, указатель мы передаем в стеке
; mov ebx,ch_left_s
; mov ecx,ch_top_s
; mov edx,dword ch_border_color
; mov eax,13
; mcall ;рисуем рамку
mcall 13,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 + длинна) для чек бокса
; shl 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 + длинна) для чек бокса
add ebx,dword ch_text_margin ;добавим размер стороны и расстояние на котором начнется вывод текста
shl eax,16 ;сдвинем на 16 разрядов в лево (умножим на 65536)
shl ebx,16 ;сдвинем на 16 разрядов в лево (умножим на 65536)
add eax,dword ch_top_s ;cкорректируем позицию Х. Т.е. сейчас в верхней части ebx у нас точка начала вывода текста по Y
add ebx,dword ch_left_s ;cкорректируем позицию Х. Т.е. сейчас в верхней части ebx у нас точка начала вывода текста по Х
shr eax,16 ;для y поместим в младшую часть
mov bx,ax ;внесем смещение для y
mov ecx,dword ch_text_color ;загрузим цвет надписи + flags
mov edx,dword ch_text_ptr ;укажем адрес от куда нужно выводить строку
mov eax,4 ;внесем в eax значение вывода надписи на канву
mcall ;Вывод
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 ;загрузить цвет
@@:
; movzx ebx,word ch_left ;загрузить координату по х
; mov eax,dword ch_size
; mov di,ax
; shr eax,2
; push ax
;
; push ax
; add ebx,eax
; shl ebx,16 ;сдвинем на 16 разрядов в лево (умножим на 65536)
; pop ax
; lea eax,[eax*2]
; sub bp,ax ;сохраним регистр bx в регистре указателя базы
; mov bx,bp
; movzx ecx,word ch_top ;загрузить координату по у
; pop ax
; add cx,ax
; shl ecx,16 ;сдвинем на 16 разрядов в лево (умножим на 65536)
; mov cx,bp ;загрузим значения регистра указателя базы в cx
; mov eax,13 ;в eax - значения функции для вывода полосы т.е. по сути прямоугольника, который отображает включенный компонент чек бокс
; mcall ;вывод
mov ebx,dword ch_left_s
mov ecx,dword ch_top_s
add ebx,1 shl 16 - 4
add ecx,1 shl 16 - 4
mcall 13
ret
}
macro use_checkbox_mouse
{
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Обработчик mouse
; При попадании мышки + нажата клавиша в область checkbox состояние бокса должно менятся активный - не активный.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
check_box_mouse: ;обработка мыши
pushad
mov ebp,dword [esp+36] ;загружаем указатель на структуру, указатель мы передаем в стеке
mcall 37,2 ;проверяем состояние клавиш мышки. Было ли событие нажатая клавиша на мышке.
test eax,eax ;проверка если у нас в eax=0, то установим флаг и выйдем
jnz @f ;перейти на нижнюю метку @@, если в eax не 0.
; and dword ch_flags,eax ;извлечение значения заданного бита в флаг cf и изменение его значения на нулевое.
jmp .check_box_mouse_end ;обработка закончилась
; Да событие: нажатие клавиши мышки произошло.
@@:
mcall 37,1 ;получить координаты курсора относительно окна
;на выходе в 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 .check_box_mouse_end ;указатель мышки меньше начальной координаты по y чем координата по Y у бокса
;сравнение нижней точки по Y
add cx,bx ;сложим длинну по y и координату верхней точки по y поличим координату нижней точки по Y
cmp ax,cx
ja .check_box_mouse_end ;указатель мышки больше конечной координаты по y чем координата по Y у бокса
;сравнение по начальной точке Х
mov ecx,dword ch_left_s ;загрузить значение (х shl 16 + длинна) для чек бокса
mov ebx,ecx
shr ebx,16 ;bx = координата по X
cmp ax,bx
jb .check_box_mouse_end ;указатель мышки меньше начальной координаты по X чем координата по X у бокса
;сравнение конечной точки по X
add bx,cx ;сложим длинну по y и координату верхней точки по y поличим координату нижней точки по Y
add ebx,dword ch_text_margin ;добавим размер стороны и расстояние на котором начнется вывод текста
mov ecx,dword ch_text_ptr ;укажем адрес строки с терминируещим 0
push eax
;подсчет длинны строки и увеличение прямогольника в котором срабатывает щелчок мышки
lodsb
test al,al
jz .ex_loop
@@:
add bx,6 ;ширина символа
lodsb
test al,al
jnz @b
.ex_loop:
pop eax
cmp ax,bx
ja .check_box_mouse_end ;указатель мышки больше конечной координаты по y чем координата по Y у бокса
;если все проверки были успешно пройдены мы обязаны поменять состояние бокса
btc dword ch_flags,2 ;перенос 2-го бита в cf и инверсия его
jc .enable_box ;если CF=1 то отобразим включенный бокс и выйдем
push dword .check_box_mouse_end ;фокус -покус, вернемся после вызова check_box_clear_ch на метку check_box_mouse_end
jmp check_box_clear_ch ;выключить чек бокс т.е. на месте закрашенного прямоугольника отобразить цвет фона.
.enable_box:
call check_box_draw_ch ;отобразить включенный чек бокс
; bts dword ch_flags,2 ;проверка флага т.е. перенос в cf значение бита и установка бита в состояние включено
; jc check_box_mouse_end ;если CF=1 то перейти в конец т.е. это выход
; mov esi,dword ch_text_length ;загрузить кол-во символов в текстовой строке
;Умножение на 6 Быстрое умножение можно воспользоваться любым мз методов, но на старых Процессорах (386,486,P1)быстрее будет с инструкцией Lea
; lea esi,[eax*3]
; shl esi,1
; imul esi,6 ; или можно и так умножить на 6
; add esi,dword ch_text_margin ;добавить 3 - расстояние от чек бокса до надписи
; mov eax,37 ;получим координаты мышки
; mov ebx,1 ;добавить 1
; mcall ;получить координаты курсора относительно окна
; movzx ebx,word ch_top ;загрузить в bx значение координаты у
; cmp ax,bx ;сравнить с с координатой курсора
; jl check_box_mouse_end ;SF <> OF если меньше
; add ebx,dword ch_size ;добавить размер
; cmp ax,bx ;сравнить
; jg check_box_mouse_end ;ZF = 0 и SF = OF если больше
; shr eax,16 ;разделим на 65536 или просто сдвинем биты на 16 значений
; movzx ebx,word ch_left ;произведем аналогичное сравнение
; cmp ax,bx ;сравнить регистры
; jl check_box_mouse_end ;если меньше
; add ebx,dword ch_size ;добавить длину стороны прямоугольника
; add ebx,esi ;Учесть в значении по х еще и длину надписи к чекбоксу
; cmp ax,bx ;стравнить регистры
; jg check_box_mouse_end ;если больше
; bts dword ch_flags,1 ;извлечение значения заданного бита в флаг cf и изменение его значения на 1.
; jc @f ;CF=1 то перейти на нижнюю @@
; call check_box_draw_ch ;отобразить включенный чек бокс
; mov dword [esp+24],1 ;дальнейшая проверка чек боксов бесмыслена, по этому в стек, где располагается ecx поместитм 0
; jmp check_box_mouse_end ;выйти
;@@:
; btr word ch_flags,1 ;извлечение значения заданного бита в флаг cf и изменение его значения на нулевое.
; call check_box_clear_ch ;выключить чек бокс т.е. на месте закрашенного прямоугольника отобразить цвет фона.
.check_box_mouse_end:
popad ;восстановить регистры из стека
ret 4 ;выйти
}