Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
234 Lrz 1
;  12.12.2006 реализовал поддержку кнопки insert и сегодя компонент почти работает!!!!
2
;  07.12.2006 продолжается работа над переработкой компонента,изменениям подверглись многие функции, переработан вывод текста, а така же алгоритм внесения символов.
3
;  03.09.2006 по возможности отказался от 16 битной арифметики, добавил новые баги
4
;  09.08.2006 произведена оптимизация работы конпок DEL и Backspace, уменьшен размер выполняемого кода.
5
;  21.07.2006 добавлена функция кнопки Del, теперь можно удалять символы при помощи данной клавиши
6
; Автор: Евтихов Максим (Maxxxx32) email: maxxxxm@mail.ru
7
; Дата последних изменений: 13.06.06 10:40
8
;  Напишите в исходном коде своей программы use_edit_box,
9
; это вставит необходимые процедуры в код вашей программы.
10
;  Процедуры:
11
;   edit_box.draw - полная перерисовка;
12
;   edit_box.key - обработка клавиатуры;
13
;   edit_box.mouse - обработка мыши;
14
;   edit_box.focus - установка фокуса;
15
;   edit_box.blur - его размывание;
16
;   edit_box.get_n - получить количество прорисовываемых символов.
17
;  При вызове любых из этих процедур в регистре edi следует
18
; оставить указатель на структуру.
19
;  Пример структуры:
20
; some_edit edit_box 100,10,30,0x00ffffff,0,0x00aaaaaa,0,255,some_edit_text
21
; длина, высота, верх, цвет фона, цвет рамки, если выбран,
22
; цвет рамки, если не выбран, максимальное количество символов,
23
; указатель на буфер, где будут хранится символы. Буфер должен
24
; оканчиваться нулем, например если максимальное количество 255:
25
;  some_edit_text:
26
;       rb      256 ;255+1
27
 
28
;  Пример вызова процедуры:
29
;       mov     edi,some_edit
30
;       call    edit_box.draw
31
 
