Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
391 Lrz 1
;  06.03.2007 Переписал полностью алгоритм управления shift
348 Lrz 2
;  15.02.2007 улучшение снятия выделения и перерисовки очищаемой области, значительно приятнее работает компонент
3
;  13.02.2007 убрал по возможности мерцание, улучшена обработка перерисовки фона
4
; добавил фитчу внесения 0х0 по адресу ed_size иначе у Maxxx32 были несостыковки в коде. Причина в том, что оптимизация была сведена к тому, что я не чистил символы в буфере, когда удалял, я просто их не выводил, и потом, когда вносился новый символ, он попросту затирал уже имеющийся. Если бы, программа обрабатывала конец строки по ed_size, проблемы не возникло. Но сейчас этот недостаток исправлен.
306 Lrz 5
;  01.02.2007 доработка edit_box, исправил баги.
295 Lrz 6
;  26.01.2007 нормальная работа компанента исправил фукцию .check_offset
7
;  24.01.2007 пофиксел баги вызваные не правильным кодом )).
289 Lrz 8
;  22.01.2007 избавился от глюков при работе с выделением и удаление, корректная работа клавишей del & backspase
9
;  20.01.2007 реализовал выделение текста по shift
234 Lrz 10
;  12.12.2006 реализовал поддержку кнопки insert и сегодя компонент почти работает!!!!
11
;  07.12.2006 продолжается работа над переработкой компонента,изменениям подверглись многие функции, переработан вывод текста, а така же алгоритм внесения символов.
12
;  03.09.2006 по возможности отказался от 16 битной арифметики, добавил новые баги
13
;  09.08.2006 произведена оптимизация работы конпок DEL и Backspace, уменьшен размер выполняемого кода.
14
;  21.07.2006 добавлена функция кнопки Del, теперь можно удалять символы при помощи данной клавиши
15
; Автор: Евтихов Максим (Maxxxx32) email: maxxxxm@mail.ru
16
; Дата последних изменений: 13.06.06 10:40
17
;  Напишите в исходном коде своей программы use_edit_box,
18
; это вставит необходимые процедуры в код вашей программы.
19
;  Процедуры:
20
;   edit_box.draw - полная перерисовка;
21
;   edit_box.key - обработка клавиатуры;
22
;   edit_box.mouse - обработка мыши;
23
;   edit_box.focus - установка фокуса;
24
;   edit_box.blur - его размывание;
25
;   edit_box.get_n - получить количество прорисовываемых символов.
26
;  При вызове любых из этих процедур в регистре edi следует
27
; оставить указатель на структуру.
28
;  Пример структуры:
29
; some_edit edit_box 100,10,30,0x00ffffff,0,0x00aaaaaa,0,255,some_edit_text
30
; длина, высота, верх, цвет фона, цвет рамки, если выбран,
31
; цвет рамки, если не выбран, максимальное количество символов,
32
; указатель на буфер, где будут хранится символы. Буфер должен
33
; оканчиваться нулем, например если максимальное количество 255:
34
;  some_edit_text:
35
;       rb      256 ;255+1
36
 
37
;  Пример вызова процедуры:
38
;       mov     edi,some_edit
39
;       call    edit_box.draw
40
 
41
;  При вызове процедуры edit_box.key код клавиши должен
42
; находится в ah, то есть перед вызовом этой процедуры надо вызвать
43
; 2-ую сисемную функцию, например:
44
;       mov     eax,2
45
;       int     0x40
46
;       mov     edi,some_edit1
47
;       call    edit_box.key
48
;       mov     edi,some_edit2
49
;       call    edit_box.key
50
;  Перед вызовом обработчика мыши следует проверить, является ли окно
51
; активным.
52
;  Если щелчок мыши был пройзведен за пределами edit box
53
; фокус теряется.
54
macro use_edit_box
55
{
56
edit_box:
57
ed_width	equ [edi]		;ширина компонента
58
ed_left 	equ [edi+4]             ;положение по оси х
59
ed_top		equ [edi+8]             ;положение по оси у
60
ed_color	equ [edi+12]		;цвет фона компонента
61
ed_focus_border_color	equ [edi+16]	;цвет рамки компонента
62
ed_blur_border_color	equ [edi+20]    ;цвет не активного компонента
63
ed_text_color	equ [edi+24]            ;цвет текста
282 Lrz 64
ed_max		equ [edi+28]                    ;кол-во символов которые можно максимально ввести
65
ed_text 	equ [edi+32]                    ;указатель на буфер
66
ed_flags	equ [edi+36]            ;флаги
67
ed_size equ [edi+38]                    ;кол-во символов
68
ed_pos	equ [edi+42]                    ;позиция курсора
69
ed_offset	equ [edi+46]            ;смещение
70
cl_curs_x	equ [edi+50]		;предыдущее координата курсора по х
71
cl_curs_y	equ [edi+54]		;предыдущее координата курсора по у
292 Lrz 72
ed_shift_pos	equ [edi+58]
391 Lrz 73
ed_shift_pos_old equ [edi+62]
234 Lrz 74
;==========================================================
75
;=== процедура прорисовки =================================
76
;==========================================================
77
.draw:
78
pusha
79
;--- рисуем рамку ---
80
	call	.draw_border		; Функция стабильна
81
.draw_bg_cursor_text:
82
;--- изменяем смещение, если надо ---
83
	call	.check_offset		;вычисление позиции курсора стабильна
84
;--- рисуем внутреннюю область ---
85
	call	.draw_bg                ;нарисовать прямоугольник рабочей области
86
.draw_cursor_text:
87
;--- рисуем курсор ---
88
	;--- может его не надо рисовать ----
282 Lrz 89
	test	word ed_flags,ed_focus
234 Lrz 90
	je	@f
91
	call	.draw_cursor
92
@@:
93
	call	.draw_text
94
popa
95
ret
96
 
292 Lrz 97
;.str:
98
;	mov ecx,0x0a ;задается система счисления изменяются регистры ebx,eax,ecx,edx входные параметры eax - число
99
;	 ;преревод числа в ASCII строку взодные данные ecx=система счисленя edi адрес куда записывать, будем строку, причем конец переменной
100
;	cmp eax,ecx  ;сравнить если в eax меньше чем в ecx то перейти на @@-1 т.е. на pop eax
101
;	jb @f
102
;	xor edx,edx  ;очистить edx
103
;	div ecx      ;разделить - остаток в edx
104
;	push edx     ;положить в стек
105
;	;dec edi	     ;смещение необходимое для записи с конца строки
295 Lrz 106
;	call .str;перейти на саму себя т.е. вызвать саму себя и так до того момента пока в eax не станет меньше чем в ecx
292 Lrz 107
;	pop eax
108
;	@@: ;cmp al,10 ;проверить не меньше ли значение в al чем 10 (для системы счисленя 10 данная команда - лишная))
109
;	;sbb al,$69  ;- честно данная инструкция меня заставляет задуматься т.е. я не знаю как это работает
110
;	;das	    ;после данной команды как бы происходит уменьшение al на 66h  (в книге написано другое)
111
;	or al,0x30  ;данная команда короче  чем две выше
112
;	stosb	    ;записать элемент из регистра al в ячеку памяти es:edi
391 Lrz 113
 ;
