Subversion Repositories Kolibri OS

Rev

Rev 144 | Rev 366 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
144 Lrz 1
;Оптимизированный компонент CheckBox (Исходный вариант от Maxxxx32)
2
;Оптимизирован вывод строки надписи для CheckBox'a + теперь, при проверке не происходит подсчет кол-ва символов в строке
3
;Оптимизация команд - отказался от сохранения регистров в стеке.
360 Lrz 4
;19.02.2007 общее улучшение кода, уменьшение размера и использование системных цветов для отображения checkbox
144 Lrz 5
;17.07.2006 произведена оптимизация, при установке чек бокса в положение включено последующие чек боксы в тот же промежуток времени не проверяются
6
;22.08.2006 произведена оптимизация команд, приняты во внимание замечания DIAMOND'а.
360 Lrz 7
;  - Теплов Алексей  www.lrz.land.ru
144 Lrz 8
 
9
macro use_check_box
10
{
11
ch_text_margin=4     ;расстояние от прямоугольника чек бокса до надписи
12
ch_size=10           ;размер квадрата чек бокса
13
ch_left equ [edi]    ;координата начала рисования по х
14
ch_top equ [edi+2]   ;координата начала рисования по у
360 Lrz 15
ch_border_color equ [sc.work_graph] ; or [edi+4] ;цвет рамки checkbox ее можно задать самостоятельно
16
ch_text_color equ   [sc.work_text];[edi+4]  ;цвет текста
17
ch_text_ptr equ [edi+4]    ;указатель на начало текстовой строки
18
ch_text_length equ [edi+8] ;длина надписи (2^64 такой длины может быть текст)
19
ch_flags equ [edi+10]       ;флаги
144 Lrz 20
check_box:
21
.draw:
22
pusha   ;сохраним все регистры
23
	mov	eax,38     	;рисование линии
24
	movzx	ebx,word ch_left	;положение по х
25
	mov	ecx,ebx		;сохраним в регистре cx значение bx  1 микрооперация
26
	;push	bx  ;3 - микрооперации  используя стек можно выиграть в размере, используя регистры - в скорости
27
	shl	ebx,16		;сдвинем на 16 разрядов в лево (умножим на 65536)
28
	;pop	bx  ;2 - микрооперации  на данный момент сформирована [координата начала по оси x]*65536 + [координата начала по оси x]
29
	mov	bx,cx		;восстановим значение bx
30
	movzx	ecx,word ch_top	;загрузим в cx значение y
31
	mov	esi,ecx		;сохраним значение регистра cx в регистр указатель si
32
	;push	cx
33
	shl	ecx,16		; сдвинем на 16 разрядов в лево (умножим на 65536)	mov	cx,si		;восстановим значение регистра cx
34
	mov 	cx,si		;восстановим значение регистра cx
35
	;pop	cx    	;[координата начала по оси y]*65536 + [координата начала по оси y]
36
	;push	cx
37
	add	ecx,ch_size ;[координата начала по оси y]*65536 + [координата конца по оси y]
38
	mov	edx,ch_border_color ;Цвет линии
39
	int	0x40   ;рисование вертикальной левой линии квадрата (прямоугольника)
40
;
41
	mov	ebp,ebx	;сохраним регистр bx в регистре указателя базы
42
	;push	bx   ;втолкнуть в bx [координата начала по оси х]*65536 + [координата начала по оси x]
43
	add	ebx,ch_size      ;[координата начала + длина стороны по оси х]
44
	ror	ebx,16          ;[координата начала + дина стороны по оси х]*65536
45
	add	ebx,ch_size      ;[координата начала+длина стороны по оси х]*65536 + [координата начала+длина стороны по оси x]
46
	int	0x40
47
 
48
	mov	bx,bp		;восстановим значение регистра bx
49
	;pop	bx
50
	mov	cx,si		;сохраним значение регистра cx в регистр указатель
51
	;pop	cx
52
	int	0x40
53
	add	ecx,ch_size	;добавим размер стороны
54
	mov	esi,ecx		;сохраним значение регистра cx в регистр указатель si
55
	;push	cx
56
	shl	ecx,16
57
	mov	cx,si
58
	;pop	cx
59
	int	0x40            ;нарисовали прямоугольник
60
 
360 Lrz 61
	call	.clear_ch
62
 
63
	test	word ch_flags,2  ;достать значение бита из переменной и поместить в  флаг CF
144 Lrz 64
	jz	@f		;в если CF=1, то выполним следующую процедуру иначе перейти на нижнюю @@
65
	call	.draw_ch  ;нарисовать включенный чек бокс
66
@@:
67
;----------------------------
68
;расчет куда будет произведен вывод текста
69
;----------------------------
70
	movzx	ebx,word ch_left	;загрузить значение х для чек бокса
71
	add	ebx,(ch_size+ch_text_margin) ;добавить размер стороны и расстояние на котором начнется вывод текста
72
	shl	ebx,16		;сдвинем на 16 разрядов в лево (умножим на 65536)
73
	mov	bx,ch_top	;загрузим значение по y
74
	add	ebx,(ch_size-9+2)	;добавим значение длины стороны -9+2
75
	mov	ecx,ch_text_color	;загрузим цвет надписи
76
 
77
	mov	edx,ch_text_ptr		;укажем адрес от куда нужно выводить строку
78
	movzx 	esi,word ch_text_length ;Загрузим длину надписи в esi
79
	;внесем в eax значение вывода надписи на канву
80
	mov	eax,4
81
	int	0x40          	;Вывод
82
popa				;восстановить значения регистров из стека
83
ret				;выйдем из процедуры
84
 
85
.clear_ch:			;очистка чек бокса
360 Lrz 86
	mov	edx,dword [sc.work]	;цвет внутри чек бокса
144 Lrz 87
	jmp	@f		;безусловный прыжок на нижнюю метку @@
88
 
89
.draw_ch:            ;нарисовать включенный чек бокс
90
	mov	edx,ch_border_color	;загрузить цвет
91
@@:
92
	movzx	ebx,word ch_left	;загрузить координату по х
93
	add	ebx,(ch_size/3)	;добавить (сторона прямоугольника/3)
94
	shl	ebx,16		;сдвинем на 16 разрядов в лево (умножим на 65536)
95
	mov	bx,(ch_size/2)	;загрузить (сторона прямоугольника/2)
96
	mov	bp,bx		;сохраним регистр bx в регистре указателя базы
97
	;push	bx
98
	movzx	ecx,word ch_top	;загрузить координату по у
99
	mov	eax,13		;в eax - значения функции для вывода полосы т.е. по сути прямоугольника, который отображает включенный компонент чек бокс
100
	add	ecx,(ch_size/3)	;добавить (сторона прямоугольника/3)
101
	shl	ecx,16		;сдвинем на 16 разрядов в лево (умножим на 65536)
102
	mov	cx,bp		;загрузим значения регистра указателя базы в cx
103
	;pop	cx
104
 
105
	int	0x40		;вывод
106
ret				;выйти из процедуры
107
 
108
.mouse:                 ;обработка мыши
109
pusha
110
	mov	eax,37   	;будем что то делать если у нас что - нить нажато
111
	mov	ebx,2		;внести в регистр значение 2
112
	int	0x40		;проверка не нажал ли пользователь кнопку мышки
113
	test	eax,eax    ;проверка если у нас в eax=0, то установим флаг и выйдем
114
	jnz	@f         ;перейти на нижнюю метку @@
360 Lrz 115
	btr	word ch_flags,2  ;извлечение значения заданного бита в флаг cf и изменение его значения на нулевое.
144 Lrz 116
	popa			;если ничего не произошло, то восстановим значения регистров из стека
117
	ret                     ;выход
118
@@:
360 Lrz 119
	bts	word ch_flags,2   ;проверка флага т.е. перенос в cf значение бита и установка бита в состояние включено
144 Lrz 120
	jc	.mouse_end         ;если CF=1 то перейти  в конец т.е. это выход
121
	movzx	esi,word ch_text_length ;загрузить кол-во символов в текстовой строке
122
	;Умножение на 6 Быстрое умножение можно воспользоваться любым мз методов, но на старых Процессорах (386,486,P1)быстрее будет с инструкцией Lea
123
	;lea	esi,[eax*2+eax]
124
	;shl	eax,1
125
	imul	esi,6               ; или можно и так умножить на 6
126
        add	esi,ch_text_margin   ;добавить 3 - расстояние от чек бокса до надписи
127
 
128
	mov	eax,37		;получим координаты мышки
129
	mov	ebx,1		;добавить 1
130
	int	0x40                ;получить координаты курсора относительно окна
131
 
132
	movzx	ebx,word ch_top           ;загрузить в bx значение координаты у
133
	cmp	ax,bx               ;сравнить с с координатой курсора
134
	jl	.mouse_end          ;SF <> OF если меньше
135
	add	ebx,ch_size          ;добавить размер
136
	cmp	ax,bx               ;сравнить
137
	jg	.mouse_end          ;ZF = 0 и SF = OF если больше
138
 
139
	shr	eax,16              ;разделим на 65536 или просто сдвинем биты на 16 значений
140
	movzx	ebx,word ch_left          ;произведем аналогичное сравнение
141
	cmp	ax,bx		     ;сравнить регистры
142
	jl	.mouse_end	     ;если меньше
143
	add	ebx,ch_size	     ;добавить длину стороны прямоугольника
144
	add	ebx,esi		    ;Учесть в значении по х еще и длину надписи к чекбоксу
145
	cmp	ax,bx		     ;стравнить регистры
146
	jg	.mouse_end	     ;если больше
147
 
360 Lrz 148
	bts	word ch_flags,1  ;извлечение значения заданного бита в флаг cf и изменение его значения на 1.
144 Lrz 149
	jc	@f                ;CF=1 то перейти на нижнюю @@
150
 
151
	call	.draw_ch          ;отобразить включенный чек бокс
152
	mov	dword [esp+24],1  ;дальнейшая проверка чек боксов бесмыслена, по этому в стек, где располагается ecx поместитм 0
153
	jmp	.mouse_end        ;выйти
154
@@:
360 Lrz 155
	btr	word ch_flags,1  ;извлечение значения заданного бита в флаг cf и изменение его значения на нулевое.
144 Lrz 156
	call	.clear_ch         ;выключить чек бокс т.е. на месте закрашенного прямоугольника отобразить цвет фона.
157
.mouse_end:
158
popa				  ;восстановить регистры из стека
159
ret				  ;выйти
160
}
161
 