32
;  При вызове процедуры edit_box.key код клавиши должен
33
; находится в ah, то есть перед вызовом этой процедуры надо вызвать
34
; 2-ую сисемную функцию, например:
35
;       mov     eax,2
36
;       int     0x40
37
;       mov     edi,some_edit1
38
;       call    edit_box.key
39
;       mov     edi,some_edit2
40
;       call    edit_box.key
41
;  Перед вызовом обработчика мыши следует проверить, является ли окно
42
; активным.
43
;  Если щелчок мыши был пройзведен за пределами edit box
44
; фокус теряется.
45
macro use_edit_box
46
{
47
edit_box:
48
ed_width	equ [edi]		;ширина компонента
49
ed_left 	equ [edi+4]             ;положение по оси х
50
ed_top		equ [edi+8]             ;положение по оси у
51
ed_color	equ [edi+12]		;цвет фона компонента
52
ed_focus_border_color	equ [edi+16]	;цвет рамки компонента
53
ed_blur_border_color	equ [edi+20]    ;цвет не активного компонента
54
ed_text_color	equ [edi+24]            ;цвет текста
55
ed_flags	equ [edi+28]            ;флаги
56
ed_max	equ [edi+32]                    ;кол-во символов которые можно максимально ввести
57
ed_size equ [edi+36]                    ;кол-во символов
58
ed_pos	equ [edi+40]                    ;позиция курсора
59
ed_offset	equ [edi+44]            ;смещение
60
ed_text equ [edi+48]                    ;указатель на буфер
61
cl_curs_x	equ [edi+52]		;предыдущее координата курсора по х
62
cl_curs_y	equ [edi+56]		;предыдущее координата курсора по у
63
ed_insert	equ [edi+60]		;word
64
ed_height=14 ; высота
65
;==========================================================
66
;=== процедура прорисовки =================================
67
;==========================================================
68
.draw:
69
pusha
70
;--- рисуем рамку ---
71
	call	.draw_border		; Функция стабильна
72
.draw_bg_cursor_text:
73
;--- изменяем смещение, если надо ---
74
	call	.check_offset		;вычисление позиции курсора стабильна
75
;--- рисуем внутреннюю область ---
76
	call	.draw_bg                ;нарисовать прямоугольник рабочей области
77
.draw_cursor_text:
78
;--- рисуем курсор ---
79
	;--- может его не надо рисовать ----
80
	test	dword ed_flags,1
81
	je	@f
82
	call	.draw_cursor
83
@@:
84
	call	.draw_text
85
popa
86
ret
87
 
88
;----------------------------------------------------------
89
;--- процедура прорисовки текста --------------------------
90
;----------------------------------------------------------
91
.draw_text:
92
;--- вычисляем, сколько помещается символов ---
93
;--- чтобы мусор не рисовать ---
94
	call 	.get_n
95
	mov	esi,ed_size
96
        mov	ebx,ed_offset
97
	sub	esi,ebx
98
	cmp	eax,esi
99
	jae	@F
100
	mov	esi,eax		;чтобы не выходить за пределы экрана
101
;--- рисуем текст ---
102
@@: 	mov	eax,4
103
	mov	ebx,ed_left
104
	add	ebx,2
105
	shl	ebx,16
106
	mov	bx,ed_top
107
	add	ebx,4
108
	mov	ecx,ed_text_color
109
	mov	edx,ed_offset
110
	add	edx,ed_text
111
	int	0x40
112
ret
113
;----------------------------------------------------------
114
;--- процедура прорисовки фона ----------------------------
115
;входные данные
116
;eax
117
;----------------------------------------------------------
118
.draw_bg_eax:
119
pusha
120
	mov	ecx,ed_top
121
	add	ecx,1
122
	shl	ecx,16
123
	mov	cx,13
124
;	sub	ecx,1
125
 
126
	mov	edx,ed_color
127
	mov	eax,13
128
	int	0x40
129
popa
130
ret
131
 
132
	jmp	@f
133
.draw_bg:
134
pusha
135
	mov	ebx,ed_left
136
	add	ebx,1
137
	shl	ebx,16
138
	mov	bx,ed_width
139
	sub	ebx,1
140
 
141
@@:
142
	mov	ecx,ed_top
143
	add	ecx,1
144
	shl	ecx,16
145
	mov	cx,ed_height
146
	sub	ecx,1
147
 
148
	mov	edx,ed_color
149
	mov	eax,13
150
	int	0x40
151
popa
152
ret
153
 
154
;----------------------------------------------------------
155
;--- процедура получения количества символов в текущей щирине компонента --------------
156
;----------------------------------------------------------
157
.get_n:
158
	xor	edx,edx   ;результат распологается в паре edx:eax в eax - остаток
159
	mov	eax,ed_width	;получем ширину компонента
160
	sub	eax,4		;вычтим 4
161
	mov	ebx,6		;загрузми делитель
162
	div	ebx		;размделим на 6
163
ret
164
 
165
;----------------------------------------------------------
166
;--- процедура рисования курсора --------------------------
167
;----------------------------------------------------------
168
.clear_cursor:
169
	mov	edx,ed_color
170
	mov	ebx,cl_curs_x
171
	mov	ecx,cl_curs_y
172
	jmp	.draw_curs
173
.draw_cursor:
174
	mov	edx,ed_text_color
175
@@:
176
	mov	ebx,ed_pos
177
	mov	ecx,ed_offset
178
	sub	ebx,ecx
179
 
180
	lea     ebx,[ebx*2+ebx]
181
	shl     ebx,1
182
	;imul	ebx,6
183
	add	bx,ed_left
184
	inc	ebx
185
	mov	ebp,ebx
186
	;push	bx
187
	shl	ebx,16
188
	mov	bx,bp
189
	;pop	bx
190
	mov	ecx,ed_top
191
	add	ecx,2
192
	mov	ebp,ecx
193
 
194
	shl	ecx,16
195
	mov	cx,bp
196
	add	cx,ed_height-4
197
 
198
	mov	cl_curs_x,ebx
199
	mov	cl_curs_y,ecx
200
.draw_curs:
201
	mov	eax,38
202
	int	0x40
203
ret
204
 
205
;----------------------------------------------------------
206
;--- процедура рисования рамки ----------------------------
207
;----------------------------------------------------------
208
.draw_border:
209
;--- цвет рамки ---
210
	test	dword ed_flags,1
211
	mov	edx,ed_focus_border_color
212
	jne     @f
213
	mov	edx,ed_blur_border_color
214
@@:
215
;--- сверху ---
216
	mov	eax,38
217
	mov	ebx,ed_left
218
	mov 	ecx,ebx
219
	shl	ebx,16
220
	mov	bx,cx
221
	add	bx,ed_width
222
	mov	ecx, ed_top
223
	mov	esi,ecx
224
	shl	ecx,16
225
	mov	cx,si
226
	int	0x40
227
 
228
;--- снизу ---
229
	mov	esi,ecx
230
	add	ecx,ed_height
231
	mov	ebp,ecx
232
	shl	ecx,16
233
	mov	cx,bp
234
	int	0x40
235
 
236
;--- слева ---
237
	mov	cx,si
238
	mov	ebp,ebx
239
	sub	bx,ed_width
240
	int	0x40
241
 
242
;--- справа ---
243
	mov	ebx,ebp
244
	shl	ebx,16
245
	mov	bx,bp
246
	int	0x40
247
ret
248
;----------------------------------------------------------
249
;--- проверка, зашел ли курсор за границы и, если надо, ---
250
;--- изменяем смещение ------------------------------------
251
;--- eax = 1, если не изменилось или eax = 0, если
252
; изменилось
253
;----------------------------------------------------------
254
.check_offset:
255
	pushad
256
	push	dword ed_offset          ;сохраним смещение
257
	call	.get_n			;получим кол-во символов в паре регистров edx:eax
258
	mov	ebx,eax
259
	mov	eax,ed_pos
260
	xor 	edx,edx
261
	idiv	ebx
262
	xor 	edx,edx
263
	imul    eax,ebx
264
	mov	ed_offset,eax
265
	pop	ebx
266
	cmp	ax,bx
267
	je	@f
268
;;;;;;;; данные для закрашивания всей полосы прямоугольника
269
	mov	ebx,ed_left
270
	inc	ebx
271
	shl	ebx,16
272
	mov	bx,ed_width
273
	dec 	ebx
274
	call    .draw_bg_eax
275
	mov	dword [esp+28],0
276
@@:	popad
277
	ret
278
;==========================================================
279
;=== обработка клавиатуры =================================
280
;==========================================================
281
.key:
282
pusha
283
	test	dword ed_flags,1 ; если не в фокусе, выходим
284
	je     .no_figure ;@f
285
;----------------------------------------------------------
286
;--- проверяем, что нажато --------------------------------
287
;----------------------------------------------------------
288
	cmp	ah,8
289
	jz	.backspace
290
	cmp	ah,0xb6
291
	jz	.delete
292
	cmp	ah,176
293
	jz	.left
294
	cmp	ah,179
295
	jz	.right
296
	cmp	ah,180
297
	jz	.home
298
	cmp	ah,181
299
	jz	.end
300
	cmp	ah,185	;insert
301
	jz	.insert
302
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
303
;Заглушка на обработку клавиш вверх и вниз
304
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
305
	cmp	ah,177
306
        jz	.no_figure
307
	cmp	ah,178
308
	jz	.no_figure
309
	cmp	ah,27   ;ESC - клавиша ))
