forked from KolibriOS/kolibrios
f999b6faa8
git-svn-id: svn://kolibrios.org@1652 a494cfbc-eb01-0410-851d-a64ba20cac60
200 lines
9.6 KiB
Plaintext
200 lines
9.6 KiB
Plaintext
;Последная модификация 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 ;выйти
|
||
} |