Subversion Repositories Kolibri OS

Rev

Rev 356 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
355 Lrz 1
;компонент OptionBox (Основан на Checkbox)
2
;Огромная благодарность Maxxxx32, Diamond, и другим программистам, и их программам, без
3
;которых я не смог бы написать этот компонент.
4
;16.02.2007
5
;  - Теплов Алексей  www.lrz.land.ru
6
 
7
macro use_option_box
8
{
9
op_text_margin=4     ;расстояние от прямоугольника чек бокса до надписи
10
op_size=10           ;размер квадрата чек бокса
11
op_left equ [edi]    ;координата начала рисования по х
12
op_top equ [edi+2]   ;координата начала рисования по у
13
op_color equ [edi+4] ;цвет внутри optionbox
14
op_border_color equ [edi+8] ;цвет рамки optionbox
15
op_text_color equ [edi+12]  ;цвет текста
16
op_text_ptr equ [edi+16]    ;указатель на начало текстовой строки
17
op_text_length equ [edi+20] ;длина надписи (2^64 такой длины может быть текст)
18
op_optibox_gr	equ [edi+22]
19
option_box:
20
.draw:
21
pusha   ;сохраним все регистры
22
	mov	eax,38     	;рисование линии
23
	movzx	ebx,word op_left	;положение по х
24
	mov	ecx,ebx		;сохраним в регистре cx значение bx  1 микрооперация
25
	;push	bx  ;3 - микрооперации  используя стек можно выиграть в размере, используя регистры - в скорости
26
	shl	ebx,16		;сдвинем на 16 разрядов в лево (умножим на 65536)
27
	;pop	bx  ;2 - микрооперации  на данный момент сформирована [координата начала по оси x]*65536 + [координата начала по оси x]
28
	mov	bx,cx		;восстановим значение bx
29
	movzx	ecx,word op_top	;загрузим в cx значение y
30
	mov	esi,ecx		;сохраним значение регистра cx в регистр указатель si
31
	;push	cx
32
	shl	ecx,16		; сдвинем на 16 разрядов в лево (умножим на 65536)	mov	cx,si		;восстановим значение регистра cx
33
	mov 	cx,si		;восстановим значение регистра cx
34
	;pop	cx    	;[координата начала по оси y]*65536 + [координата начала по оси y]
35
	;push	cx
36
	add	ecx,op_size ;[координата начала по оси y]*65536 + [координата конца по оси y]
37
	mov	edx,op_border_color ;Цвет линии
38
	int	0x40   ;рисование вертикальной левой линии квадрата (прямоугольника)
39
;
40
	mov	ebp,ebx	;сохраним регистр bx в регистре указателя базы
41
	;push	bx   ;втолкнуть в bx [координата начала по оси х]*65536 + [координата начала по оси x]
42
	add	ebx,op_size      ;[координата начала + длина стороны по оси х]
43
	ror	ebx,16          ;[координата начала + дина стороны по оси х]*65536
44
	add	ebx,op_size      ;[координата начала+длина стороны по оси х]*65536 + [координата начала+длина стороны по оси x]
45
	int	0x40
46
 
47
	mov	bx,bp		;восстановим значение регистра bx
48
	;pop	bx
49
	mov	cx,si		;сохраним значение регистра cx в регистр указатель
50
	;pop	cx
51
	int	0x40
52
	add	ecx,op_size	;добавим размер стороны
53
	mov	esi,ecx		;сохраним значение регистра cx в регистр указатель si
54
	;push	cx
55
	shl	ecx,16
56
	mov	cx,si
57
	;pop	cx
58
	int	0x40            ;нарисовали прямоугольник
59
 
60
	mov	eax,13          ;закрашиваем его. Функция 13 - нарисовать полосу
61
	movzx	ebx,word op_left	;загрузить в bx, положение по х
62
	add	ebx,1		;сдвинем на 1 т.е. прибавим 1 иначе затрется рамка
63
	shl	ebx,16		;сдвинем на 16 разрядов в лево (умножим на 65536)
64
	mov	bx,op_size	;прибавим длину стороны прямоугольника
65
	sub	ebx,1		;вычтем 1 т.к. иначе затрется рамка
66
	mov	bp,bx		;сохраним регистр bx в регистре указателя базы
67
	;push	bx
68
	movzx	ecx,word op_top	;загрузим координаты по y
69
	add	ecx,1		;сдвинем на 1 т.е. прибавим 1 иначе затрется рамка
70
	shl	ecx,16		;сдвинем на 16 разрядов в лево (умножим на 65536)
71
	mov	cx,bp		;восстановим значение регистра cx
72
	;pop	cx
73
	mov	edx,op_color	;загрузим цвет полосы
74
	int	0x40            ;закрасили
75
 
76
        mov	eax,op_optibox_gr
77
	mov	dword eax,[eax]
78
        cmp	eax,edi
79
	jne	@f
80
	call	.draw_op  ;нарисовать включенный чек бокс
81
;----------------------------
82
;расчет куда будет произведен вывод текста
83
;----------------------------
84
@@:	movzx	ebx,word op_left	;загрузить значение х для чек бокса
85
	add	ebx,(op_size+op_text_margin) ;добавить размер стороны и расстояние на котором начнется вывод текста
86
	shl	ebx,16		;сдвинем на 16 разрядов в лево (умножим на 65536)
87
	mov	bx,op_top	;загрузим значение по y
88
	add	ebx,(op_size-9+2)	;добавим значение длины стороны -9+2
89
	mov	ecx,op_text_color	;загрузим цвет надписи
90
 
91
	mov	edx,op_text_ptr		;укажем адрес от куда нужно выводить строку
92
	movzx 	esi,word op_text_length ;Загрузим длину надписи в esi
93
	;внесем в eax значение вывода надписи на канву
94
	mov	eax,4
95
	int	0x40          	;Вывод
96
popa				;восстановить значения регистров из стека
97
ret				;выйдем из процедуры
98
 
99
.clear_op:			;очистка чек бокса
100
	mov	edx,op_color	;цвет внутри чек бокса
101
	jmp	@f		;безусловный прыжок на нижнюю метку @@
102
 
103
.draw_op:            ;нарисовать включенный чек бокс
104
	mov	edx,op_border_color	;загрузить цвет
105
@@:
106
	movzx	ebx,word op_left	;загрузить координату по х
107
	add	ebx,(op_size/3)	;добавить (сторона прямоугольника/3)
108
	shl	ebx,16		;сдвинем на 16 разрядов в лево (умножим на 65536)
109
	mov	bx,(op_size/2)	;загрузить (сторона прямоугольника/2)
110
	mov	bp,bx		;сохраним регистр bx в регистре указателя базы
111
	;push	bx
112
	movzx	ecx,word op_top	;загрузить координату по у
113
	mov	eax,13		;в eax - значения функции для вывода полосы т.е. по сути прямоугольника, который отображает включенный компонент чек бокс
114
	add	ecx,(op_size/3)	;добавить (сторона прямоугольника/3)
115
	shl	ecx,16		;сдвинем на 16 разрядов в лево (умножим на 65536)
116
	mov	cx,bp		;загрузим значения регистра указателя базы в cx
117
	;pop	cx
118
	int	0x40		;вывод
119
ret				;выйти из процедуры
120
 
121
.mouse:                 ;обработка мыши
122
pusha
123
	mov	eax,37   	;будем что то делать если у нас что - нить нажато
124
	mov	ebx,2		;внести в регистр значение 2
125
	int	0x40		;проверка не нажал ли пользователь кнопку мышки
126
	test	eax,eax    ;проверка если у нас в eax=0, то установим флаг и выйдем
127
	jnz	@f         ;перейти на нижнюю метку @@
128
	popa			;если ничего не произошло, то восстановим значения регистров из стека
129
	ret                     ;выход
130
@@:
131
	movzx	esi,word op_text_length ;загрузить кол-во символов в текстовой строке
132
	;Умножение на 6 Быстрое умножение можно воспользоваться любым мз методов, но на старых Процессорах (386,486,P1)быстрее будет с инструкцией Lea
133
	;lea	esi,[eax*2+eax]
134
	;shl	eax,1
135
	imul	esi,6               ; или можно и так умножить на 6
136
        add	esi,op_text_margin   ;добавить 3 - расстояние от чек бокса до надписи
137
 
138
	mov	eax,37		;получим координаты мышки
139
	mov	ebx,1		;добавить 1
140
	int	0x40                ;получить координаты курсора относительно окна
141
 
142
	movzx	ebx,word op_top           ;загрузить в bx значение координаты у
143
	cmp	ax,bx               ;сравнить с с координатой курсора
144
	jl	.mouse_end          ;SF <> OF если меньше
145
	add	ebx,op_size          ;добавить размер
146
	cmp	ax,bx               ;сравнить
147
	jg	.mouse_end          ;ZF = 0 и SF = OF если больше
148
 
149
	shr	eax,16              ;разделим на 65536 или просто сдвинем биты на 16 значений
150
	movzx	ebx,word op_left          ;произведем аналогичное сравнение
151
	cmp	ax,bx		     ;сравнить регистры
152
	jl	.mouse_end	     ;если меньше
153
	add	ebx,op_size	     ;добавить длину стороны прямоугольника
154
	add	ebx,esi		    ;Учесть в значении по х еще и длину надписи к чекбоксу
155
	cmp	ax,bx		     ;стравнить регистры
156
	jg	.mouse_end	     ;если больше
157
	mov	eax,op_optibox_gr
158
        mov	[eax],edi
159
 
160
.mouse_end:
161
popa				  ;восстановить регистры из стека
162
ret				  ;выйти
163
}
164
 