292 Lrz 114
;	ret	    ;вернуться чень интересный ход т.к. пока в стеке храниться кол-во вызовов то столько раз мы и будем вызываться
282 Lrz 115
 
234 Lrz 116
;----------------------------------------------------------
117
;--- процедура прорисовки текста --------------------------
118
;----------------------------------------------------------
119
.draw_text:
120
;--- вычисляем, сколько помещается символов ---
121
;--- чтобы мусор не рисовать ---
122
	call 	.get_n
123
	mov	esi,ed_size
124
        mov	ebx,ed_offset
125
	sub	esi,ebx
126
	cmp	eax,esi
127
	jae	@F
128
	mov	esi,eax		;чтобы не выходить за пределы экрана
129
;--- рисуем текст ---
130
@@: 	mov	eax,4
131
	mov	ebx,ed_left
306 Lrz 132
	mov	edx,ed_offset
234 Lrz 133
	add	ebx,2
134
	shl	ebx,16
135
	mov	bx,ed_top
136
	add	ebx,4
137
	mov	ecx,ed_text_color
138
	add	edx,ed_text
139
	int	0x40
140
ret
141
;----------------------------------------------------------
142
;--- процедура прорисовки фона ----------------------------
143
;входные данные
144
;eax
292 Lrz 145
;edx - color
234 Lrz 146
;----------------------------------------------------------
343 Lrz 147
;вход только цвет edx
234 Lrz 148
.draw_bg:
149
	mov	ebx,ed_left
150
	add	ebx,1
151
	shl	ebx,16
152
	mov	bx,ed_width
153
	sub	ebx,1
391 Lrz 154
       	mov	edx,ed_color
155
.draw_bg_eax:
234 Lrz 156
	mov	ecx,ed_top
306 Lrz 157
	mov	eax,13
234 Lrz 158
	add	ecx,1
159
	shl	ecx,16
160
	mov	cx,ed_height
391 Lrz 161
	dec	ecx
306 Lrz 162
        int	0x40
234 Lrz 163
ret
164
 
165
;----------------------------------------------------------
166
;--- процедура получения количества символов в текущей щирине компонента --------------
167
;----------------------------------------------------------
168
.get_n:
306 Lrz 169
	mov	eax,ed_width	;получем ширину компонента
234 Lrz 170
	xor	edx,edx   ;результат распологается в паре edx:eax в eax - остаток
171
	sub	eax,4		;вычтим 4
172
	mov	ebx,6		;загрузми делитель
173
	div	ebx		;размделим на 6
174
ret
175
 
176
;----------------------------------------------------------
177
;--- процедура рисования курсора --------------------------
178
;----------------------------------------------------------
391 Lrz 179
;входные ebp- цвет
234 Lrz 180
.clear_cursor:
391 Lrz 181
	mov	edx,ebp
234 Lrz 182
	mov	ebx,cl_curs_x
183
	mov	ecx,cl_curs_y
184
	jmp	.draw_curs
185
.draw_cursor:
282 Lrz 186
 
234 Lrz 187
	mov	edx,ed_text_color
391 Lrz 188
;@@:
234 Lrz 189
	mov	ebx,ed_pos
190
	mov	ecx,ed_offset
191
	sub	ebx,ecx
192
 
193
	lea     ebx,[ebx*2+ebx]
194
	shl     ebx,1
195
	;imul	ebx,6
196
	add	bx,ed_left
306 Lrz 197
	mov	ecx,ed_top
234 Lrz 198
	inc	ebx
306 Lrz 199
	add	ecx,2
234 Lrz 200
	mov	ebp,ebx
201
	shl	ebx,16
202
	mov	bx,bp
203
	mov	ebp,ecx
204
 
205
	shl	ecx,16
206
	mov	cx,bp
207
	add	cx,ed_height-4
208
 
209
	mov	cl_curs_x,ebx
210
	mov	cl_curs_y,ecx
211
.draw_curs:
212
	mov	eax,38
213
	int	0x40
214
ret
215
 
216
;----------------------------------------------------------
217
;--- процедура рисования рамки ----------------------------
218
;----------------------------------------------------------
219
.draw_border:
220
;--- цвет рамки ---
282 Lrz 221
	test	dword ed_flags,ed_focus
234 Lrz 222
	mov	edx,ed_focus_border_color
223
	jne     @f
224
	mov	edx,ed_blur_border_color
225
@@:
226
;--- сверху ---
227
	mov	eax,38