360 Lrz 162
struc check_box left,top,text,text_length,flags
144 Lrz 163
{	;структура параметров для чек бокса
164
.left: dw left	;+0	;положение по х
165
.top: dw top	;+2	;положение по у
360 Lrz 166
;.border_color: dd border_color ;+8	цвет рамки
167
;.text_color: dd text_color     ;+12	цвет текста надписи
144 Lrz 168
.text: dd text	     ;+16		адрес в коде программы где расположен текстр
169
.text_length: dw text_length ; +20	длина текста
360 Lrz 170
.flags: dw flags+0   ;+22		флаги
144 Lrz 171
}
360 Lrz 172
ch_struc_size=12			;общая структура 24 байт
173
ch_flag_en=10b
144 Lrz 174
macro draw_check_boxes start,end	;рисовать чек боксы
175
{
176
	mov	edi,start			;Указатель на начало данных чек боксов т.е. на начало данных первого чекбокса
177
	mov	ecx,((end-start)/ch_struc_size) ;Количество чек боксов
178
@@:
179
	call	check_box.draw                  ;Отобразить чек бокс
180
	add	edi,ch_struc_size               ;Указатель на последующие чек боксы  т.е. +28
181
	loop	@b	;прыгнуть если в ecx/cx значение не 0 на верхнюю @@
182
}
183
macro mouse_check_boxes start,end	;установка чек боксов, в зависимости от события
184
{
185
	mov	edi,start		; Указатель на начало данных чек боксов т.е. на начало данных первого чекбокса
186
	mov	ecx,((end-start)/ch_struc_size)	;Количество чек боксов
187
@@:
188
	call	check_box.mouse		;проверка мышки и обработка событий
189
	add	edi,ch_struc_size	;Указатель на последующие чек боксы
190
	loop	@b	;прыгнуть если в ecx/cx значение не 0 на верхнюю @@
191
}