165
struc option_box left,top,color,border_color,text_color,text,text_length,point_gr,flags
166
{	;структура параметров для чек бокса
167
.left: dw left	;+0	;положение по х
168
.top: dw top	;+2	;положение по у
169
.color: dd color ;+4	;цвет внутри чек бокса
170
.border_color: dd border_color ;+8	цвет рамки
171
.text_color: dd text_color     ;+12	цвет текста надписи
172
.text: dd text	     ;+16		адрес в коде программы где расположен текстр
173
.text_length: dw text_length ; +20	длина текста
174
.option_group: dd point_gr	;указатель на размещение edi - идентификатора optibox
175
}
176
op_struc_size=26			;общая структура 24 байт
177
op_flag_en=10b
178
macro draw_option_boxes start,end	;рисовать чек боксы
179
{
180
	mov	edi,start			;Указатель на начало данных чек боксов т.е. на начало данных первого чекбокса
181
	mov	ecx,((end-start)/op_struc_size) ;Количество чек боксов
182
@@:
183
	call	option_box.draw                  ;Отобразить чек бокс
184
	add	edi,op_struc_size               ;Указатель на последующие чек боксы  т.е. +28
185
	loop	@b	;прыгнуть если в ecx/cx значение не 0 на верхнюю @@
186
}
187
macro mouse_option_boxes start,end	;установка чек боксов, в зависимости от события
188
{
189
	mov	edi,start		; Указатель на начало данных чек боксов т.е. на начало данных первого чекбокса
190
	mov	ecx,((end-start)/op_struc_size)	;Количество чек боксов
191
@@:
192
	call	option_box.mouse		;проверка мышки и обработка событий
193
	add	edi,op_struc_size	;Указатель на последующие чек боксы
194
	loop	@b	;прыгнуть если в ecx/cx значение не 0 на верхнюю @@
195
 
196
       	mov	edi,start		; Указатель на начало данных чек боксов т.е. на начало данных первого чекбокса
197
	mov	ecx,((end-start)/op_struc_size)	;Количество чек боксов
198
 
199
.home:
200
	mov	eax,[edi+22]	;op_optibox_gr
201
        mov	dword eax,[eax]
202
 
203
        pusha
204
 
205
	cmp	eax,edi
206
	jne	@f
207
 
208
	call	option_box.draw_op
209
	jmp	.nxtm
210
@@:     call	option_box.clear_op
211
 
212
.nxtm:  popa
213
	add	edi,op_struc_size               ;Указатель на последующие чек боксы  т.е. +28
214
        loop 	.home
215
 
216
}