228
	mov	ebx,ed_left
229
	mov 	ecx,ebx
230
	shl	ebx,16
231
	mov	bx,cx
232
	add	bx,ed_width
233
	mov	ecx, ed_top
234
	mov	esi,ecx
235
	shl	ecx,16
236
	mov	cx,si
237
	int	0x40
238
 
239
;--- снизу ---
240
	mov	esi,ecx
241
	add	ecx,ed_height
242
	mov	ebp,ecx
243
	shl	ecx,16
244
	mov	cx,bp
245
	int	0x40
246
 
247
;--- слева ---
248
	mov	cx,si
249
	mov	ebp,ebx
250
	sub	bx,ed_width
251
	int	0x40
252
 
253
;--- справа ---
254
	mov	ebx,ebp
255
	shl	ebx,16
256
	mov	bx,bp
257
	int	0x40
258
ret
259
;----------------------------------------------------------
260
;--- проверка, зашел ли курсор за границы и, если надо, ---
261
;--- изменяем смещение ------------------------------------
296 Lrz 262
;--- eax = -1, если не изменилось или eax = 0, если
234 Lrz 263
; изменилось
264
;----------------------------------------------------------
265
.check_offset:
350 Lrz 266
pusha
295 Lrz 267
	mov	ecx,ed_pos
268
	mov	ebx,ed_offset
269
	cmp	ebx,ecx
270
	ja	.sub_8
271
 
272
	push	ebx
234 Lrz 273
	call	.get_n			;получим кол-во символов в паре регистров edx:eax
274
	pop	ebx
295 Lrz 275
	mov	edx,ebx
276
	add	edx,eax		;ed_offset+width editbox
277
	cmp	edx,ecx
278
	ja	@f
279
 
280
	mov	edx,ed_size
296 Lrz 281
	cmp	edx,ecx
282
	je      .add_end
283
 
284
	sub	edx,ecx
295 Lrz 285
	cmp	edx,8
286
	jbe	.add_8
296 Lrz 287
	add	ebx,8
295 Lrz 288
	jmp	.chk_d
289
 
290
.sub_8: cmp	ecx,0
291
	je	.sub_min
292
	cmp	ebx,8
293
        jbe	.sub_min
294
	sub	ebx,8	;ebx=ed_offset
295
	jmp	.chk_d
296
.sub_min:
297
        xor	ebx,ebx
298
	jmp	.chk_d
299
 
296 Lrz 300
.add_end:sub	edx,eax
301
	mov	ebx,edx
302
	jmp	.chk_d
303
.add_8:	add	ebx,edx
295 Lrz 304
.chk_d:	mov	ed_offset,ebx
305
	call    .draw_bg
391 Lrz 306
	;mov	dword [esp+28],-1
350 Lrz 307
popa
295 Lrz 308
	ret
309
@@:
310
	mov	dword [esp+28],0
350 Lrz 311
popa
295 Lrz 312
	ret
313
;==========================================================
314
;=== обработка клавиатуры =================================
315
;==========================================================
316
.key:
317
pusha
318
	test	word ed_flags,ed_focus ; если не в фокусе, выходим
350 Lrz 319
	je      @b
343 Lrz 320
;Проверка на нажаты shift
292 Lrz 321
	xor	ecx,ecx
282 Lrz 322
	push	eax
292 Lrz 323
	inc	ecx
282 Lrz 324
	mov	eax,66
325
	mov	ebx,3
326
	int	0x40
327
	test	al,0x03
328
	je	@f
343 Lrz 329
        or      word ed_flags,ed_shift   ;установим флаг
282 Lrz 330
 
343 Lrz 331
@@:     pop	eax   ;восстановим считаный символ с клавиатуры
234 Lrz 332
;----------------------------------------------------------
333
;--- проверяем, что нажато --------------------------------
334
;----------------------------------------------------------
335
	cmp	ah,8
336
	jz	.backspace
337
	cmp	ah,0xb6
338
	jz	.delete
339
	cmp	ah,176
340
	jz	.left
341
	cmp	ah,179
342
	jz	.right
343
	cmp	ah,180
344
	jz	.home
345
	cmp	ah,181
346
	jz	.end
347
	cmp	ah,185	;insert
348
	jz	.insert
349
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
350
;Заглушка на обработку клавиш вверх и вниз
351
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
352
	cmp	ah,177
353
        jz	.no_figure
354
	cmp	ah,178
355
	jz	.no_figure
356
	cmp	ah,27   ;ESC - клавиша ))
357
	jz	.no_figure
358
;--- нажата другая клавиша ---
359
	test	word ed_flags,ed_figure_only  ; только цифры ?
360
	jz	@f
361
	cmp	ah,'0'
362
	jb	.no_figure
363
	cmp	ah,'9'
364
	ja	.no_figure
292 Lrz 365
 
366
 
367
;проверка на shift
306 Lrz 368
@@:	test	word ed_flags,ed_shift_on
292 Lrz 369
	je	@f
370
	;Входные данные edx=ed_size;ecx=ed_pos
350 Lrz 371
 
292 Lrz 372
	push	eax
373
	mov	edx,ed_size
374
	mov	ecx,ed_pos
350 Lrz 375
	pusha
376
 
391 Lrz 377
	;cmp	edx,ecx
378
	;jne	.sh_cl
343 Lrz 379
;clear
391 Lrz 380
	mov	ebp,edx ;ed_size
381
        call	.clear_bg
382
       	mov	ebp,ed_color
348 Lrz 383
        call	.sh_cl_
350 Lrz 384
 
391 Lrz 385
.sh_nxt:popa
350 Lrz 386
	call	.del_char
387
 
292 Lrz 388
;;;;
391 Lrz 389
        mov	eax,dword ed_shift_pos
292 Lrz 390
        mov	ebx,ed_size
