;Последная модификация 03.10.2010
;файл создан 13.02.2009 <Lrz> На код применена GPL2 лицензия
;Макрос для системной библиотеки box_lib.obj
;Checkbox

;Инициализация checkbox
macro _init_checkbox2
{
init_checkbox2:
;подсчитаем кол-во символов в длинне выводимой строки.
	pushad
	mov	ebp,dword [esp+36]	;загружаем указатель на структуру, указатель мы передаем в стеке
	mov	ebx,dword 2ch_text_margin	;eax=0
	mov	esi,dword 2ch_text_ptr   ;указатель на строчку
	lodsb	                        ;в al первый символ из строки
	test	al,al
	jz	.ex_loop
@@:	
	add	ebx,6			;ширина символа
	lodsb
	test	al,al
	jnz	@b
.ex_loop:

	mov	dword 2ch_sz_str,ebx     ;запишем длинну строки с учетом отступа от квадратика
	or	dword 2ch_text_color,0x80000000 ;добавляем бит для вывода ASCIIZ-строки
		;на случай если пользователь забыл его самостоятельно поставить в структуре
	popad
	ret 4
}

macro use_checkbox_draw2
{
check_box_draw2:
	pushad   ;сохраним все регистры 
	mov	ebp,dword [esp+36]	;загружаем указатель на структуру, указатель мы передаем в стеке
	mcall	13,2ch_left_s,2ch_top_s,2ch_border_color		;рисуем рамку чек бокса, фактически рисуем прямоугольник и закрашиваем фон внутри цветом рамки бокса

	mov 	edx,dword 2ch_color	;загружаем цвет фона
	add 	ebx,1 shl 16 - 2 
	add 	ecx,1 shl 16 - 2 
	mcall 	;закрашиваем внутренности чекбокса фоном

	test dword 2ch_flags,2  ;достать значение бита из переменной и поместить в  флаг CF 
	jz   @f                ;в если CF=1, то выполним следующую процедуру иначе перейти на нижнюю @@
	call check_box_draw_ch2 ;нарисовать включенный чек бокс
@@:
;----------------------------
;расчет куда будет произведен вывод текста
;----------------------------
;        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 2ch_left_s		;загрузить значение (х shl 16 + длинна)  для чек бокса
	mov	eax,dword 2ch_top_s		;загрузим значение по (y shl 16 + длинна) для чек бокса 
	mov	ecx,eax
	add	ebx,dword 2ch_text_margin	;добавим размер стороны и расстояние на котором начнется вывод текста
	shr	eax,16				;сдвинем на 16 разрядов в право (разделим на 65536) в ax верхная точка
	shl	ebx,16				;сдвинем на 16 разрядов в лево (умножим на 65536)

	sub	ecx,8				;корретировка учитываем высоту шрифта

	test 	dword 2ch_flags,ch_flag_bottom	;проверим, нужно ли выводить вверху надпись
	jnz	.bottom

	test 	dword 2ch_flags,ch_flag_middle	;проверим, нужно ли выводить в центр надпись
	jz	.top				;остался только top
	
	shr	cx,1				;разделим на 2
.bottom:
	add	ax,cx
.top:
	add	ebx,dword 2ch_left_s             ;cкорректируем позицию Х. Т.е. сейчас в верхней части ebx у нас точка начала вывода текста по Х
	mov	bx,ax
						;ebx х shl 16 +y координаты вывода строчки

	mov	ecx,dword 2ch_text_color		;загрузим цвет надписи + flags
        mov	edx,dword 2ch_text_ptr		;укажем адрес от куда нужно выводить строку
        mcall	4				;Вывод 
	popad					;восстановить значения регистров из стека
	ret 4					;выйдем из процедуры и удалим из стека указатель на структуру (4 байта)

check_box_clear_ch2:				;очистка чек бокса
        mov	edx,dword 2ch_color   		;цвет внутри чек бокса
        jmp	@f				;безусловный прыжок на нижнюю метку @@
check_box_draw_ch2:				;нарисовать включенный чек бокс
        mov	edx,dword 2ch_border_color	;загрузить цвет
@@:
;Отобразить включеный checkbox
	mov	ebx,dword 2ch_left_s		;загружаем х shl 16 + длинна по Х
	mov	ecx,dword 2ch_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	13				;отобразить квадрат внутри checkbox
	ret
}


macro use_checkbox_mouse2
{

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Обработчик mouse
;При попадании мышки + нажата клавиша в область checkbox состояние бокса должно менятся активный - не активный.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
check_box_mouse2:      ;обработка мыши 
pushad
	mov	ebp,dword [esp+36]	;загружаем указатель на структуру, указатель мы передаем в стеке
        mcall	37,2			;проверяем состояние клавиш мышки. Было ли событие нажатая клавиша на мышке.
	test    eax,eax			;проверка если у нас в eax=0, выйдем
	jz	.check_box_mouse_end    ;обработка закончилась
; Да событие: нажатие клавиши мышки произошло.        
@@:
        mcall	37,1			;получить координаты курсора относительно окна
					;на выходе в eax x shl 16 + y
;сравнение верхней точки по Y
	mov	ecx,dword 2ch_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 у бокса
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	shr	eax,16			;сместим координату по Х в нижную часть регистра т.е. в ax
;сравнение по начальной точке Х
	mov 	ecx,dword 2ch_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			;сложим длинну по x и координату точки по х получим координату конечной точки по Х
	add	bx,word 2ch_sz_str	;добавим длинну строки текста с отступом предвартиельно записав их в момент инициализации
	cmp	ax,bx
	ja	.check_box_mouse_end	;указатель мышки больше конечной координаты по х чем координата по Х у бокса
;если все проверки были успешно пройдены мы обязаны поменять состояние бокса
	btc	dword	2ch_flags,1	;перенос 2-го бита в cf и инверсия его
	jnc	.enable_box		;если CF=1 то отобразим включенный бокс и выйдем
	push	dword .check_box_mouse_end	;фокус -покус, вернемся после вызова check_box_clear_ch на метку check_box_mouse_end
	jmp	check_box_clear_ch2     ;выключить чек бокс т.е. на месте закрашенного прямоугольника отобразить цвет фона.	

.enable_box:
	call	check_box_draw_ch2	;отобразить включенный чек бокс
.check_box_mouse_end:
popad					;восстановить регистры из стека
	ret  4				;выйти и восстановим стек
}