310
	jz	.no_figure
311
;--- нажата другая клавиша ---
312
	test	word ed_flags,ed_figure_only  ; только цифры ?
313
	jz	@f
314
	cmp	ah,'0'
315
	jb	.no_figure
316
	cmp	ah,'9'
317
	ja	.no_figure
318
@@:        ; проверяем, находится ли курсор в конце
319
	mov	edx, ed_max
320
	mov	ebx, ed_pos
321
	cmp	ebx,edx
322
	jl	@f ; если меньше или равно
323
.no_figure:
324
	popa
325
	ret
326
.insert: not 	word ed_insert
327
        jmp	.no_figure
328
.ins_v:
329
	pop	eax edi
330
	dec	dword ed_size    ;processing is insert
331
	push	edi eax
332
	sub	esi,ecx
333
	add	esi,ebx
334
        mov	edi,esi
335
	jmp	.In_k
336
@@:     ; сдвигаем символы после курсора вправо
337
	mov	ecx,ed_size
338
	push	edi eax
339
	mov	esi,ed_text     ; Указатель на буфер
340
 
341
	movzx	eax,word ed_insert
342
				;Будем работать со строкой
343
	add	esi,ecx		;add ed_size добавим max size
344
	mov	edi,esi
345
 
346
       	cmp 	ecx,ebx         ;Если у нас позиция курсора = текущему размеру напечатанных символов т.е. курсор стоит в конце