391
	sub	ebx,eax
392
	mov	ed_size,ebx
393
	pop	eax
394
 
395
        ; проверяем, находится ли курсор в конце
396
@@:	mov	ecx,ed_size
234 Lrz 397
	mov	edx, ed_max
343 Lrz 398
	test	word ed_flags,ed_insert
399
	jne	@f
289 Lrz 400
	cmp	ecx,edx
401
	jae	.no_figure
343 Lrz 402
@@:	mov	ebx, ed_pos
234 Lrz 403
	cmp	ebx,edx
404
	jl	@f ; если меньше или равно
405
.no_figure:
406
	popa
407
	ret
292 Lrz 408
.insert: test	word ed_flags,ed_insert	;not 	word ed_insert
409
         je     .insert_1
410
         and	word ed_flags,ed_insert_cl
411
	jmp	.no_figure
412
.insert_1:
413
	or	word ed_flags,ed_insert
234 Lrz 414
        jmp	.no_figure
292 Lrz 415
.ins_v:
306 Lrz 416
	dec	dword [ebp+38];ed_size    ;processing is insert
234 Lrz 417
	sub	esi,ecx
418
	add	esi,ebx
419
        mov	edi,esi
343 Lrz 420
;clear
421
pusha
422
	mov	edi,ebp
423
	mov	ebp,ed_pos
424
	call	.clear_bg
425
popa
234 Lrz 426
	jmp	.In_k
427
@@:     ; сдвигаем символы после курсора вправо
428
	mov	ecx,ed_size
429
	push	edi eax
292 Lrz 430
	mov	ebp,edi
234 Lrz 431
	mov	esi,ed_text     ; Указатель на буфер
432
				;Будем работать со строкой
433
	add	esi,ecx		;add ed_size добавим max size
434
	mov	edi,esi
435
 
436
       	cmp 	ecx,ebx         ;Если у нас позиция курсора = текущему размеру напечатанных символов т.е. курсор стоит в конце
437
	je	.In_k
438
 
292 Lrz 439
	test	word [ebp+36],ed_insert ;IF insert is enable  т.к. edi изменен адресуем через ebp
440
	jne	.ins_v
343 Lrz 441
;clear
442
pusha
443
	mov	edi,ebp
444
	mov	ebp,ed_size
445
	call	.clear_bg
446
popa
234 Lrz 447
	sub	ecx,ebx         ;Найдем кол-во символов для передвижения.
448
	inc	edi		;Сместим наши символы в право
449
	std
450
	inc 	ecx
451
   @@:
452
	;--------
453
	lodsb
454
	stosb
455
	;--------
456
	loop	@b
457
.In_k:	cld
458
	pop eax
459
	mov al,ah
460
	stosb
461
	pop edi
462
; вставляем код клавиши туда, где курсор
463
	; увеличиваем значение размера и позиции
464
	inc	 dword ed_size
295 Lrz 465
	inc	 dword ed_pos
234 Lrz 466
	call	.draw_all2
295 Lrz 467
	jmp	.shift;.draw_cursor_text
234 Lrz 468
.delete:
469
	mov	edx,ed_size
470
	mov	ecx,ed_pos
471
	cmp	edx,ecx
292 Lrz 472
	jg	.bac_del
289 Lrz 473
	test	word ed_flags,ed_shift_on
474
	jne	.del_bac
234 Lrz 475
	popa
476
	ret
289 Lrz 477
.bac_del:
292 Lrz 478
	call 	.del_char
234 Lrz 479
	jmp 	.draw_all
480
 
481
;--- нажата клавиша backspace ---
482
.backspace:
483
	; проверяем, курсор у левого края ?
484
	mov	edx,ed_size
485
	mov	ecx,ed_pos
486
	test	ecx,ecx
292 Lrz 487
	jnz	.del_bac
289 Lrz 488
        test	word ed_flags,ed_shift_on
489
        jne	.bac_del
234 Lrz 490
	popa
491
	ret
289 Lrz 492
.del_bac:
292 Lrz 493
	cmp	edx,ecx	;if ed_pos=ed_size
234 Lrz 494
	je	@f
495
	dec	ecx
496
	call 	.del_char
289 Lrz 497
@@:     test	word ed_flags,ed_shift_on
498
        jne	.bac_del
234 Lrz 499
	dec	 dword ed_pos
500
 
501
.draw_all:
343 Lrz 502
       	push	.shift;.draw_cursor_text;eax
289 Lrz 503
 
504
        test	word ed_flags,ed_shift_on
505
        je	@f
391 Lrz 506
        mov	eax,dword ed_shift_pos
289 Lrz 507
        mov	ebx,ed_size
508
	sub	ebx,eax
509
	mov	ed_size,ebx
510
 
391 Lrz 511
	mov	ebp,ed_color
343 Lrz 512
	call	.clear_cursor
513
	call	.check_offset
514
        call	.draw_bg
515
 
516
	ret
517
 
289 Lrz 518
@@:	dec	 dword ed_size
519
 
234 Lrz 520
.draw_all2:
290 Lrz 521
	and    word ed_flags,ed_shift_cl
391 Lrz 522
	mov	ebp,ed_color
234 Lrz 523
	call	.clear_cursor
524
	call	.check_offset
343 Lrz 525
	mov	ebp,ed_size
526
	call	.clear_bg
295 Lrz 527
	ret
343 Lrz 528
	;jmp	.shift
234 Lrz 529
;--- нажата клавиша left ---
391 Lrz 530
.left:  mov	ebx,ed_pos
234 Lrz 531
	test	ebx,ebx
391 Lrz 532
	jz	.sh_st_of
533
	or	word ed_flags,ed_left_fl
534
	call	.sh_first_sh
234 Lrz 535
	dec	 dword ed_pos
391 Lrz 536
	call	.sh_enable
537
	jmp	.draw_cursor_text
234 Lrz 538
;--- нажата клавиша right ---
391 Lrz 539
.right:	mov	ebx,ed_pos
234 Lrz 540
	cmp	ebx,ed_size
391 Lrz 541
	je	.sh_st_of
542
	and	word ed_flags,ed_right_fl
543
	call	.sh_first_sh
234 Lrz 544
	inc	dword  ed_pos
391 Lrz 545
	call	.sh_enable
546
	jmp	.draw_cursor_text
547
.home:
289 Lrz 548
	mov	ebx,ed_pos
234 Lrz 549
	test	ebx,ebx
391 Lrz 550
	jz	.sh_st_of
551
	call	.sh_first_sh
234 Lrz 552
	xor	eax,eax
553
	mov	ed_pos,eax
391 Lrz 554
	call	.sh_home_end
555
 	jmp	.draw_cursor_text
556
.end:
289 Lrz 557
	mov	ebx,ed_pos
234 Lrz 558
	cmp	ebx,dword ed_size
391 Lrz 559
	je	.sh_st_of
234 Lrz 560
	mov	eax,ed_size
561
	mov	ed_pos,eax
391 Lrz 562
	call	.sh_home_end
563
	jmp	.draw_cursor_text
564
;Обработка Shift для снятия выделения неизвестной области
348 Lrz 565
.shift: ;;;;;;;SHIFT
391 Lrz 566
	test    word ed_flags,ed_shift
348 Lrz 567
        je	.f_exit
343 Lrz 568
 
391 Lrz 569
@@:	mov	ebp,shift_color
570
	or	word ed_flags,ed_shift_bac ;установка флага, выделенной области
348 Lrz 571
	call	.sh_cl_
572
        jmp	.draw_cursor_text
573
;;;;;;;;;;;;;;;;;;;;;
391 Lrz 574
.f_exit:call	.check_offset
575
	and    word ed_flags,ed_shift_cl
348 Lrz 576
        call	.enable_null
577
	jmp	.draw_cursor_text
578
.sh_cl_:
282 Lrz 579
;;;;;;SHIFT end
391 Lrz 580
;обработка очистки, при левом - правом движении выделения
348 Lrz 581
;для обработки снятия выделения
391 Lrz 582
;	or	word ed_flags,ed_shift_bac ;установка флага, выделенной области
282 Lrz 583
	mov 	eax,dword	ed_pos
584
	mov	ebx,dword	ed_shift_pos
585
	cmp	eax,ebx
586
	jae	.sh_n
587
	push	eax  ;меньшее в eax
588
	push	ebx  ;большее
589
	jmp	.sh_n1
590
	             ;если иначе
591
.sh_n: 	push	ebx
592
	push	eax
593
.sh_n1:
594
	call	.check_offset
391 Lrz 595
;	test	eax,eax
596
;	jz      .drw_sim
282 Lrz 597
	call	.get_n
598
	mov	edx,eax	;size of ed_box
599
;	push	eax
600
	mov	ecx,ed_offset
601
	add	eax,ecx	;eax = w_off= ed_offset+width
348 Lrz 602
	mov	edx,eax ;save
282 Lrz 603
	pop	ebx     ;большее
604
	pop	eax     ;меньшее
605
 
606
	cmp	eax,ecx         ;сравнение с меньшего с offset.
607
	jae	.f_f            ;если больше
608
	xor	eax,eax
348 Lrz 609
	cmp	edx,ebx		;cравним размер w_off с большим
282 Lrz 610
	jb	@f
611
	sub	ebx,ecx
612
	jmp     .nxt_f
348 Lrz 613
@@:	mov	ebx,edx
282 Lrz 614
	sub	ebx,ecx
615
	jmp     .nxt_f
616
 
617
.f_f:
618
	sub	eax,ecx
348 Lrz 619
	cmp	edx,ebx		;cравним размер w_off с большим
282 Lrz 620
	jle	@f
621
	sub	ebx,ecx
622
	sub	ebx,eax
623
	jmp     .nxt_f
234 Lrz 624
@@:
348 Lrz 625
	mov	ebx,edx
282 Lrz 626
	sub	ebx,ecx
627
	sub	ebx,eax
628
.nxt_f:
289 Lrz 629
	mov	edx,ebx
282 Lrz 630
	lea	ebx,[eax*2+eax]
631
	shl	ebx,1
632
	add	ebx,ed_left
633
	inc	ebx
634
	shl	ebx,16
635
	lea	ecx,[edx*2+edx]
636
	shl	ecx,1
637
	mov	bx,cx
391 Lrz 638
	inc	ebx
348 Lrz 639
	mov	edx,ebp;shift_color
640
 
282 Lrz 641
	call	.draw_bg_eax
391 Lrz 642
@@:	;and    word ed_flags,1111111111111011b
343 Lrz 643
	call	.enable_null
391 Lrz 644
	;mov	dword	ed_shift_pos,0
348 Lrz 645
	ret
391 Lrz 646
;;;;;;;;;;;;;;;;;;;;;
647
;Установка- снятие выделения в один символ
648
;;;;;;;;;;;;;;;;;;;;;
649
.drw_sim:
650
	mov	eax,dword	ed_pos
651
	call    .draw_rectangle   ;нарисовать прямоугольник с заданным цветом
652
        jmp     @b
653
;;;;;;;;;;;;;;;;;;;;;
282 Lrz 654
 
391 Lrz 655
;;;;;;;;;;
656
;Фукция установки выделения при движения влево и вправо и нажатии shift
657
;Логика:
658
;;;;;;;;;;
659
.draw_wigwag:
660
;функция установки переменных
661
	mov	ebp,shift_color
662
	call	.clear_cursor
289 Lrz 663
 
391 Lrz 664
	or	word ed_flags,ed_shift_bac ;установка флага, выделенной области
665
	mov	ebp,shift_color