347
	je	.In_k
348
	cmp	ax,-1 ;IF insert is enable
349
	je	.ins_v
350
 
351
	sub	ecx,ebx         ;Найдем кол-во символов для передвижения.
352
	inc	edi		;Сместим наши символы в право
353
	std
354
	inc 	ecx
355
   @@:
356
	;--------
357
	lodsb
358
	stosb
359
	;--------
360
	loop	@b
361
.In_k:	cld
362
	pop eax
363
	mov al,ah
364
	stosb
365
	pop edi
366
; вставляем код клавиши туда, где курсор
367
	; увеличиваем значение размера и позиции
368
	inc	 dword ed_size
369
	call	.draw_all2
370
	inc	 dword ed_pos
371
	jmp    .draw_cursor_text
372
.delete:
373
	mov	edx,ed_size
374
	mov	ecx,ed_pos
375
 
376
	cmp	edx,ecx
377
	jg	@f
378
	popa
379
	ret
380
 
381
@@:	call 	.del_char
382
	jmp 	.draw_all
383
 
384
;--- нажата клавиша backspace ---
385
.backspace:
386
	; проверяем, курсор у левого края ?
387
	mov	edx,ed_size
388
	mov	ecx,ed_pos
389
	test	ecx,ecx
390
	jnz	@f
391
	popa
392
	ret
393
 
394
@@:	cmp	edx,ecx	;if ed_pos=ed_size
395
	je	@f
396
	dec	ecx
397
	call 	.del_char
398
@@:
399
	dec	 dword ed_pos
400
 
401
.draw_all:
402
;	mov	eax,.draw_cursor_text
403
	push	.draw_cursor_text;eax
404
	dec	 dword ed_size
405
.draw_all2:
406
	call	.clear_cursor
407
	call	.check_offset
408
	call	.get_n
409
	push	eax
410
	mov	ebx,ed_offset
411
	add	eax,ebx	;eax = w_off= ed_offset+width
412
	mov	ebx,ed_size
413
 
414
	cmp	eax,ebx
415
	jb	@f
416
	mov	eax,ed_pos
417
	sub	ebx,eax
418
	mov	ecx,ed_offset
419
	sub	eax,ecx
420
	jmp	.nxt
421
@@:	mov	ebx,ed_pos
422
	push	ebx
423
	sub	eax,ebx
424
	mov	ebx,eax	;don't optimal
425
 
426
	pop	eax	;ed_pos
427
       	mov	ecx,ed_offset
428
	sub	eax,ecx
429
 
430
.nxt:
431
	mov	ebp,eax  ;проверка на выход закрашиваемой области за пределы длины