666
	mov 	eax,dword	ed_pos
667
	;mov	ebx,dword	ed_shift_pos
668
	test	word ed_flags,ed_left_fl
669
	jz      .low
670
;	sub	eax,2
671
	;dec	eax
672
	jmp	@f
673
;;;;;;;;;;
674
;Фукция удаления выделения при движения влево и вправо и нажатии shift
675
;Логика:
676
;;;;;;;;;;
677
.draw_wigwag_cl:
678
;функция установки переменных
679
	mov	ebp,ed_color
680
	call	.clear_cursor
681
 
682
	mov	ebp,ed_color
683
	mov 	eax,dword	ed_pos
684
	;mov	ebx,dword	ed_shift_pos
685
	test	word ed_flags,ed_left_fl
686
	jz      .low
687
	;dec	eax
688
@@:     call	.draw_rectangle  ;нарисовать прямоугольник закрашиваемой области
689
	ret
690
.low:   dec	eax
691
        jmp	@b
692
;входной параметр ebx - ed_pos
693
.sh_first_sh:
289 Lrz 694
	test    word ed_flags,ed_shift
695
	je	@f
391 Lrz 696
	mov	dword ed_shift_pos_old,ebx
289 Lrz 697
	test	word ed_flags,ed_shift_on
391 Lrz 698
	jne	@f
699
	mov	dword ed_shift_pos,ebx
700
       	or	word ed_flags,ed_shift_on
701
@@:    	ret
289 Lrz 702
 
391 Lrz 703
;Обработка крайних положений в editbox при нажатом shift
704
;производит снятие выделение, если нет shift
705
;иначе вообще выходит
706
.sh_st_of:
707
	test    word ed_flags,ed_shift
708
	jne	@f
709
	test    word ed_flags,ed_shift_bac
348 Lrz 710
        je      @f
391 Lrz 711
       	mov	ebp,ed_color
712
	call	.sh_cl_  ;очистка выделеного фрагмента
713
	call	.draw_wigwag_cl
714
	and	word ed_flags,ed_shift_cl ; очистка от того что убрали выделение
715
	jmp     .draw_cursor_text
716
@@:
717
     	;-----------  отладка
718
;	pushad
719
;	mov	dword [ed_buffer.3],0
720
;	mov eax,ebx;word ed_flags
721
;	mov edi,ed_buffer.3
722
;	call .str
723
;	;рисование фона
724
;	mov eax,13
725
;	mov ebx,178*65536+70
726
;	mov ecx,28*65536+10
727
;	xor edx,edx
728
;	int 0x40
729
;	;вывод значения на экран
730
;	mov eax,4
731
;	mov ebx,180*65536+30
732
;	mov ecx,0x10DDBBCC
733
;	mov edx,ed_buffer.3
734
;	mov esi,8
735
;	int 0x40
736
;	popad
737
	;----------- отладка
738
        and	word ed_flags,ed_shift_off
739
	popa
740
	ret
741
 
742
;проверка состояния shift был ли он нажат раньше?
743
.sh_enable:
744
	test    word ed_flags,ed_shift
745
	jne	.sh_ext_en ;нарисовать закрашеный прямоугольник
746
 
747
	test    word ed_flags,ed_shift_bac
748
        je      @f
749
       	call	.check_offset
750
 
348 Lrz 751
	mov	ebp,ed_color
752
	call	.sh_cl_  ;очистка выделеного фрагмента
391 Lrz 753
	call	.draw_wigwag_cl
754
	and	word ed_flags,ed_shift_cl ; 1вар не нужно
755
	ret
756
 
757
@@:     mov	ebp,ed_color
758
	call	.clear_cursor
759
	call	.check_offset
760
	ret
348 Lrz 761
.sh_ext_en:
391 Lrz 762
       	call	.check_offset
763
	test	eax,eax
764
	jnz	@f
765
;Рисование закрашеных прямоугольников и очистка их
766
        mov 	eax,dword	ed_shift_pos
767
	mov	ebx,dword	ed_pos
768
	mov	ecx,dword	ed_shift_pos_old
769
;проверка и рисование закрашеных областей
770
	cmp	eax,ecx
771
	je	.1_shem
772
	jb      .smaller
773
        cmp	ecx,ebx
774
        ja	.1_shem
775
        call	.draw_wigwag_cl ;clear
776
	jmp	.sh_e_end
777
.smaller:
778
        cmp	ecx,ebx
779
        jb	.1_shem
780
        call	.draw_wigwag_cl ;clear
781
	jmp	.sh_e_end
782
;alike  =
783
.1_shem: call	.draw_wigwag
784
.sh_e_end:	and	word ed_flags,ed_shift_off
785
	ret
786
@@:	mov	ebp,shift_color
787
	call	.sh_cl_
788
	jmp	.sh_e_end
789
;функция для обработки shift при нажатии home and end
790
.sh_home_end:
791
	mov	ebp,ed_color
792
	call	.clear_cursor
793
	test    word ed_flags,ed_shift_bac
794
        je      @f
795
	mov	ebp,ed_color
796
	call	.sh_cl_
797
 
798
@@:	test    word ed_flags,ed_shift
799
	je	.sh_exit_ ;нарисовать закрашеный прямоугольник (область)
800
    	call	.check_offset
801
        mov	ebp,shift_color
802
	call	.sh_cl_
803
	or	word ed_flags,ed_shift_bac ;установка флага, выделенной области
804
	jmp	.sh_e_end
805
.sh_exit_:	ret
806
 
807
 
808
;	test    word ed_flags,ed_shift_bac
809
;        je      @f
810
 
811
 
812
 
813
 
814
 
815
 
816
 
817
 
818
 
343 Lrz 819
;функция внесения 0 по адресу ed_size+1
820
.enable_null:
821
        pusha
822
        mov	eax,ed_size
823
	mov	ebx,ed_text
824
	add	eax,ebx
825
	inc	eax
826
	xor	ebx,ebx
827
	mov 	[eax],bl
828
	popa
829
	ret
830
 
234 Lrz 831
        ;- удаление символа
289 Lrz 832
	;Входные данные edx=ed_size;ecx=ed_pos
234 Lrz 833
.del_char:
834
	mov     esi,ed_text
289 Lrz 835
        test	word ed_flags,ed_shift_on
836
        je	@f
837
	mov	eax,dword ed_shift_pos
838
	mov	ebx,esi
839
        cmp	eax,ecx
840
	jae	.dh_n
841
 
842
	mov	ed_pos,eax	;что бы не было убегания курсора
843
	mov	ebp,ecx
844
	sub	ebp,eax
845
	add	ebx,eax  ;eax меньше
846
	sub	edx,ecx
234 Lrz 847
	add	esi,ecx
848
 
391 Lrz 849
	mov	dword ed_shift_pos,ebp
289 Lrz 850
        jmp	.del_ch_sh
851
	             ;если иначе
852
.dh_n:
853
	mov	ebp,eax
854
	sub	ebp,ecx
855
	add	ebx,ecx
856
	sub	edx,eax
857
	add	esi,eax
391 Lrz 858
	mov	dword ed_shift_pos,ebp
289 Lrz 859
	jmp	.del_ch_sh
860
 
861
@@:	add	esi,ecx ;указатель + смещение к реальному буфферу
234 Lrz 862
	mov	ebx,esi
863
	inc 	esi
864
	cld
865
 
866
	sub	edx,ecx
289 Lrz 867
.del_ch_sh:
868
 
234 Lrz 869
	push 	edi
870
	mov 	edi,ebx
871
@@:
872
	lodsb
873
	stosb
289 Lrz 874
	dec edx
234 Lrz 875
	jns @b
876
 
877
	pop edi
878
	ret
343 Lrz 879
 
880
;вычислить закрашиваемую область
881
;соглашение в ebp - передается ed_size
882
.clear_bg:
883
	call	.get_n  ;получить размер в символах ширины компонента
884
	push	eax
885
	mov	ebx,ed_offset
886
	add	eax,ebx	;eax = w_off= ed_offset+width
887
	mov	ebx,ebp ;ed_size
888
 
889
	cmp	eax,ebx
890
	jb	@f
891
	mov	eax,ed_pos
892
	sub	ebx,eax
893
	mov	ecx,ed_offset
894
	sub	eax,ecx
895
	jmp	.nxt
896
@@:	mov	ebx,ed_pos
897
	push	ebx
898
	sub	eax,ebx
899
	mov	ebx,eax	;It is don't optimal
900
 
901
	pop	eax	;ed_pos
902
       	mov	ecx,ed_offset
903
	sub	eax,ecx
904
 
905
.nxt:
906
	mov	ebp,eax  ;проверка на выход закрашиваемой области за пределы длины
907
	add	ebp,ebx
908
	pop	edx
909
	cmp	ebp,edx
910
	je	@f
911
	inc	ebx
912
 
913
@@:     mov	edx,ebx
914
	lea	ebx,[eax*2+eax]
915
	shl	ebx,1
916
	add	ebx,ed_left
917
	inc	ebx
918
	shl	ebx,16
919
	lea	ecx,[edx*2+edx]
920
	shl	ecx,1
921
	mov	bx,cx
922
	mov	edx,ed_color
923
	call	.draw_bg_eax
924
	ret
391 Lrz 925
;;;;;;;;;;;;;;;;;;;
926
;;; Обработка примитивов
927
;;;;;;;;;;;;;;;;;;;;
928
;Нарисовать прямоугольник, цвет передается в ebp
929
;входные параметры:
930
;eax=dword ed_pos
931
;ebp=-цвет ed_color or shift_color
932
.draw_rectangle:
933
;        mov	eax,dword ed_pos
934
	mov	ecx,dword ed_offset
935
	sub     eax,ecx
936
        lea	ebx,[eax*2+eax]
937
	shl	ebx,1
938
	inc	ebx
939
	add	ebx,ed_left
940
	shl	ebx,16
941
	mov	bx,6
942
	mov	edx,ebp
943
	call	.draw_bg_eax
944
	ret
234 Lrz 945
;==========================================================
946
;=== обработка мыши =======================================
947
;==========================================================
948
.mouse:
949
pusha
950
;----------------------------------------------------------
951
;--- получаем состояние кнопок мыши -----------------------
952
;----------------------------------------------------------
953
	mov	eax,37
954
	mov	ebx,2
955
	int	0x40
956
;----------------------------------------------------------
957
;--- проверяем состояние ----------------------------------
958
;----------------------------------------------------------
959
	test	eax,1
960
	jnz	.mouse_left_button
348 Lrz 961
	popa
234 Lrz 962
	ret
963
 
964
.mouse_left_button:
965
;----------------------------------------------------------
966
;--- получаем координаты мыши -----------------------------
967
;----------------------------------------------------------
968
	mov	eax,37
969
	xor	ebx,ebx
970
	inc	ebx
971
	int	0x40
972
;----------------------------------------------------------
973
;--- проверяем, попадает ли курсор в edit box -------------
974
;----------------------------------------------------------
975
	mov	ebx,ed_top
976
	cmp	ax,bx
977
	jl	._blur;.mouse_end_no_focus
978
 
979
	add	bx,ed_height
980
	cmp	ax,bx
981
	jg	._blur;.mouse_end_no_focus
982
 
983
	shr	eax,16
984
 
985
	mov	bx,ed_left
986
	cmp	ax,bx
987
	jl	._blur;.mouse_end_no_focus
988
 
989
	add	bx,ed_width
990
	cmp	ax,bx
991
	jg	._blur;.mouse_end_no_focus