432
	add	ebp,ebx
433
	pop	edx
434
	cmp	ebp,edx
435
	je	@f
436
	inc	ebx
437
 
438
@@:     mov	edx,ebx
439
	lea	ebx,[eax*2+eax]
440
	shl	ebx,1
441
	add	ebx,ed_left
442
	inc	ebx
443
	shl	ebx,16
444
	lea	ecx,[edx*2+edx]
445
	shl	ecx,1
446
	mov	bx,cx
447
	call	.draw_bg_eax
448
	ret
449
;--- нажата клавиша left ---
450
.left:
451
	mov	ebx,ed_pos
452
	test	ebx,ebx
453
	jz	.nd_k
454
	call	.clear_cursor
455
	dec	 dword ed_pos
456
	jmp	.nd_k
457
;--- нажата клавиша right ---
458
.right:
459
	mov	ebx,ed_pos
460
	cmp	ebx,ed_size
461
	je	.nd_k
462
	call	.clear_cursor
463
	inc	dword  ed_pos
464
	jmp	.nd_k
465
.home:
466
	mov	ebx,ed_pos
467
	test	ebx,ebx
468
	jz	.nd_k
469
	call	.clear_cursor
470
	xor	eax,eax
471
	mov	ed_pos,eax
472
	jmp	.nd_k
473
 
474
.end:
475
	mov	ebx,ed_pos
476
	cmp	ebx,dword ed_size
477
	je	@f
478
	call	.clear_cursor
479
	mov	eax,ed_size
480
	mov	ed_pos,eax
481
.nd_k:	call	.check_offset
482
	test	eax,eax
483
	jz	.draw_bg_cursor_text
484
	call	.draw_cursor
485
@@:
486
popa
487
ret
488
        ;- удаление символа
489
.del_char:
490
	mov     esi,ed_text
491
	add	esi,ecx
492
 
493
	mov	ebx,esi
494
	inc 	esi
495
	cld
496
 
497
	sub	edx,ecx
498
	mov	ecx,edx
499
	push 	edi
500
	mov 	edi,ebx
501
@@:
502
	lodsb
503
	stosb
504
	dec ecx
505
	jns @b
506
 
507
	pop edi
508
	ret
509
;==========================================================
510
;=== обработка мыши =======================================
511
;==========================================================
512
.mouse:
513
pusha
514
;----------------------------------------------------------
515
;--- получаем состояние кнопок мыши -----------------------
516
;----------------------------------------------------------
517
	mov	eax,37
518
	mov	ebx,2
519
	int	0x40
520
;----------------------------------------------------------
521
;--- проверяем состояние ----------------------------------
522
;----------------------------------------------------------
523
	test	eax,1
524
	jnz	.mouse_left_button
525
;	or	eax,1
526
;	jc	@f
527
;	btr	dword ed_flags,2
528
@@:     popa
529
	ret
530
 
531
.mouse_left_button:
532
;----------------------------------------------------------
533
;--- получаем координаты мыши -----------------------------
534
;----------------------------------------------------------
535
	mov	eax,37
536
	xor	ebx,ebx
537
	inc	ebx
538
	int	0x40
539
;----------------------------------------------------------
540
;--- проверяем, попадает ли курсор в edit box -------------
541
;----------------------------------------------------------
542
	mov	ebx,ed_top
543
	cmp	ax,bx
544
	jl	._blur;.mouse_end_no_focus
545
 
546
	add	bx,ed_height
547
	cmp	ax,bx
548
	jg	._blur;.mouse_end_no_focus
549
 
550
	shr	eax,16
551
 
552
	mov	bx,ed_left
553
	cmp	ax,bx
554
	jl	._blur;.mouse_end_no_focus
555
 
556
	add	bx,ed_width
557
	cmp	ax,bx
558
	jg	._blur;.mouse_end_no_focus
559
;--- изменяем позицию курсора ---
560
	push	eax
561
	call	.clear_cursor
562
	pop	eax
563
	xor	dx,dx
564
	sub	ax,ed_left
565
	add	ax,2
566
	mov	bx,6
567
	div	bx
568
	add	ax,ed_offset
569
	cmp	ax,ed_size
570
	jna	 @f
571
	mov	ax,ed_size
572
@@:
573
	mov	ed_pos,ax
574
	call	.check_offset
575
;	test	eax,eax
576
;	jz	.draw_bg_cursor_text
577
	call	.draw_cursor
578
 
579
	call	.focus
580
 
581
.mouse_pressed:
582
popa
583
ret
584
;.mouse_end_no_focus:
585
;        call    .blur
586
;popa
587
;ret
588
;----------------------------------------------------------
589
;--- процедура установки фокуса ---------------------------
590
;----------------------------------------------------------
591
.blur:
592
pusha
593
._blur:
594
	btr	dword ed_flags,0
595
	jnc	@f
596
	call	.clear_cursor
597
	jmp	.blur_end
598
.focus:
599
pusha
600
	bts	dword ed_flags,0
601
	jc	@f
602
	call	.draw_cursor
603
.blur_end:
604
	call	.draw_border
605
@@:
606
popa
607
ret
608
 
609
;----------------------------------------------------------
610
;--- процедура размывания фокуса --------------------------
611
;----------------------------------------------------------
612
;.blur:
613
;pusha
614
;._blur:
615
	;btr     ed_flags,1
616
	;jnc     @f
617
	;call    .draw_border
618
	;call    .clear_cursor
619
;@@:
620
;popa
621
;ret
622
}
623
ed_figure_only=1000000000000000b
624
ed_focus=10b
625
macro draw_edit_boxes start,end
626
{
627
	mov	edi,start
628
	mov	ecx,((end-start)/ed_struc_size)
629
@@:
630
	call	edit_box.draw
631
	add	edi,ed_struc_size
632
	loop	@b
633
}
634
 
635
macro mouse_edit_boxes start,end
636
{
637
	mov	edi,start
638
	mov	ecx,((end-start)/ed_struc_size)
639
@@:
640
	call	edit_box.mouse
641
	add	edi,ed_struc_size
642
	loop	@b
643
}
644
 
645
macro key_edit_boxes start,end
646
{
647
	mov	edi,start
648
	mov	ecx,((end-start)/ed_struc_size)
649
@@:
650
	call	edit_box.key
651
	add	edi,ed_struc_size
652
	loop	@b
653
}
654
ed_struc_size=62
655
struc  edit_box width,left,top,color,focus_border_color,\
656
       blur_border_color,text_color,max,text,flags,size
657
{
658
.width dd width
659
.left dd left
660
.top dd top
661
.color dd color
662
.focus_border_color dd focus_border_color
663
.blur_border_color dd blur_border_color
664
.text_color dd text_color
665
.flags dd flags+0
666
.max dd max
667
.size dd size+0
668
.pos dd 0
669
.offset dd 0
670
.text dd text
671
.cl_curs_x dd 0
672
.cl_curs_y dd 0
673
.insert	   dw 0
674
}
675
 
676
macro edit_boxes_set_sys_color start,end,color_table
677
{
678
	mov	edi,start
679
	mov	ecx,((end-start)/ed_struc_size)
680
	mov	esi,color_table
681
@@:
682
	mov	eax,[esi+36]
683
	mov	ebx,[esi+20]
684
	mov	ed_focus_border_color,eax
685
	shr	bh,1
686
	shr	bl,1
687
	shr	ah,1
688
	shr	al,1
689
	add	ah,bh
690
	add	al,bl
691
	ror	eax,16
692
	ror	ebx,16
693
	shr	bl,1
694
	shr	al,1
695
	add	al,bl
696
	ror	eax,16
697
	mov	ed_blur_border_color,eax
698
	add	edi,ed_struc_size
699
	loop	@b
700
}