992
;--- изменяем позицию курсора ---
993
	push	eax
391 Lrz 994
	mov	ebp,ed_color
234 Lrz 995
	call	.clear_cursor
996
	pop	eax
997
	xor	dx,dx
998
	sub	ax,ed_left
999
	add	ax,2
1000
	mov	bx,6
1001
	div	bx
1002
	add	ax,ed_offset
1003
	cmp	ax,ed_size
1004
	jna	 @f
1005
	mov	ax,ed_size
1006
@@:
1007
	mov	ed_pos,ax
1008
	call	.check_offset
1009
	call	.draw_cursor
292 Lrz 1010
;----------------------------------------------------------
1011
;--- процедура установки фокуса ---------------------------
1012
;----------------------------------------------------------
1013
	bts	word ed_flags,1
348 Lrz 1014
	jc	@f
292 Lrz 1015
	call	.draw_cursor
348 Lrz 1016
	jmp	.drc
1017
 
1018
 
234 Lrz 1019
._blur:
306 Lrz 1020
	test	word ed_flags,ed_always_focus
1021
	jne	@f
292 Lrz 1022
	btr	word ed_flags,1 ; если не в фокусе, выходим
1023
	jnc     @f
391 Lrz 1024
	mov	ebp,ed_color
234 Lrz 1025
	call	.clear_cursor
348 Lrz 1026
.drc:	call	.draw_border
234 Lrz 1027
@@:
1028
popa
1029
ret
1030
 
1031
;----------------------------------------------------------
1032
;--- процедура размывания фокуса --------------------------
1033
;----------------------------------------------------------
1034
;.blur:
1035
;pusha
1036
;._blur:
1037
	;btr     ed_flags,1
1038
	;jnc     @f
1039
	;call    .draw_border
1040
	;call    .clear_cursor
1041
;@@:
1042
;popa
1043
;ret
1044
}
391 Lrz 1045
ed_figure_only= 1000000000000000b
1046
ed_always_focus= 100000000000000b
234 Lrz 1047
ed_focus=10b
391 Lrz 1048
ed_shift_on=                1000b   ;если не установлен -значит впервые нажат shift,если был установлен, значит мы уже что - то делали удерживая shift
1049
ed_shift=                    100b   ;включается при нажатии на shift т.е. если нажимаю
1050
ed_shift_off=   1111111111111011b
1051
ed_shift_bac=              10000b   ;бит для очистки выделеного shift т.е. при установке говорит что есть выделение
1052
ed_shift_cl=    1111111111100011b
1053
ed_left_fl=               100000b
1054
ed_right_fl=    1111111111011111b
1055
ed_insert=              10000000b
1056
ed_insert_cl=   1111111101111111b
1057
ed_height=14 ; высота
1058
shift_color=0x6a9480
234 Lrz 1059
macro draw_edit_boxes start,end
1060
{
1061
	mov	edi,start
1062
	mov	ecx,((end-start)/ed_struc_size)
1063
@@:
1064
	call	edit_box.draw
1065
	add	edi,ed_struc_size
1066
	loop	@b
1067
}
1068
 
1069
macro mouse_edit_boxes start,end
1070
{
1071
	mov	edi,start
1072
	mov	ecx,((end-start)/ed_struc_size)
1073
@@:
1074
	call	edit_box.mouse
1075
	add	edi,ed_struc_size
1076
	loop	@b
1077
}
1078
 
1079
macro key_edit_boxes start,end
1080
{
1081
	mov	edi,start
1082
	mov	ecx,((end-start)/ed_struc_size)
1083
@@:
1084
	call	edit_box.key
1085
	add	edi,ed_struc_size
1086
	loop	@b
1087
}
391 Lrz 1088
ed_struc_size=66
234 Lrz 1089
struc  edit_box width,left,top,color,focus_border_color,\
1090
       blur_border_color,text_color,max,text,flags,size
1091
{
1092
.width dd width
1093
.left dd left
1094
.top dd top
1095
.color dd color
1096
.focus_border_color dd focus_border_color
1097
.blur_border_color dd blur_border_color
1098
.text_color dd text_color
1099
.max dd max
282 Lrz 1100
.text dd text
1101
.flags dw flags+0
234 Lrz 1102
.size dd size+0
1103
.pos dd 0
1104
.offset dd 0
1105
.cl_curs_x dd 0
1106
.cl_curs_y dd 0
391 Lrz 1107
.shift   dd 0
1108
.shift_old   dd 0
234 Lrz 1109
}
1110
 
1111
macro edit_boxes_set_sys_color start,end,color_table
1112
{
1113
	mov	edi,start
1114
	mov	ecx,((end-start)/ed_struc_size)
1115
	mov	esi,color_table
1116
@@:
1117
	mov	eax,[esi+36]
1118
	mov	ebx,[esi+20]
1119
	mov	ed_focus_border_color,eax
1120
	shr	bh,1
1121
	shr	bl,1
1122
	shr	ah,1
1123
	shr	al,1
1124
	add	ah,bh
1125
	add	al,bl
1126
	ror	eax,16
1127
	ror	ebx,16
1128
	shr	bl,1
1129
	shr	al,1
1130
	add	al,bl
1131
	ror	eax,16
1132
	mov	ed_blur_border_color,eax
1133
	add	edi,ed_struc_size
1134
	loop	@b
306 Lrz 1135
}
1136
 
1137
macro draw_edit_box ed_ptr
1138
{
1139
        mov     edi,ed_ptr
1140
        call    edit_box.draw
1141
}
1142
 
1143
macro mouse_edit_box ed_ptr
1144
{
1145
        mov     edi,ed_ptr
1146
        call    edit_box.mouse
1147
}
1148
 
1149
macro key_edit_box ed_ptr
1150
{
1151
        mov     edi,ed_ptr
1152
        call    edit_box.key
234 Lrz 1153
}