Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
5911 IgorA 1
; макрос для системной библиотеки box_lib.obj
2
; элемент TreeList для Kolibri OS
5948 IgorA 3
; файл последний раз изменялся 03.12.2015 IgorA
5911 IgorA 4
; на код применена GPL2 лицензия
1277 IgorA 5
 
6
 
7
sizeof.TreeList equ 20
1283 IgorA 8
;struct TreeList
5911 IgorA 9
;  type dw ? ;+ 0 тип элемента, или индекс иконки для узла
10
;  lev db ?  ;+ 2 уровень элемента
11
;  clo db ?  ;+ 3 флаг закрытия, или открытия (имеет смысл для родительского узла)
12
;  perv dd ? ;+ 4 индекс предыдущего элемента
13
;  next dd ? ;+ 8 индекс последующего элемента
14
;  tc dd ?   ;+12 врем. создания
15
;  td dd ?   ;+16 врем. удаления
1283 IgorA 16
;ends
1277 IgorA 17
 
1382 diamond 18
macro use_tree_list
19
{
5879 IgorA 20
 
5911 IgorA 21
;выделние памяти для структур списка и основной информации (конструктор)
1277 IgorA 22
align 4
5879 IgorA 23
proc tl_data_init uses eax ecx edi, tlist:dword
24
	mov edi,dword[tlist]
1277 IgorA 25
 
5879 IgorA 26
	xor ecx,ecx
27
	mov cx,tl_info_size
28
	imul ecx,tl_info_max_count
29
	invoke mem.alloc,ecx
5911 IgorA 30
	mov tl_data_info,eax ;копируем указатель на полученую память в структуру
31
	mov tl_data_img,0  ;обнуляем указатель 'data_img'
32
	mov tl_data_img_sys,0 ;обнуляем указатель 'data_img_sys'
1277 IgorA 33
 
5879 IgorA 34
	mov ecx,sizeof.TreeList
35
	imul ecx,tl_info_max_count
36
	invoke mem.alloc,ecx
5911 IgorA 37
	mov tl_data_nodes,eax ;копируем указатель на полученую память в структуру
1277 IgorA 38
 
5879 IgorA 39
	stdcall tl_info_clear, edi
1277 IgorA 40
 
5911 IgorA 41
	;настройки дочернего скроллинга
42
	cmp tl_p_scroll,0
5879 IgorA 43
	je @f
5911 IgorA 44
		mov eax,tl_p_scroll
45
		;*** цветовые настройки ***
5879 IgorA 46
		mov ecx,tl_col_bkg
47
		mov dword[eax+sb_offs_bckg_col],ecx
48
		mov ecx,tl_col_zag
49
		mov dword[eax+sb_offs_frnt_col],ecx
50
		mov ecx,tl_col_txt
51
		mov dword[eax+sb_offs_line_col],ecx
5911 IgorA 52
		;*** настройки размеров ***
5879 IgorA 53
		mov ecx,tl_box_left
54
		add ecx,tl_box_width
55
		mov word[eax+2],cx
56
		mov ecx,tl_box_height
57
		mov word[eax+4],cx
58
		mov ecx,tl_box_top
59
		mov word[eax+6],cx
60
	@@:
61
	ret
62
endp
1277 IgorA 63
 
5911 IgorA 64
;очистка памяти элемента (деструктор)
1277 IgorA 65
align 4
5948 IgorA 66
proc tl_data_clear uses eax edi, tlist:dword
1464 IgorA 67
	mov edi,dword[tlist]
68
	cmp tl_data_img,0
69
	je @f
5911 IgorA 70
		invoke mem.free,tl_data_img ;чистка системных иконок
1464 IgorA 71
	@@:
72
	cmp tl_data_img_sys,0
73
	je @f
5911 IgorA 74
		invoke mem.free,tl_data_img_sys ;чистка системных иконок
1464 IgorA 75
	@@:
5879 IgorA 76
	invoke mem.free,tl_data_info
1489 IgorA 77
	invoke mem.free,tl_data_nodes
1464 IgorA 78
	ret
79
endp
1277 IgorA 80
 
5911 IgorA 81
;очистка списка (информации)
1277 IgorA 82
align 4
5879 IgorA 83
proc tl_info_clear uses eax ecx edi, tlist:dword
84
	mov edi,dword[tlist]
85
	mov tl_ch_tim,0
86
	mov tl_tim_undo,0
87
	mov tl_cur_pos,0
88
	mov ecx,sizeof.TreeList
89
	imul ecx,tl_info_max_count
90
	mov eax,tl_data_nodes
91
	@@:
5911 IgorA 92
		mov byte[eax],0 ;чистим узлы 0-ми
5879 IgorA 93
		inc eax
94
		loop @b
5911 IgorA 95
	mov eax,tl_data_nodes ;указатель на 0-й узел
96
	mov dword[eax+8],1 ;указатель next в 0-м узле приравниваем к 1
1303 IgorA 97
 
5911 IgorA 98
	cmp tl_p_scroll,0 ;обработка скроллинга
5879 IgorA 99
	je @f
5911 IgorA 100
		mov eax,tl_p_scroll
5879 IgorA 101
		mov dword[eax+sb_offs_position],0
102
		call tb_scrol_resize
103
	@@:
104
	ret
105
endp
1277 IgorA 106
 
5911 IgorA 107
;реакция на клавиатуру
1277 IgorA 108
align 4
5879 IgorA 109
proc tl_key uses ebx ecx edi, tlist:dword
110
	mov edi,dword[tlist]
1277 IgorA 111
 
5879 IgorA 112
	mov ebx,tl_el_focus
113
	cmp dword[ebx],edi
5911 IgorA 114
	jne .no_focus ;элемент не в фокусе
1277 IgorA 115
 
5879 IgorA 116
	push eax
5911 IgorA 117
	mcall 66,2 ;получить режим ввода с клавиатуры
1303 IgorA 118
 
5879 IgorA 119
	lea ecx,[tl_key_scan]
5911 IgorA 120
	cmp eax,1 ;1 = сканкоды
5879 IgorA 121
	je @f
122
		lea ecx,[tl_key_ascii]
123
	@@:
124
	pop eax
1303 IgorA 125
 
5879 IgorA 126
	xor bx,bx
127
	cmp ah,byte[ecx] ;Enter
128
	jne @f
129
	cmp tl_on_press,0
130
	je @f
5948 IgorA 131
		call tl_on_press
5879 IgorA 132
	@@:
133
	cmp ah,byte[ecx+1] ;Space
134
	jne @f
135
		stdcall tl_node_close_open, edi
136
	@@:
137
	cmp ah,byte[ecx+2] ;Up
138
	jne @f
139
		stdcall tl_cur_perv, edi
140
	@@:
141
	cmp ah,byte[ecx+3] ;Down
142
	jne @f
143
		stdcall tl_cur_next, edi
144
	@@:
145
	cmp ah,byte[ecx+7] ;Page Up
146
	jne @f
147
		stdcall tl_cur_page_up, edi
148
	@@:
149
	cmp ah,byte[ecx+8] ;Page Down
150
	jne @f
151
		stdcall tl_cur_page_down, edi
152
	@@:
1277 IgorA 153
 
5879 IgorA 154
	bt tl_style,0 ;tl_key_no_edit
155
	jc .no_edit
156
		cmp ah,byte[ecx+4] ;Left
157
		jne @f
158
			stdcall tl_node_lev_dec, edi
159
			mov bx,1
160
		@@:
161
		cmp ah,byte[ecx+5] ;Right
162
		jne @f
163
			stdcall tl_node_lev_inc, edi
164
			mov bx,1
165
		@@:
166
		cmp ah,byte[ecx+6] ;Delete
167
		jne @f
168
			stdcall tl_node_delete, edi
169
			mov bx,1
170
		@@:
171
	.no_edit:
1277 IgorA 172
 
5879 IgorA 173
	cmp bx,1
174
	jne .no_focus
175
		stdcall tl_draw, edi
176
	.no_focus:
177
	ret
178
endp
1277 IgorA 179
 
5911 IgorA 180
;реакция на мышь
1277 IgorA 181
align 4
5879 IgorA 182
proc tl_mouse, tlist:dword
183
	pushad
184
	mov edi,dword[tlist]
1277 IgorA 185
 
5911 IgorA 186
	mcall 37,1 ;координаты мыши относительно окна
1277 IgorA 187
 
5879 IgorA 188
	mov ebx,tl_box_left
189
	shl ebx,16
5911 IgorA 190
	cmp eax,ebx ;левая граница окна
191
	jl .no_in_wnd ;.test_scroll не применяем
5879 IgorA 192
		shr ebx,16
193
		add ebx,tl_box_width
194
		shl ebx,16
5911 IgorA 195
		cmp eax,ebx ;правая граница окна
5879 IgorA 196
		jg .test_scroll
1277 IgorA 197
 
5879 IgorA 198
		mov ebx,tl_box_top
199
		add ebx,tl_box_height
5911 IgorA 200
		cmp ax,bx ;нижняя граница окна
5879 IgorA 201
		jg .test_scroll
1277 IgorA 202
 
5879 IgorA 203
		sub ebx,tl_box_height
204
		add bx,tl_capt_cy
5911 IgorA 205
		cmp ax,bx ;верхняя граница окна + высота подписи
5879 IgorA 206
		jl .test_scroll
1277 IgorA 207
 
5914 IgorA 208
push eax ebx
5948 IgorA 209
	mcall 37,7 ;обработка колеса мыши
210
	mov edx,eax
211
	xor	ecx,ecx
5914 IgorA 212
	test eax,eax
213
	jz .mouse_next
214
	test ax,0x8000
215
	jnz .decr
216
	shr eax,16
217
	test ax,0x8000
218
	jnz .decr_1
219
 
220
	mov cx,dx ;dx = mouse scroll data vertical
221
	test ecx,ecx
222
	jnz @f
223
	shr edx,16
224
	mov cx,dx ;dx = mouse scroll data horizontal
225
	test ecx,ecx
226
	jz .mouse_next
227
@@:
228
	stdcall tl_cur_next, edi
229
	dec ecx
230
	jnz @r
231
	jmp .mouse_next
5948 IgorA 232
;------------------------------------------------
5914 IgorA 233
.decr: ;вертикальная прокрутка отрицательная
234
	mov bx,ax ;ax = mouse scroll data vertical
235
	jmp @f
236
.decr_1: ;горизонтальная прокрутка отрицательная
237
	mov bx,ax ;ax = mouse scroll data horizontal
238
@@:
239
	mov ecx,0xffff
240
	sub ecx,ebx
241
	inc ecx
242
@@:
243
	stdcall tl_cur_perv, edi
244
	dec ecx
245
	jnz @r
5948 IgorA 246
;------------------------------------------------
5914 IgorA 247
.mouse_next:
248
pop ebx eax
249
 
5879 IgorA 250
		push eax ebx
251
		mcall 37,2
1390 IgorA 252
 
5879 IgorA 253
		bt eax,0 ;left mouse button press
254
		pop ebx eax
255
		jae .no_draw
1390 IgorA 256
 
5879 IgorA 257
		mov esi,tl_el_focus
258
		mov dword[esi],edi ;set focus
1390 IgorA 259
 
5879 IgorA 260
		; if '+' or '-' press
261
		mov esi,eax
262
		shr esi,16
263
		sub esi,tl_box_left ;esi = mouse x coord in element window
1283 IgorA 264
 
5879 IgorA 265
		and eax,0xffff
266
		sub ax,bx
267
		xor edx,edx
268
		xor ecx,ecx
269
		mov cx,tl_img_cy
270
		div ecx
5911 IgorA 271
		cmp tl_p_scroll,0 ;учитываем скроллинг
5879 IgorA 272
		je @f
5911 IgorA 273
			mov edx,tl_p_scroll
274
			add eax,dword[edx+sb_offs_position] ;добавляем скроллинг на верху
5879 IgorA 275
		@@:
1277 IgorA 276
 
5879 IgorA 277
		mov ecx,eax
278
		call tl_get_node_count ;eax = node count
279
		cmp eax,ecx
280
		jl @f
5911 IgorA 281
			mov eax,ecx ;если курсор не вышел за пределы узлов, восстанавливаем старое значение eax
5879 IgorA 282
		@@:
1277 IgorA 283
 
5911 IgorA 284
		cmp eax,tl_cur_pos ;если новое значение курсора совпало с предыдущим
285
		je @f ;то не стираем курсор
5879 IgorA 286
		push esi
287
			mov esi,tl_box_top
288
			add esi,tl_box_height ;esi = coord bottom border
5911 IgorA 289
			call tl_draw_null_cursor ;стираем курсор
5879 IgorA 290
		pop esi
291
		@@:
1277 IgorA 292
 
5879 IgorA 293
		mov tl_cur_pos,eax
1277 IgorA 294
 
5879 IgorA 295
		; if '+' or '-' press
296
		call tl_get_cur_node_index ;eax = node index
297
		cmp eax,2
5911 IgorA 298
		jl .no_open_close ;курсор стоит на пустом месте, без узлов
5879 IgorA 299
		imul eax,sizeof.TreeList
300
		add eax,tl_data_nodes
301
		xor bx,bx
5911 IgorA 302
		mov bl,byte[eax+2] ;+2 lev сохраняем уровень текущего узла
303
		inc bx ;+ поле для курсора
1277 IgorA 304
 
5879 IgorA 305
		cmp si,tl_img_cx
5911 IgorA 306
		jl .no_open_close ;мышей попали на левое поле для курсора, где точно нет '+' и '-'
5879 IgorA 307
			mov eax,esi
308
			xor edx,edx
309
			xor ecx,ecx
310
			mov cx,tl_img_cx
311
			div ecx
1277 IgorA 312
 
5879 IgorA 313
			cmp ax,bx
314
			jne .no_open_close
1277 IgorA 315
 
5879 IgorA 316
			stdcall tl_node_close_open, edi
317
		.no_open_close:
1277 IgorA 318
 
5879 IgorA 319
		mov esi,tl_box_top
320
		add esi,tl_box_height ;esi = coord bottom border
5911 IgorA 321
		call tl_draw_cursor ;перерисовка курсора
5879 IgorA 322
		call tl_draw_caption_cur_pos
323
		jmp .no_draw
1309 IgorA 324
;--- mouse event for children scrollbar ----------------------------------------
325
.test_scroll:
5911 IgorA 326
	mov edx,tl_p_scroll
5879 IgorA 327
	cmp edx,0
5911 IgorA 328
	je .no_in_wnd ;пользователь не создал дочернего скроллинга
5879 IgorA 329
		shr ebx,16
330
		add bx,word[edx] ;+0 .size_x
331
		shl ebx,16
5911 IgorA 332
		cmp eax,ebx ;правая граница окна
5879 IgorA 333
		jg .no_in_wnd
1309 IgorA 334
 
5879 IgorA 335
		mov eax,dword[edx+sb_offs_max_area]
336
		cmp eax,dword[edx+sb_offs_cur_area]
5911 IgorA 337
		jbe .no_in_wnd ;все узлы попадают в окно скроллинга
5879 IgorA 338
			stdcall scroll_bar_vertical.mouse, edx ;scrollbar_ver_mouse
1309 IgorA 339
 
5879 IgorA 340
			cmp dword[edx+sb_offs_redraw],0
5948 IgorA 341
			je @f
5879 IgorA 342
				mov dword[edx+sb_offs_redraw],0
5911 IgorA 343
				stdcall tl_draw, edi ;произошли изменения скроллинга
5879 IgorA 344
			@@:
345
			cmp dword[edx+sb_offs_delta2],0
5911 IgorA 346
			jne .no_draw ;попали на скроллинг - не снимаем фокус с TreeList
1309 IgorA 347
;-------------------------------------------------------------------------------
5911 IgorA 348
	.no_in_wnd:  ;не попали в окно - потеря фокуса (при условии что фокус был на данном эелементе)
349
	mcall 37,2 ;проверяем нажатость любых кнопок
350
	cmp eax,0  ;ничего не нажали eax=0
5879 IgorA 351
	je .no_draw
352
		mov ebx,tl_el_focus
353
		cmp dword[ebx],edi
5911 IgorA 354
		jne .no_draw ;элемент не в фокусе
5879 IgorA 355
			mov dword[ebx],0 ;reset focus
356
			mov esi,tl_box_top
357
			add esi,tl_box_height ;esi = coord bottom border
5911 IgorA 358
			call tl_draw_cursor ;рисуем курсор с потеряным фокусом
5879 IgorA 359
	.no_draw:
1277 IgorA 360
 
5879 IgorA 361
	popad
362
	ret
363
endp
1277 IgorA 364
 
5911 IgorA 365
;отмена действия
1277 IgorA 366
align 4
5879 IgorA 367
proc tl_info_undo uses eax edi, tlist:dword
368
	mov edi,dword[tlist]
369
	mov eax,tl_tim_undo
370
	cmp tl_ch_tim,eax
371
	jbe @f
372
		inc tl_tim_undo
5911 IgorA 373
		call tb_scrol_resize ;обработка скроллинга
5879 IgorA 374
	@@:
375
	ret
376
endp
1277 IgorA 377
 
5911 IgorA 378
;повтор действия
1277 IgorA 379
align 4
5879 IgorA 380
proc tl_info_redo uses edi, tlist:dword
381
	mov edi,dword[tlist]
382
	cmp tl_tim_undo,1
383
	jl @f
384
		dec tl_tim_undo
5911 IgorA 385
		call tb_scrol_resize ;обработка скроллинга
5879 IgorA 386
	@@:
387
	ret
388
endp
1277 IgorA 389
 
5911 IgorA 390
;удаление отмененных действий
391
;внутренняя функция, не для экспорта
1277 IgorA 392
align 4
5879 IgorA 393
tl_info_set_undo:
5948 IgorA 394
	cmp tl_tim_undo,1
395
	jl .no_work
1277 IgorA 396
 
5948 IgorA 397
	push eax ebx ecx edx
398
	mov edx,tl_data_nodes
399
	mov ecx,edx
400
	add ecx,sizeof.TreeList
401
	call tl_move_next ;long i=node[0].next;
402
	mov eax,tl_tim_undo
403
	sub tl_ch_tim,eax ;ch_tim-=tim_undo;
404
	mov eax,tl_ch_tim
405
	cmp edx,ecx
406
	jle @f
407
		;if(node[i].tc>ch_tim){ // если создание символа было отменено
408
		cmp dword[edx+12],eax
409
		jle .no_u1
410
			mov dword[edx+12],0
411
			mov dword[edx+16],0
1277 IgorA 412
 
5948 IgorA 413
			mov ebx, dword[edx+4]
414
			imul ebx,sizeof.TreeList
415
			add ebx, tl_data_nodes ;.next
416
			push dword[edx+8] ;node[node[i].perv].next=node[i].next;
417
			pop dword[ebx+8]
1277 IgorA 418
 
5948 IgorA 419
			mov ebx, dword[edx+8]
420
			imul ebx,sizeof.TreeList
421
			add ebx, tl_data_nodes ;.perv
422
			push dword[edx+4] ;node[node[i].next].perv=node[i].perv;
423
			pop dword[ebx+4]
424
		.no_u1:
1277 IgorA 425
 
5948 IgorA 426
		;else if(node[i].td>ch_tim) node[i].td=0; // если удаление символа было отменено
427
		cmp dword[edx+16],eax
428
		jle .no_u2
429
			mov dword[edx+16],0
430
		.no_u2:
431
		call tl_move_next
432
		jmp @b
433
	@@:
434
	mov tl_tim_undo,0
435
	pop edx ecx ebx eax
436
	.no_work:
437
	ret
1277 IgorA 438
 
5911 IgorA 439
;вывод списка на экран
1277 IgorA 440
align 4
5879 IgorA 441
proc tl_draw, tlist:dword
5948 IgorA 442
	pushad
443
	;draw dir_list main rect
444
	mov edi,dword[tlist]
445
	mov ebx,tl_box_left
446
	shl ebx,16
447
	add ebx,tl_box_width
448
	mov ecx,tl_box_top
449
	shl ecx,16
450
	mov cx,tl_capt_cy
451
	mov edx,tl_col_zag
452
	mcall 13 ;draw window caption
1277 IgorA 453
 
5948 IgorA 454
	add ecx,tl_box_top
455
	shl ecx,16
456
	add ecx,tl_box_height
457
	sub cx,tl_capt_cy
458
	mov edx,tl_col_bkg
459
	int 0x40 ;draw window client rect
1277 IgorA 460
 
5948 IgorA 461
	cmp tl_capt_cy,9 ;9 - minimum caption height
462
	jl @f
463
	mov ebx,edi ;calculate cursor position
464
	mov eax,tl_cur_pos
465
	inc eax
466
	lea edi,[txt_capt_cur]
467
	add edi,7
468
	call tl_convert_to_str
1309 IgorA 469
 
5948 IgorA 470
	mov edi,ebx
471
	mov eax,tl_tim_undo
472
	lea edi,[txt_capt_otm]
473
	add edi,7
474
	call tl_convert_to_str
475
	mov edi,ebx ;restore edi
1309 IgorA 476
 
5948 IgorA 477
	mov eax,4 ;draw text captions
478
	mov ebx,tl_box_left
479
	shl ebx,16
480
	add ebx,5*65536+3
481
	add ebx,tl_box_top
482
	mov ecx,tl_col_txt
483
	or  ecx,0x80000000
484
	lea edx,[txt_capt_cur]
485
	int 0x40
1277 IgorA 486
 
5948 IgorA 487
	mov ebx,tl_box_left
488
	shl ebx,16
489
	add ebx,100*65536+3
490
	add ebx,tl_box_top
491
	lea edx,[txt_capt_otm]
492
	int 0x40
493
	@@:
1277 IgorA 494
 
5948 IgorA 495
	;cycle to nodes
496
	xor eax,eax
497
	mov edx,tl_data_nodes
498
	mov ecx,edx
499
	add ecx,sizeof.TreeList
1277 IgorA 500
 
5948 IgorA 501
	;*** пропуск узлов, которые промотаны скроллингом ***
502
	cmp tl_p_scroll,0 ;если есть указатель на скроллинг
503
	je .end_c1
504
		mov esi,tl_p_scroll
505
		cmp dword[esi+sb_offs_position],0 ;если скроллинг на верху, выходим
506
		je .end_c1
507
		@@:
508
			call tl_iterat_next
509
			cmp edx,ecx
510
			jle .end_draw
511
			inc eax
512
			cmp eax,dword[esi+sb_offs_position]
513
			jl @b
514
	.end_c1:
1277 IgorA 515
 
5948 IgorA 516
	xor eax,eax
517
	mov esi,tl_box_top
518
	add esi,tl_box_height ;esi = coord bottom border
519
	@@:
520
		call tl_iterat_next
521
		cmp edx,ecx
522
		jle @f
523
		call tl_draw_node
524
		inc eax
525
		jmp @b
526
	@@:
1277 IgorA 527
 
5948 IgorA 528
	call tl_draw_cursor
1390 IgorA 529
 
5948 IgorA 530
	mov edi,tl_p_scroll ;рисуем дочерний скроллинг
531
	cmp edi,0    ;для того что-бы его не пришлось рисовать в пользовательской программе
532
	je .end_draw ;если нет скроллинга выходим
533
		stdcall scroll_bar_vertical.draw, edi
534
	.end_draw:
535
	popad
536
	ret
5879 IgorA 537
endp
1277 IgorA 538
 
5911 IgorA 539
;переход на следущий видимый узел (пропуская закрытые)
1277 IgorA 540
;input:
541
; ecx = pointer to 1 node struct
542
; edx = pointer to some node struct
543
; edi = pointer to 'TreeList' struct
1285 IgorA 544
;output:
545
; edx = pointer to next node struct
1277 IgorA 546
align 4
5879 IgorA 547
tl_iterat_next:
5948 IgorA 548
	push bx
549
	mov bl,0x7f
550
	cmp byte[edx+3],1
551
	jne @f
552
		mov bl,byte[edx+2]
553
	@@:
1277 IgorA 554
 
5948 IgorA 555
	cmp tl_tim_undo,0
556
	je .else
1277 IgorA 557
 
5948 IgorA 558
	push eax
559
	.beg0:
560
		call tl_move_next
561
		cmp edx,ecx
562
		jle @f
563
		call tl_node_not_vis ;пропуск удаленных и отмененных
564
		cmp al,1
565
		je .beg0
566
		cmp bl,byte[edx+2] ;пропуск закрытых
567
		jl .beg0
568
		@@:
569
	pop eax
570
	pop bx
571
	ret
1277 IgorA 572
 
5948 IgorA 573
	.else:
574
		call tl_move_next
575
		cmp edx,ecx
576
		jle .endif
577
		cmp dword[edx+16],0 ;td = 'time delete' -> пропуск удаленных
578
		jne .else
579
		cmp bl,byte[edx+2] ;пропуск закрытых
580
		jl .else
581
	.endif:
582
	pop bx
583
	ret
1277 IgorA 584
 
5911 IgorA 585
;переход на следущий видимый узел (и на закрытые тоже)
1277 IgorA 586
;input:
587
; ecx = pointer to 1 node struct
588
; edx = pointer to some node struct
589
; edi = pointer to 'TreeList' struct
5879 IgorA 590
;output:
591
; edx = pointer to next visible node struct
1277 IgorA 592
align 4
5879 IgorA 593
tl_iterat_next_all:
5948 IgorA 594
	cmp tl_tim_undo,0
595
	je .else
1277 IgorA 596
 
5948 IgorA 597
	push eax
598
	@@:
599
		call tl_move_next
600
		cmp edx,ecx
601
		jle @f
602
		call tl_node_not_vis
603
		cmp al,1
604
		je @b
605
	@@:
606
	pop eax
607
	ret
608
	.else:
609
		call tl_move_next
610
		cmp edx,ecx
611
		jle .endif
612
		cmp dword[edx+16],0 ;td -> time delete
613
		jne .else
614
	.endif:
615
	ret
1277 IgorA 616
 
5911 IgorA 617
;переход на предыдущий видимый узел (пропуская закрытые)
1277 IgorA 618
;input:
619
; ecx = pointer to 1 node struct
620
; edx = pointer to some node struct
621
; edi = pointer to 'TreeList' struct
622
align 4
5879 IgorA 623
tl_iterat_perv:
5948 IgorA 624
	push eax
625
	cmp tl_tim_undo,0
626
	je .beg1
1277 IgorA 627
 
5948 IgorA 628
	.beg0:
629
		call tl_move_perv
630
		cmp edx,ecx
631
		jle @f
632
		call tl_node_not_vis ;пропуск удаленных и отмененных
633
		cmp al,1
634
		je .beg0
1277 IgorA 635
 
5948 IgorA 636
	.beg1:
637
		call tl_move_perv
638
		cmp edx,ecx
639
		jle @f
640
		cmp dword[edx+16],0 ;td = 'time delete' -> пропуск удаленных
641
		jne .beg1
1309 IgorA 642
 
5948 IgorA 643
	@@:
644
		call tl_move_max_clo_par
645
	pop eax
646
	ret
1277 IgorA 647
 
5911 IgorA 648
;находит родительский закрытый узел максимального уровня
1277 IgorA 649
;input:
650
; edx = pointer to some node struct
651
; edi = pointer to 'TreeList' struct
652
;output:
1309 IgorA 653
; edx = pointer closed parent node with maximum level
654
align 4
5879 IgorA 655
proc tl_move_max_clo_par uses eax ebx
5948 IgorA 656
	mov eax,edx
657
	xor ebx,ebx
658
	.beg:
659
		call tl_move_par
660
		cmp byte[edx+3],1 ;родительский узел закрыт ?
661
		jne @f
662
			mov eax,edx
663
		@@:
664
		cmp ebx,edx
665
		je .end_f
666
			mov ebx,edx
667
			jmp .beg
668
	.end_f:
669
	mov edx,eax
670
	ret
5879 IgorA 671
endp
1309 IgorA 672
 
673
;input:
674
; edx = pointer to some node struct
675
; edi = pointer to 'TreeList' struct
676
;output:
1277 IgorA 677
; edx = pointer to next node struct
678
align 4
679
tl_move_next:
5911 IgorA 680
	mov edx,dword[edx+8]
681
	imul edx,sizeof.TreeList
682
	add edx,tl_data_nodes
683
	ret
1277 IgorA 684
 
685
;input:
686
; edx = pointer to some node struct
687
; edi = pointer to 'TreeList' struct
688
;output:
689
; edx = pointer to perv node struct
690
align 4
691
tl_move_perv:
5911 IgorA 692
	mov edx,dword[edx+4]
693
	imul edx,sizeof.TreeList
694
	add edx,tl_data_nodes
695
	ret
1277 IgorA 696
 
5911 IgorA 697
;передвигаемся на родительский узел, если такого нет, то оставляем старое значение указателя
1277 IgorA 698
;input:
1309 IgorA 699
; ecx =
700
; edx = pointer to some node struct
701
; edi = pointer to 'TreeList' struct
702
;output:
703
; edx = pointer to parent node struct
704
align 4
5879 IgorA 705
tl_move_par:
706
	cmp byte[edx+2],0
5911 IgorA 707
	je .end_f ;узел 0-го уровня не может быть дочерним
5879 IgorA 708
	push eax ebx esi
709
	mov esi,edx ;copy node pointer (edx)
710
	mov bl,byte[edx+2]
711
	@@:
712
		call tl_move_perv
713
		cmp edx,ecx
5911 IgorA 714
		jle @f ;все выше стоящие узлы не родительские
715
		call tl_node_not_vis ;пропуск удаленных и отмененных
5879 IgorA 716
		cmp al,1
717
		je @b
718
		cmp byte[edx+2],bl
5911 IgorA 719
		jl .end_0 ;удачно нашли родительский узел
5879 IgorA 720
		jmp @b
721
	@@:
722
		mov esi,ebx ;restore node pointer
723
	.end_0:
724
	pop esi ebx eax
725
	.end_f:
726
	ret
1309 IgorA 727
 
5911 IgorA 728
;проверяет видимый ли указанный узел с учетом: добавлений, удалений, отмен действий
1309 IgorA 729
;input:
1277 IgorA 730
; edx = pointer to symbol struct
731
; edi = pointer to 'TreeList' struct
732
;output:
733
; al = 1 if sumbol not visible
1283 IgorA 734
; (node[i].td+tim_Undo<=ch_tim && node[i].td) || (node[i].tc>ch_tim-tim_Undo)
1277 IgorA 735
align 4
5879 IgorA 736
tl_node_not_vis:
5948 IgorA 737
	cmp dword[edx+16],0
738
	je @f
739
	mov eax,dword[edx+16] ;eax=node[i].td
740
	add eax,tl_tim_undo
741
	cmp eax,tl_ch_tim
742
	jg @f
743
		mov al,1
744
		ret
745
	@@:
1277 IgorA 746
 
5948 IgorA 747
	mov eax,tl_ch_tim
748
	sub eax,tl_tim_undo
749
	cmp dword[edx+12],eax ;tc -> time create
750
	jle @f
751
		mov al,1
752
		ret
753
	@@:
754
	xor al,al
755
	ret
1277 IgorA 756
 
5911 IgorA 757
;рисуем курсор на экране
1277 IgorA 758
;input:
759
; edi = pointer to TreeInfo struct
760
; esi = coord bottom border
761
align 4
5879 IgorA 762
proc tl_draw_cursor uses eax ebx ecx edx esi
763
	call tl_get_display_cur_pos ;eax = cursor pos in screen
764
	cmp eax,0
5911 IgorA 765
	jl .end_f ;курсор находится выше окна, в области прокрученной скроллингом
1277 IgorA 766
 
5911 IgorA 767
	cmp tl_data_img_sys,0 ;смотрим есть ли указатель на картинку системных иконок
5879 IgorA 768
	jne @f
769
		mov ebx,tl_box_left
770
		shl ebx,16
771
		mov bx,tl_img_cx
772
		xor ecx,ecx
773
		mov cx,tl_img_cy
774
		imul ecx,eax
775
		add ecx,tl_box_top
776
		add cx,tl_capt_cy
1277 IgorA 777
 
5879 IgorA 778
		;crop image if on the border
5911 IgorA 779
		cmp esi,ecx ;если курсор внизу и его вообще не видно
5879 IgorA 780
		jl .end_f
1277 IgorA 781
 
5879 IgorA 782
		sub esi,ecx
783
		shl ecx,16
784
		mov cx,tl_img_cy
785
		cmp si,tl_img_cy
786
		jge .crop0
5911 IgorA 787
			mov cx,si ;если курсор виден частично (попал на нижнюю границу)
5879 IgorA 788
		.crop0:
1277 IgorA 789
 
5879 IgorA 790
		mov edx,tl_col_txt
5911 IgorA 791
		mcall 13 ;рисуем простой прямоугольник, т.к. нет системных иконок
5879 IgorA 792
		jmp .end_f
793
	@@:
794
	mov ebx,tl_data_img_sys
795
	imul ax,tl_img_cy
796
	mov edx,tl_box_left
797
	shl edx,16
798
	mov dx,ax
799
	add edx,tl_box_top
800
	add dx,tl_capt_cy
1277 IgorA 801
 
5911 IgorA 802
	mov ecx,tl_el_focus ;проверяем в фокусе элемент или нет
5879 IgorA 803
	cmp dword[ecx],edi
804
	je .focus
5911 IgorA 805
		;если не в фокусе сдвигаем координаты на иконку не активного курсора
5879 IgorA 806
		xor eax,eax
807
		xor ecx,ecx
808
		mov cx,tl_img_cx
809
		mov ax,tl_img_cy
810
		imul eax,ecx
811
		imul eax,4*3 ;4=icon index 3=rgb
812
		add ebx,eax
813
	.focus:
1309 IgorA 814
 
5879 IgorA 815
	mov cx,tl_img_cx
816
	shl ecx,16
817
	mov cx,tl_img_cy
1309 IgorA 818
 
5879 IgorA 819
	;crop image if on the border
5911 IgorA 820
	cmp si,dx ;если курсор внизу и его вообще не видно
5879 IgorA 821
	jl .end_f
1277 IgorA 822
 
5879 IgorA 823
		sub si,dx
824
		cmp si,tl_img_cy
825
		jge .crop1
5911 IgorA 826
			mov cx,si ;если курсор виден частично (попал на нижнюю границу)
5879 IgorA 827
		.crop1:
1277 IgorA 828
 
5911 IgorA 829
		mcall 7 ;рисуем иконку курсора
5879 IgorA 830
	.end_f:
831
	ret
832
endp
1277 IgorA 833
 
5911 IgorA 834
;стираем курсор на экране
1277 IgorA 835
;input:
836
; edi = pointer to TreeInfo struct
837
; esi = coord bottom border
838
align 4
5879 IgorA 839
proc tl_draw_null_cursor uses eax ebx ecx edx esi
5948 IgorA 840
	call tl_get_display_cur_pos ;eax = cursor pos in screen
841
	cmp eax,0
842
	jl .end_f ;курсор находится выше окна, в области прокрученной скроллингом
843
		mov ebx,tl_box_left
844
		shl ebx,16
845
		mov bx,tl_img_cx
846
		xor ecx,ecx
847
		mov cx,tl_img_cy
848
		imul ecx,eax
849
		add ecx,tl_box_top
850
		add cx,tl_capt_cy
1277 IgorA 851
 
5948 IgorA 852
		;crop image if on the border
853
		cmp esi,ecx ;если курсор внизу и его вообще не видно
854
		jl .end_f
1277 IgorA 855
 
5948 IgorA 856
		sub esi,ecx
857
		shl ecx,16
858
		mov cx,tl_img_cy
859
		cmp si,tl_img_cy
860
		jge @f
861
			mov cx,si ;если курсор виден частично (попал на нижнюю границу)
862
		@@:
863
		mcall 13,,,tl_col_bkg ;рисуем простой прямоугольник с фоновым цветом
864
	.end_f:
865
	ret
5879 IgorA 866
endp
1277 IgorA 867
 
5911 IgorA 868
;берет позицию курсора, относительно экрана
1277 IgorA 869
;input:
870
; edi = pointer to TreeInfo struct
871
;output:
872
; eax = index
873
align 4
5879 IgorA 874
tl_get_display_cur_pos:
5948 IgorA 875
	mov eax,tl_cur_pos
876
	cmp tl_p_scroll,0
877
	je @f
878
		push ebx
879
		mov ebx,tl_p_scroll
880
		mov ebx,dword[ebx+sb_offs_position]
881
		sub eax,ebx ;отнимаем позицию скроллинга
882
		pop ebx
883
	@@:
884
	ret
1277 IgorA 885
 
5911 IgorA 886
;рисует узел с: картинкой, подписью, иконкой открытия/закрытия и линиями к родит. узлу
1277 IgorA 887
;input:
5948 IgorA 888
; eax = node position (0, ..., max_nodes-scroll_pos) не до tl_box_height/tl_img_cy
1277 IgorA 889
; edx = pointer to some node struct
1401 IgorA 890
; edi = pointer to 'TreeList' struct
1277 IgorA 891
; esi = coord of bottom border
892
align 4
5879 IgorA 893
proc tl_draw_node uses eax ebx ecx edx esi
5911 IgorA 894
	mov ebx,1 ;1 - место под курсор
1714 IgorA 895
	bt tl_style,2 ;tl_list_box_mode
896
	jc @f
5911 IgorA 897
		inc ebx ;+1 - место под знак +,-
898
		add bl,byte[edx+2] ;добавляем уровень элемента для его учета в левом отступе иконки
1714 IgorA 899
	@@:
900
	imul bx,tl_img_cx
901
	add ebx,tl_box_left
1277 IgorA 902
 
1714 IgorA 903
	shl ebx,16
904
	mov bx,tl_img_cx
905
	xor ecx,ecx
906
	mov cx,tl_img_cy
907
	imul ecx,eax
5948 IgorA 908
	add cx,tl_capt_cy
909
	jc .end_draw ;когда много узлов, то может быть переполнение координаты cx
1714 IgorA 910
	add ecx,tl_box_top
1277 IgorA 911
 
1714 IgorA 912
	;crop image if on the border
5911 IgorA 913
	cmp esi,ecx ;если узел внизу и его вообще не видно
1714 IgorA 914
	jl .end_draw
1277 IgorA 915
 
1714 IgorA 916
	sub esi,ecx
917
	shl ecx,16
918
	mov cx,tl_img_cy
919
	cmp si,tl_img_cy
920
	jge @f
5911 IgorA 921
		mov cx,si ;если узел виден частично (попал на нижнюю границу)
922
		jmp .crop ;пропускаем рисование надписи, которая скорее всего тоже вылезет за нижнюю границу
1714 IgorA 923
	@@:
924
		call tl_draw_node_caption
925
	.crop:
926
	mov esi,ecx ;save ecx
1277 IgorA 927
 
1714 IgorA 928
	cmp tl_data_img,0
929
	jne .draw_img_n
930
		push edx
931
		mov edx,tl_col_txt
5879 IgorA 932
		mcall 13 ;draw node rect
5948 IgorA 933
		pop edx
1714 IgorA 934
	jmp @f
935
	.draw_img_n:
936
	push ebx edx esi
937
		xor esi,esi
938
		mov si,word[edx] ;get icon type
939
		mov edx,ebx
940
		ror ecx,16
941
		mov dx,cx
942
		mov cx,bx
943
		ror ecx,16
944
		mov ebx,3 ;rgb = 3 bytes
945
		imul bx,tl_img_cx
946
		imul bx,tl_img_cy
947
		imul ebx,esi ;esi = icon index
948
		add ebx,tl_data_img
1277 IgorA 949
 
5879 IgorA 950
		mcall 7 ;draw node icon '-'
1714 IgorA 951
	pop esi edx ebx
952
	@@:
1277 IgorA 953
 
1714 IgorA 954
	mov al,byte[edx+2] ;draw minus '-'
955
	mov ecx,tl_data_nodes
956
	add ecx,sizeof.TreeList
1277 IgorA 957
 
1714 IgorA 958
	mov ah,10 ;get icon index '+' or '-' ?
959
	cmp byte[edx+3],1
960
	jne .close
961
		dec ah
962
	.close:
1277 IgorA 963
 
5911 IgorA 964
	call tl_draw_node_icon_opn_clo ;рисование иконки открытого или закрытого узла
1714 IgorA 965
	bt tl_style,1
966
	jae .end_draw
5911 IgorA 967
		call tl_draw_node_icon_par_lin ;рисование линии к родительскому элементу
968
		call tl_draw_node_icon_par_lin_up ;рисование вертикальной линии к родительскому элементу
1714 IgorA 969
	.end_draw:
970
	ret
5879 IgorA 971
endp
1277 IgorA 972
 
5911 IgorA 973
;рисует иконки открытого или закрытого узла (обычно + или -)
1277 IgorA 974
;input:
5911 IgorA 975
; al = уровень элемента
1277 IgorA 976
; ecx = pointer to 1 node struct
1401 IgorA 977
; edx = pointer to some node struct
1277 IgorA 978
;...
979
align 4
5879 IgorA 980
proc tl_draw_node_icon_opn_clo uses eax ebx ecx edx esi
5948 IgorA 981
	inc al
982
	call tl_iterat_next_all ;get next visible item
983
	cmp edx,ecx
984
	jle @f
985
		mov ecx,esi ;load ecx
986
		cmp al,byte[edx+2]
987
		jne @f
988
		ror ebx,16
989
		sub bx,tl_img_cx
990
		ror ebx,16
991
		cmp tl_data_img_sys,0
992
		jne .draw_img_s
993
			mcall 13,,,tl_col_txt ;draw minus rect, if not system icons
994
			jmp @f
995
		.draw_img_s:
996
		mov ecx,esi ;load ecx
997
		mov edx,ebx
998
		ror ecx,16
999
		mov dx,cx
1000
		mov cx,bx
1001
		ror ecx,16
1002
		mov ebx,3 ;rgb = 3 bytes
1003
		imul bx,tl_img_cx
1004
		imul bx,tl_img_cy
1005
		shr eax,8
1006
		and eax,0xff
1007
		imul ebx,eax ;eax = icon index
1008
		add ebx,tl_data_img_sys
1009
		mcall 7 ;draw minus icon '-'
1010
	@@:
1011
	ret
5879 IgorA 1012
endp
1277 IgorA 1013
 
5911 IgorA 1014
;рисование линии к родительскому элементу
1277 IgorA 1015
;input:
5911 IgorA 1016
; al = уровень элемента
1401 IgorA 1017
; ecx = pointer to 1 node struct
1018
; edx = pointer to some node struct
1277 IgorA 1019
;...
1020
align 4
5879 IgorA 1021
tl_draw_node_icon_par_lin:
5948 IgorA 1022
	cmp byte[edx+3],1
1023
	je .close
1024
	push eax ebx ecx edx esi
1025
	cmp al,0
1026
	je @f
1027
		call tl_iterat_next_all ;get next visible item
1028
		cmp edx,ecx
1029
		jle .line3 ;if end of list
1030
			cmp al,byte[edx+2]
1031
			jne .line3 ;jg ???
1032
			mov eax,3 ;line in middle element
1033
			jmp .line2
1034
		.line3:
1035
			mov eax,6 ;line in end element
1036
		.line2:
1277 IgorA 1037
 
5948 IgorA 1038
		mov ecx,esi ;load ecx
1039
		ror ebx,16
1040
		sub bx,tl_img_cx
1041
		ror ebx,16
1042
		cmp tl_data_img_sys,0
1043
		jne .draw_img_s
1044
			mcall 13,,,tl_col_txt ;draw minus rect, if not system icons
1045
			jmp @f
1046
		.draw_img_s:
1047
		mov edx,ebx
1048
		ror ecx,16
1049
		mov dx,cx
1050
		mov cx,bx
1051
		ror ecx,16
1052
		mov ebx,3 ;rgb = 3 bytes
1053
		imul bx,tl_img_cx
1054
		imul bx,tl_img_cy
1277 IgorA 1055
 
5948 IgorA 1056
		imul ebx,eax ;eax = icon index
1057
		add ebx,tl_data_img_sys
1058
		mcall 7 ;draw line icon
1059
	@@:
1060
	pop esi edx ecx ebx eax
1061
	.close:
1062
	ret
1277 IgorA 1063
 
1064
 
1401 IgorA 1065
;input:
5911 IgorA 1066
; al = уровень элемента
5948 IgorA 1067
; ebx = (node.left shl 16) + tl_img_cx
1401 IgorA 1068
; ecx = pointer to 1 node struct
1069
; edx = pointer to some node struct
1070
; edi = pointer to 'TreeList' struct
1309 IgorA 1071
align 4
5948 IgorA 1072
proc tl_draw_node_icon_par_lin_up uses eax ebx ecx edx esi
1073
	cmp tl_data_img_sys,0 ;if not image
1074
	je @f
1075
	cmp al,0
1076
	je @f
1077
		xor esi,esi ;в si будем насчитывать кол-во иконок, нужных для прорисовки линии
5911 IgorA 1078
;--- цикл для вычисления колличества вертикальных линий ---
5948 IgorA 1079
		.cycle0:
1080
			call tl_iterat_perv ;get perv visible item
1081
			cmp edx,ecx
1082
			jle .cycle1 ;if begin of list
1309 IgorA 1083
 
5948 IgorA 1084
			cmp byte[edx+2],al
1085
			jle .cycle0end ;уровень верхнего элемента не требует прорисовки
1086
			inc si
1087
			jmp .cycle0
1088
		.cycle0end:
1089
		cmp si,0 ;si = кол-во иконок линии которые нужно нарисовать сверху
1090
		je @f
1091
		shl esi,16
1309 IgorA 1092
 
5948 IgorA 1093
		pop ecx ;esi->ecx
1094
		push ecx ;save esi
1309 IgorA 1095
 
5948 IgorA 1096
		ror ebx,16
1097
		sub bx,tl_img_cx
1098
		ror ebx,16
1309 IgorA 1099
 
5948 IgorA 1100
		mov edx,ebx
1101
		ror ecx,16
1102
		mov dx,cx
1103
		mov cx,bx
1104
		ror ecx,16
1105
		mov cx,tl_img_cy ;restore size y (if crop)
1106
		mov ebx,3 ;rgb = 3 bytes
1107
		imul bx,tl_img_cx
1108
		imul bx,tl_img_cy
1109
		add ebx,tl_data_img_sys
1309 IgorA 1110
 
5948 IgorA 1111
		add esi,tl_box_top
1112
		add si,tl_capt_cy ;si = верхняя граница окна
1113
		mov eax,7
5911 IgorA 1114
;--- цикл для рисования вертикальной линии ---
5948 IgorA 1115
		.cycle1:
1116
		sub dx,tl_img_cy ;поднимаем координату y вверх
1117
		cmp dx,si
1118
		jl @f
1119
			cmp esi,0x10000
1120
			jl @f
1121
			int 0x40 ;draw line icon
1122
			sub esi,0x10000 ;уменьшаем счетчик иконок
1123
		jmp .cycle1
1124
	@@:
1125
	ret
1126
endp
1309 IgorA 1127
 
1277 IgorA 1128
;input:
1129
; edi = pointer to TreeInfo struct
1130
;output:
1131
; eax = rows
1132
align 4
1133
tl_get_rows_count:
5948 IgorA 1134
	push ecx edx
1135
		mov eax,tl_box_height
1136
		sub ax,tl_capt_cy
1137
		xor ecx,ecx
1138
		mov cx,tl_img_cy
1139
		xor edx,edx
1140
		div ecx
1141
	pop edx ecx
1142
	ret
1277 IgorA 1143
 
1144
;input:
1145
; eax = node position
5911 IgorA 1146
; ebx = [координата по оси x]*65536 + [img_cx]
1147
; ecx = [координата по оси y]*65536 + [img_cy]
1277 IgorA 1148
; edx = pointer to some node struct
1149
; edi = pointer to TreeInfo struct
1150
align 4
5948 IgorA 1151
proc tl_draw_node_caption uses ebx ecx edx esi
1152
	xor esi,esi
1153
	mov si,tl_info_size
1154
	cmp si,tl_info_capt_offs
1155
	jle @f ;if caption size <= 0
1156
		push eax
1157
			call tl_get_node_index ;eax = node index
1158
			imul esi,eax
1159
		pop eax
1160
		add si,tl_info_capt_offs
1161
		add esi,tl_data_info
1162
		mov edx,esi
1277 IgorA 1163
 
5948 IgorA 1164
		shr ebx,16
1165
		add bx,tl_img_cx ;сдвигаем надпись по горизонтали --->
1166
		add bx,3 ;отступ
1167
		;bx = coord.x
1168
		call tl_strlen ;eax = strlen
1169
		call tl_get_draw_text_len
1170
		mov cx,bx
1171
		ror ecx,16
1172
		mov ebx,ecx
1173
		add bx,tl_img_cy ;выравнивиние по нижней границе иконки
1174
		sub bx,9 ;отнимаем высоту текста
1175
		mov ecx,tl_col_txt
1176
		and ecx,0xffffff
1177
		mcall 4
1178
	@@:
1179
	ret
1180
endp
1277 IgorA 1181
 
1182
;input:
1183
; eax = strlen
1184
; ebx = text coord x
1185
;output:
1186
; esi = text len
1187
align 4
5948 IgorA 1188
proc tl_get_draw_text_len uses eax ecx edx
1189
	mov esi,eax ;берем длинну строки
1190
	mov eax,tl_box_left
1191
	add eax,tl_box_width
1192
	cmp eax,ebx
1193
	jle .text_null ;если подпись полностью вся за экраном
1194
		sub eax,ebx
1195
		xor edx,edx
1196
		mov ecx,6 ;ширина системного шрифта
1197
		div ecx ;смотрим сколько символов может поместиться на экране
1198
		cmp esi,eax
1199
		jl @f
1200
			mov esi,eax ;если длинна текста меньше, чем все место под строку
1201
			jmp @f
1202
	.text_null:
1203
	xor esi,esi
1204
	@@:
1205
	ret
1206
endp
1277 IgorA 1207
 
1208
;input:
1209
; esi = pointer to string
1210
;output:
1211
; eax = strlen
1212
align 4
1213
tl_strlen:
5948 IgorA 1214
	mov eax,esi
1215
	@@:
1216
		cmp byte[eax],0
1217
		je @f
1218
		inc eax
1219
		jmp @b
1220
	@@:
1221
	sub eax,esi
1222
	ret
1277 IgorA 1223
 
5911 IgorA 1224
;добавить узел
1277 IgorA 1225
;input:
5911 IgorA 1226
; tlist - указатель на структуру листа
1227
; n_opt - опции добавления
1228
; n_info - указатель на добавляемые данные
1277 IgorA 1229
align 4
5911 IgorA 1230
proc tl_node_add uses eax ebx ecx edx edi, tlist:dword, n_opt:dword, n_info:dword
5948 IgorA 1231
	mov edi,dword[tlist]
1277 IgorA 1232
 
5948 IgorA 1233
	call tl_info_set_undo
1277 IgorA 1234
 
5948 IgorA 1235
	mov ebx,sizeof.TreeList
1236
	imul ebx,tl_info_max_count
1237
	add ebx,tl_data_nodes
1277 IgorA 1238
;--
5948 IgorA 1239
	call tl_get_cur_node_index ;eax=po_t
1240
	imul eax,sizeof.TreeList
1241
	add eax,tl_data_nodes
1242
	mov edx,eax
1243
	call tl_move_perv
1244
	call tl_get_node_index ;eax = index of pointer [edx]
1277 IgorA 1245
;--
5948 IgorA 1246
	mov edx,sizeof.TreeList
1247
	shl edx,1
1248
	add edx,tl_data_nodes
1249
	@@: ;for(i=2;i
1250
		cmp dword [edx+12],0
1251
		jne .u0
1252
		cmp dword [edx+16],0
1253
		jne .u0
1277 IgorA 1254
 
5948 IgorA 1255
		inc tl_ch_tim
1256
		mov ecx,dword[n_opt]
1257
		ror ecx,16 ;cx = type
1258
		mov word[edx],cx
1259
		rol ecx,8 ;cl = close|open
1260
		mov byte[edx+3],cl ;node[i].clo
1261
		mov byte[edx+2],0 ;node[i].lev=0
1262
		bt tl_style,2 ;tl_list_box_mode
1263
		jc .l_box_m
1264
			mov cl,byte[n_opt]
1265
			mov byte[edx+2],cl ;node[i].lev
1266
		.l_box_m:
1267
		push tl_ch_tim       ;node[i].tc=ch_tim;
1268
		pop dword[edx+12]
1269
		mov [edx+4],eax ;node[i].perv=po_t;
1270
		;*** copy node data ***
1271
		push esi
1272
		xor ecx,ecx
1273
		mov cx,tl_info_size
1274
		mov esi,ecx
1277 IgorA 1275
 
5948 IgorA 1276
		push eax
1277
			call tl_get_node_index ;eax = node index
1278
			imul esi,eax
1279
		pop eax
1280
		add esi,tl_data_info
1281
		mov edi,dword[n_info] ;pointer to node data
1282
		xchg edi,esi
1283
		rep movsb
1277 IgorA 1284
 
5948 IgorA 1285
		mov esi,edi
1286
		mov edi,dword[tlist] ;restore edi
1287
		mov cx,tl_info_capt_offs
1288
		cmp cx,tl_info_size
1289
		jge .no_text_data
1290
		cmp tl_info_capt_len,0 ;проверяем есть ли ограничение на длинну строки
1291
		je .no_len_ogran
1292
			add cx,tl_info_capt_len
1293
			and ecx,0xffff
1294
			add esi,ecx
1295
			mov cx,tl_info_size
1296
			sub esi,ecx
1297
		.no_len_ogran:
1298
		dec esi
1299
		mov byte[esi],0
1300
		.no_text_data:
1301
		pop esi ;restore esi
1277 IgorA 1302
 
5948 IgorA 1303
		mov ecx,eax
1304
		imul ecx,sizeof.TreeList
1305
		add ecx,tl_data_nodes ; *** ecx = node[po_t] ***
1306
		add ecx,8   ; *** ecx = node[po_t].next ***
1307
		push dword[ecx] ;node[i].next=node[po_t].next;
1308
		pop dword[edx+8]
1277 IgorA 1309
 
5948 IgorA 1310
		call tl_get_node_index ;*** eax = i ***
1311
		cmp eax,tl_info_max_count
1312
		jge .u0
1313
			mov [ecx],eax ;node[po_t].next=i; // ссылки перенаправляем
1314
			mov ecx,[edx+8] ; *** ecx = node[i].next ***
1315
			imul ecx,sizeof.TreeList
1316
			add ecx,tl_data_nodes ; *** ecx = node[node[i].next] ***
1317
			mov [ecx+4],eax ;node[node[i].next].perv=i;
1277 IgorA 1318
 
5948 IgorA 1319
			call tb_scrol_resize ;обработка скроллинга
1320
			jmp @f
1321
		.u0:
1322
		add edx,sizeof.TreeList
1323
		cmp edx,ebx ;enf of node memory ?
1324
		jle @b
1325
	@@:
5879 IgorA 1326
	ret
1327
endp
1277 IgorA 1328
 
1329
;input:
1330
; edi = pointer to TreeInfo struct
1331
align 4
5879 IgorA 1332
proc tb_scrol_resize uses eax ecx edx
5911 IgorA 1333
	cmp tl_p_scroll,0 ;обработка скроллинга
5948 IgorA 1334
	je @f
1335
		call tl_get_node_count ;eax = node count
1336
		mov ecx,eax
1337
		call tl_get_rows_count
1338
		cmp ecx,eax
1339
		jg .ye_sb
1340
			xor ecx,ecx
1341
		.ye_sb:
1342
		mov edx,tl_p_scroll
1343
		mov dword[edx+sb_offs_cur_area],eax
1344
		mov dword[edx+sb_offs_max_area],ecx
5879 IgorA 1345
		stdcall scroll_bar_vertical.draw,edx
5948 IgorA 1346
	@@:
1347
	ret
5879 IgorA 1348
endp
1277 IgorA 1349
 
1350
;input:
5879 IgorA 1351
;n_info - pointer to node info
1277 IgorA 1352
align 4
5911 IgorA 1353
proc tl_node_set_data uses eax ecx edx edi esi, tlist:dword, n_info:dword
5948 IgorA 1354
	mov edi,dword[tlist]
1355
	call tl_get_cur_node_index ;eax=po_t
1356
	cmp eax,2
1357
	jl @f
1358
		xor ecx,ecx
1359
		mov cx,tl_info_size
1360
		imul eax,ecx
1361
		add eax,tl_data_info
1362
		mov edi,eax
1363
		mov esi,dword[n_info] ;pointer to node data
1364
		rep movsb
1277 IgorA 1365
 
5948 IgorA 1366
		mov esi,edi
1367
		mov edi,dword[tlist] ;restore edi
1368
		mov cx,tl_info_capt_offs
1369
		cmp cx,tl_info_size
1370
		jge .no_text_data
1371
			mov ax,tl_info_capt_len ;проверяем есть ли ограничение на длинну текста
1372
			cmp ax,0
1373
			je .no_limit
1374
				add cx,ax ;cx = tl_info_capt_offs + tl_info_capt_len
1375
				and ecx,0xffff
1376
				xor eax,eax
1377
				mov ax,tl_info_size
1378
				cmp eax,ecx
1379
				jl .no_limit ;пользователь задал слишком большую длинну текста
1380
				add esi,ecx
1381
				sub esi,eax
1382
			.no_limit:
1383
			dec esi
1384
			mov byte[esi],0 ;обнуляем последний символ подписи, что-бы не глючило если пользователь задал неправильную структуру
1385
		.no_text_data:
1386
	@@:
5879 IgorA 1387
	ret
1388
endp
1277 IgorA 1389
 
5911 IgorA 1390
;взять указатель на данные узла под курсором
1277 IgorA 1391
;input:
5911 IgorA 1392
; tlist - pointer to 'TreeList' struct
1393
;output:
1394
; eax - pointer to node data
1277 IgorA 1395
align 4
5911 IgorA 1396
proc tl_node_get_data uses ecx edi, tlist:dword
1397
	mov edi,dword[tlist]
1398
	call tl_get_cur_node_index ;eax=po_t
1399
	cmp eax,2
1400
	jl @f
1401
		movzx ecx,tl_info_size
1402
		imul eax,ecx
1403
		add eax,tl_data_info
1404
		jmp .end_f ;return node data pointer
1405
	@@:
1406
	xor eax,eax
1407
	.end_f:
1277 IgorA 1408
  ret
5911 IgorA 1409
endp
1277 IgorA 1410
 
5911 IgorA 1411
;взять указатель на структуру узла в указанной позиции
1277 IgorA 1412
;input:
5911 IgorA 1413
; tlist - pointer to 'TreeList' struct
1414
; node_ind - node index
1415
;output:
1416
; eax - pointer to node info
1277 IgorA 1417
align 4
5914 IgorA 1418
proc tl_node_poi_get_info uses ebx ecx edx edi, tlist:dword, node_ind:dword
5911 IgorA 1419
	mov edi,dword[tlist]
1420
	mov ebx,dword[node_ind]
1277 IgorA 1421
 
5911 IgorA 1422
	;cycle to nodes
5914 IgorA 1423
	mov edx,tl_data_nodes
1424
	mov ecx,edx
5911 IgorA 1425
	add ecx,sizeof.TreeList
1426
	@@:
1427
		call tl_iterat_next_all
5914 IgorA 1428
		cmp edx,ecx
5911 IgorA 1429
		jle @f
1430
		dec ebx
1431
		cmp ebx,0
1432
		jg @b
1433
		jmp .find
1434
	@@:
5914 IgorA 1435
		xor edx,edx
5911 IgorA 1436
	.find:
5914 IgorA 1437
	mov eax,edx
5911 IgorA 1438
	ret
1439
endp
1277 IgorA 1440
 
5911 IgorA 1441
;взять указатель на следущую структуру узла
1277 IgorA 1442
;input:
5911 IgorA 1443
; tlist - pointer to 'TreeList' struct
1444
; node_p - node param struct
1445
;output:
1446
; eax - pointer to next node struct
1277 IgorA 1447
align 4
5911 IgorA 1448
proc tl_node_poi_get_next_info uses ecx edx edi, tlist:dword, node_p:dword
1449
	mov edi,dword[tlist]
1450
	mov edx,dword[node_p]
1277 IgorA 1451
 
5911 IgorA 1452
	mov ecx,tl_data_nodes
1453
	add ecx,sizeof.TreeList
1277 IgorA 1454
 
5911 IgorA 1455
	call tl_iterat_next_all
1456
	cmp edx,ecx
1457
	jg @f
1458
		xor edx,edx
1459
	@@:
1460
	mov eax,edx
1461
	ret
1462
endp
1277 IgorA 1463
 
5911 IgorA 1464
;взять указатель на данные узла
1277 IgorA 1465
;input:
5911 IgorA 1466
; tlist - pointer to 'TreeList' struct
1467
; node_p - node param struct
1468
;output:
1469
; eax - pointer
1277 IgorA 1470
align 4
5911 IgorA 1471
proc tl_node_poi_get_data uses ecx edx edi, tlist:dword, node_p:dword
1472
	mov edi,dword[tlist]
1473
	mov edx,dword[node_p]
1277 IgorA 1474
 
5948 IgorA 1475
	call tl_get_node_index ;eax = node index
1476
	cmp eax,2
1477
	jl @f
1478
		xor ecx,ecx
1479
		mov cx,tl_info_size
1480
		imul eax,ecx
5911 IgorA 1481
		add eax,tl_data_info
1482
		jmp .end_f ;return node data pointer
5948 IgorA 1483
	@@:
5911 IgorA 1484
		xor eax,eax ;возвращаем 0 в случае не удачного поиска
1485
	.end_f:
1486
	ret
1487
endp
1277 IgorA 1488
 
5911 IgorA 1489
;берет позицию под курсором
1277 IgorA 1490
;input:
1491
; edi = pointer 'tl' struct
1492
;output:
1493
; eax = index of current node
1494
align 4
5879 IgorA 1495
proc tl_get_cur_node_index uses ecx edx
5911 IgorA 1496
	;cycle to nodes
1497
	xor eax,eax
1498
	mov edx,tl_data_nodes
1499
	mov ecx,edx
1500
	add ecx,sizeof.TreeList
1501
	@@:
1502
		call tl_iterat_next
1503
		cmp edx,ecx
1504
		jle @f
1505
		cmp eax,tl_cur_pos
1506
		je @f
1507
		inc eax
1508
		jmp @b
1509
	@@:
1510
	mov eax,edx
1511
	sub eax,tl_data_nodes
1512
	xor edx,edx
1513
	mov ecx,sizeof.TreeList
1514
	div ecx
1515
	ret
5879 IgorA 1516
endp
1277 IgorA 1517
 
5911 IgorA 1518
;берет позицию указанного символа
1277 IgorA 1519
;input:
1520
; edx = pointer node memory
1521
; edi = pointer 'tl' struct
1522
;output:
1523
; eax = struct index of current node
1524
align 4
5879 IgorA 1525
tl_get_node_index:
5911 IgorA 1526
	push ecx edx
1527
	mov eax,edx
1528
	sub eax,tl_data_nodes
1529
	xor edx,edx
1530
	mov ecx,sizeof.TreeList
1531
	div ecx
1532
	pop edx ecx
1533
	ret
1277 IgorA 1534
 
5911 IgorA 1535
;удалить узел
1277 IgorA 1536
align 4
5879 IgorA 1537
proc tl_node_delete uses eax edx edi, tlist:dword
1538
	mov edi,dword[tlist]
5911 IgorA 1539
	call tl_get_cur_node_index ;eax=po_t
1540
	cmp eax,2
1541
	jl @f
1542
		imul eax,sizeof.TreeList
1543
		add eax,tl_data_nodes
1544
		mov edx,eax
1545
		inc tl_ch_tim
1546
		mov eax,tl_ch_tim
1547
		mov dword[edx+16],eax
1548
		call tb_scrol_resize ;обработка скроллинга
1549
	@@:
5879 IgorA 1550
	ret
1551
endp
1277 IgorA 1552
 
5911 IgorA 1553
;поставить курсор на первый узел
1277 IgorA 1554
align 4
5879 IgorA 1555
proc tl_cur_beg uses edi, tlist:dword
1556
	mov edi,dword[tlist]
5911 IgorA 1557
	mov tl_cur_pos,0
1558
	cmp tl_p_scroll,0
1559
	je @f
1560
		mov edi,tl_p_scroll
1561
		mov dword[edi+sb_offs_position],0
5879 IgorA 1562
		stdcall scroll_bar_vertical.draw, edi
5911 IgorA 1563
	@@:
5879 IgorA 1564
	ret
1565
endp
1277 IgorA 1566
 
5911 IgorA 1567
;перенести курсор на 1 позицию ниже
1277 IgorA 1568
align 4
5879 IgorA 1569
proc tl_cur_next uses eax ebx edi esi, tlist:dword
5948 IgorA 1570
	mov edi,dword[tlist]
1571
	call tl_get_node_count ;eax = node count
1572
	cmp tl_cur_pos,eax
1573
	jge .no_redraw
1574
		mov esi,tl_box_top
1575
		add esi,tl_box_height ;esi = coord bottom border
1576
		call tl_draw_null_cursor ;стираем курсор
1577
		inc tl_cur_pos
1277 IgorA 1578
 
5948 IgorA 1579
		cmp tl_p_scroll,0 ;if not scrol struct
1580
		je @f
1581
		call tl_get_rows_count ;eax = rows count
1582
		mov ebx,tl_p_scroll
1583
		add eax,dword[ebx+sb_offs_position]
1584
		cmp tl_cur_pos,eax
1585
		jl @f
1586
			inc dword[ebx+sb_offs_position]
1587
			stdcall scroll_bar_vertical.draw,ebx
1588
			stdcall tl_draw,dword[tlist] ;полная перерисовка окна
1589
			jmp .no_redraw
1590
		@@:
1591
		mov edi,dword[tlist] ;restore edi
1592
		call tl_draw_cursor ;перерисовка курсора
1593
		call tl_draw_caption_cur_pos
1594
	.no_redraw:
5879 IgorA 1595
	ret
1596
endp
1277 IgorA 1597
 
5911 IgorA 1598
;берет число всех видимых узлов (не считая закрытых дочерних)
1277 IgorA 1599
;input:
1600
; edi = pointer 'tl' struct
1601
;output:
1602
; eax = struct index of current node
1603
align 4
5879 IgorA 1604
tl_get_node_count:
5911 IgorA 1605
push ecx edx
1606
	;cycle to nodes
1607
	xor eax,eax
1608
	mov edx,tl_data_nodes
1609
	mov ecx,edx
1610
	add ecx,sizeof.TreeList
1611
	@@:
1612
		call tl_iterat_next
1613
		cmp edx,ecx
1614
		jle @f
1615
		inc eax
1616
		jmp @b
1617
	@@:
1618
pop edx ecx
1619
	ret
1277 IgorA 1620
 
5911 IgorA 1621
;берет число всех видимых узлов (считая закрытые дочерние)
1303 IgorA 1622
;input:
1623
; edi = pointer 'tl' struct
1624
;output:
1625
; eax = struct index of current node
1277 IgorA 1626
align 4
5879 IgorA 1627
tl_get_node_count_all:
5911 IgorA 1628
push ecx edx
1629
	;cycle to nodes
1630
	xor eax,eax
1631
	mov edx,tl_data_nodes
1632
	mov ecx,edx
1633
	add ecx,sizeof.TreeList
1634
	@@:
1635
		call tl_iterat_next_all
1636
		cmp edx,ecx
1637
		jle @f
1638
		inc eax
1639
		jmp @b
1640
	@@:
1641
pop edx ecx
1642
	ret
1303 IgorA 1643
 
5911 IgorA 1644
;перенести курсор на 1 позицию выше
1303 IgorA 1645
align 4
5879 IgorA 1646
proc tl_cur_perv uses eax edi esi, tlist:dword
5911 IgorA 1647
	mov edi,dword[tlist]
1648
	cmp tl_cur_pos,0
1649
	je .no_redraw
1650
		mov esi,tl_box_top
1651
		add esi,tl_box_height ;esi = coord bottom border
1652
		call tl_draw_null_cursor ;стираем курсор
1653
		dec tl_cur_pos ;двигаем курсор вверх
1277 IgorA 1654
 
5911 IgorA 1655
		cmp tl_p_scroll,0 ;если есть указатель на скроллинг
1656
		je @f
1657
		mov eax,tl_p_scroll
1658
		cmp dword[eax+sb_offs_position],0 ;если скроллинг на верху, выходим
1659
		je @f
1660
		mov edi,tl_cur_pos
1661
		cmp edi,dword[eax+sb_offs_position] ;если курсор ушел выше скроллинга, тогда опускаем скроллинг
1662
		jge @f
1663
			dec dword[eax+sb_offs_position]
1664
			stdcall scroll_bar_vertical.draw, eax
1665
			stdcall tl_draw, dword[tlist] ;полная перерисовка окна
1666
			jmp .no_redraw
1667
		@@:
1668
			mov edi,dword[tlist] ;restore edi
1669
			call tl_draw_cursor ;перерисовка курсора
1670
			call tl_draw_caption_cur_pos
1671
	.no_redraw:
5879 IgorA 1672
	ret
1673
endp
1277 IgorA 1674
 
5911 IgorA 1675
;перенести курсор на 1 страницу выше
1277 IgorA 1676
align 4
5879 IgorA 1677
proc tl_cur_page_up uses eax edi esi, tlist:dword
5948 IgorA 1678
	mov edi,dword[tlist]
1303 IgorA 1679
 
5948 IgorA 1680
	cmp tl_p_scroll,0 ;если есть указатель на скроллинг
1681
	je .no_redraw
1682
		mov esi,tl_p_scroll
1683
		call tl_get_rows_count ;eax = rows count
1303 IgorA 1684
 
5948 IgorA 1685
		cmp tl_cur_pos,0
1686
		jne @f
1687
		cmp dword[esi+sb_offs_position],0 ;если скроллинг на верху, выходим
1688
		jne @f
1689
			jmp .no_redraw
1690
		@@:
1691
		cmp tl_cur_pos,eax ;проверяем позицию курсора и кол-во сток на странице
1692
		jl @f ;если меньше, то приравниваем к 0, что-бы не отнять больше чем надо
1693
			sub tl_cur_pos,eax
1694
			jmp .cursor
1695
		@@:
1696
			mov tl_cur_pos,0
1697
		.cursor:
1698
		cmp dword[esi+sb_offs_position],eax
1699
		jl @f
1700
			sub dword[esi+sb_offs_position],eax
1701
			jmp .scroll
1702
		@@:
1703
		mov dword[esi+sb_offs_position],0
1704
		.scroll:
1705
		;перерисовки окна и скроллинга
1706
		stdcall tl_draw, edi ;draw window
1707
		stdcall scroll_bar_vertical.draw, esi
1708
	.no_redraw:
5879 IgorA 1709
	ret
1710
endp
1303 IgorA 1711
 
5911 IgorA 1712
;перенести курсор на 1 страницу ниже
1303 IgorA 1713
align 4
5879 IgorA 1714
proc tl_cur_page_down uses eax ebx ecx edi esi, tlist:dword
5911 IgorA 1715
;eax - кол-во строк на странице
1716
;ebx - макс. позиция курсора
1717
;ecx - макс. позиция скроллинга
5948 IgorA 1718
	mov edi,dword[tlist]
1719
	cmp tl_p_scroll,0 ;если есть указатель на скроллинг
1720
	je .no_redraw
1721
		mov esi,tl_p_scroll
1722
		call tl_get_node_count ;eax = node count
1723
		mov ebx,eax
1724
		call tl_get_rows_count ;eax = rows count
1303 IgorA 1725
 
5948 IgorA 1726
		mov ecx,ebx
1727
		inc ecx ;если нижний узел виден на половину
1728
		cmp ecx,eax ;if (ecx>eax) { ecx=ecx-eax } else { ecx=0 }
1729
		jl @f
1730
			sub ecx,eax ;уменьшаем максимальную позицию скроллинга, так что-бы были видны последние узлы
1731
			jmp .control
1732
		@@:
1733
			xor ecx,ecx ;ecx=0 - все узлы влазят в экран, скроллинг не нужен
1734
		.control:
1303 IgorA 1735
 
5948 IgorA 1736
		cmp tl_cur_pos,ebx ;курсор внизу ?
1737
		jl @f
1738
		cmp dword[esi+sb_offs_position],ecx ;скроллинг внизу ?
1739
		jl @f
1740
			jmp .no_redraw
1741
		@@:
1742
		add tl_cur_pos,eax ;перемещаем курсор
1743
		cmp tl_cur_pos,ebx
1744
		jl @f
1745
			mov tl_cur_pos,ebx
1746
		@@:
1747
		add dword[esi+sb_offs_position],eax ;перемещаем скроллинг
1748
		cmp dword[esi+sb_offs_position],ecx
1749
		jl @f
1750
			mov dword[esi+sb_offs_position],ecx
1751
		@@:
1303 IgorA 1752
 
5948 IgorA 1753
		;перерисовки окна и скроллинга
1754
		stdcall tl_draw, edi ;draw window
1755
		stdcall scroll_bar_vertical.draw, esi
1756
	.no_redraw:
5879 IgorA 1757
	ret
1758
endp
1303 IgorA 1759
 
5911 IgorA 1760
;открыть/закрыть узел (работает с узлами которые имеют дочерние узлы)
1303 IgorA 1761
align 4
5879 IgorA 1762
proc tl_node_close_open uses eax edx edi, tlist:dword
1763
	mov edi,dword[tlist]
5911 IgorA 1764
	call tl_get_cur_node_index ;eax = позиция узла на котором стоит курсор
1765
	cmp eax,2 ;курсор стоит на узле ?
1766
	jl @f
1767
		imul eax,sizeof.TreeList
1768
		add eax,tl_data_nodes
1769
		;eax = указатель на структуру узла выбранного курсором
1770
		push eax
1771
			stdcall tl_node_poi_get_next_info, edi,eax
1772
			mov edx,eax ;edx = указатель на структуру узла который идет после узла eax
1773
		pop eax
1774
		cmp edx,0 ;есть ли узлы ниже выбранного нами ?
1775
		je @f
1776
			mov dl,byte[edx+2] ;берем уровень нижнего узла
1777
			cmp byte[eax+2],dl ;+2 = .lev
1778
			jge @f ;если нижние узлы меньшего уровня, значит они не дочерние, конец функции
1779
				xor byte[eax+3],1 ;+3 = .clo *** открытие/закрытие узла ***
1780
				call tb_scrol_resize ;обработка скроллинга
1277 IgorA 1781
 
5911 IgorA 1782
				stdcall tl_draw, edi ;обновление окна
1783
	@@:
5879 IgorA 1784
	ret
1785
endp
1277 IgorA 1786
 
5911 IgorA 1787
;увеличить уровень
1277 IgorA 1788
align 4
5879 IgorA 1789
proc tl_node_lev_inc uses eax ecx edx edi, tlist:dword
5911 IgorA 1790
	mov edi,dword[tlist]
1791
	bt tl_style,2 ;tl_list_box_mode
1792
	jc @f
1793
	call tl_get_cur_node_index ;eax=po_t
1794
	cmp eax,2
1795
	jl @f
1796
		mov ecx,tl_data_nodes
1797
		imul eax,sizeof.TreeList
1798
		add eax,ecx ;eax = pointer to some node struct
1799
		add ecx,sizeof.TreeList ;ecx = pointer to 1 node struct
1401 IgorA 1800
 
5911 IgorA 1801
		mov edx,eax
1802
		call tl_iterat_perv ;проверяем есть ли верхний узел
1803
		cmp edx,ecx
1804
		jle @f ;если верхнего узла нет то текущий узел не двигаем
1805
		mov cl,byte[edx+2] ;берем уровень родительского узла
1806
		inc cl ;добавляем 1 и получаем максимальное значение
1807
		cmp byte[eax+2],cl
1808
		jge @f
1809
			inc byte[eax+2] ;увеличиваем значение узла
1810
	@@:
5879 IgorA 1811
	ret
1812
endp
1277 IgorA 1813
 
5911 IgorA 1814
;уменьшить уровень
1277 IgorA 1815
align 4
5879 IgorA 1816
proc tl_node_lev_dec uses eax edi, tlist:dword
1817
	mov edi,dword[tlist]
5911 IgorA 1818
	call tl_get_cur_node_index ;eax=po_t
1819
	cmp eax,2
1820
	jl @f
1821
		imul eax,sizeof.TreeList
1822
		add eax,tl_data_nodes
1823
		cmp byte[eax+2],0
1824
		je @f
1825
		dec byte[eax+2]
1826
	@@:
5879 IgorA 1827
	ret
1828
endp
1277 IgorA 1829
 
5911 IgorA 1830
;перемещаем узел вверх
1285 IgorA 1831
align 4
5914 IgorA 1832
proc tl_node_move_up tlist:dword
1833
pushad
5911 IgorA 1834
	mov edi,dword[tlist]
1835
	call tl_get_cur_node_index ;eax=po_t
1836
	cmp eax,2
1837
	jl @f
1838
		mov ebx,eax ;copy index of node struct
1839
		mov edx,tl_data_nodes
1840
		mov ecx,edx
1841
		add ecx,sizeof.TreeList
1842
		imul eax,sizeof.TreeList
1843
		add eax,edx ;eax = pointer to 2 node struct
1844
		mov edx,eax ;edx = pointer to 2 node struct
1845
		mov esi,eax ;esi = pointer to 2 node struct
1846
		call tl_iterat_perv ;edx = pointer to 1 node struct
1847
		call tl_get_node_index ;eax = index of 1 node struct
1848
		cmp edx,ecx
1849
		jle @f
1850
			cmp dword[edx+8],ebx ;+8 next
1851
			jne .po8
1852
				call tl_node_move_po6 ;узлы идут подряд меняем 6 ссылок
1853
				jmp .cur_mov
1854
			.po8:
1855
				call tl_node_move_po8 ;узлы идут не подряд меняем 8 ссылок
1856
			.cur_mov:
1857
				push dword edi
1858
				call tl_cur_perv
1859
				push dword edi
1860
				call tl_draw
1861
	@@:
5914 IgorA 1862
popad
5879 IgorA 1863
	ret
1864
endp
1285 IgorA 1865
 
5911 IgorA 1866
;перемещаем узел вниз
1285 IgorA 1867
align 4
5914 IgorA 1868
proc tl_node_move_down tlist:dword
1869
pushad
5911 IgorA 1870
	mov edi,dword[tlist]
1871
	call tl_get_cur_node_index ;eax=po_t
1872
	cmp eax,2
1873
	jl @f
1874
		mov ebx,eax ;copy index of node struct
1875
		mov edx,tl_data_nodes
1876
		mov ecx,edx
1877
		add ecx,sizeof.TreeList
1878
		imul eax,sizeof.TreeList
1879
		add eax,edx ;eax = pointer to 1 node struct
1880
		mov edx,eax ;edx = pointer to 1 node struct
1881
		mov esi,eax ;esi = pointer to 1 node struct
1882
		call tl_iterat_next ;edx = pointer to 2 node struct
1883
		call tl_get_node_index ;eax = index of 2 node struct
1884
		cmp edx,ecx
1885
		jle @f
1886
			cmp dword[esi+8],eax ;+8 next
1887
			jne .po8
1888
				xchg eax,ebx ;меняе порядок следования заменяемых узлов
1889
				xchg edx,esi
1890
				call tl_node_move_po6 ;узлы идут подряд меняем 6 ссылок
1891
				jmp .cur_mov
1892
			.po8: ;а тут порядок следования узлов не меняем
1893
				call tl_node_move_po8 ;узлы идут не подряд меняем 8 ссылок
1894
			.cur_mov:
1895
				stdcall tl_cur_next, edi
1896
				stdcall tl_draw, edi
1897
	@@:
5879 IgorA 1898
	ret
5914 IgorA 1899
popad
5879 IgorA 1900
endp
1285 IgorA 1901
 
1902
align 4
1903
tl_node_move_po6:
5914 IgorA 1904
	mov ecx,edx ;save node pointer
1905
	call tl_move_perv
1906
	mov dword[edx+8],ebx
1285 IgorA 1907
 
5914 IgorA 1908
	mov edx,esi
1909
	call tl_move_next
1910
	mov dword[edx+4],eax
1911
	mov edx,ecx ;restore node pointer
1285 IgorA 1912
 
5914 IgorA 1913
	;+4 perv
1914
	mov ecx,dword[edx+4]
1915
	mov dword[esi+4],ecx
1916
	;+8 next
1917
	mov ecx,dword[esi+8]
1918
	mov dword[edx+8],ecx
1285 IgorA 1919
 
5914 IgorA 1920
	mov dword[edx+4],ebx
1921
	mov dword[esi+8],eax
1922
	ret
1285 IgorA 1923
 
1924
;input
1925
;eax = index 1 node struct
1926
;ebx = index 2 node struct
1927
;edx = pointer 1 node struct
1928
;esi = pointer 2 node struct
1929
;edi = pointer to 'TreeList' struct
1930
;output:
1931
;eax = ?
1932
;ebx = ?
1933
;ecx = ?
1934
align 4
1935
tl_node_move_po8:
5914 IgorA 1936
	mov ecx,edx ;save node pointer
1937
	call tl_move_perv
1938
	mov dword[edx+8],ebx
1939
	mov edx,ecx
1940
	call tl_move_next
1941
	mov dword[edx+4],ebx
1942
	mov edx,esi
1943
	call tl_move_perv
1944
	mov dword[edx+8],eax
1945
	mov edx,esi
1946
	call tl_move_next
1947
	mov dword[edx+4],eax
1948
	mov edx,ecx ;restore node pointer
1285 IgorA 1949
 
5914 IgorA 1950
	;+4 perv
1951
	mov eax,dword[edx+4]
1952
	mov ebx,dword[esi+4]
1953
	xchg eax,ebx
1954
	mov dword[edx+4],eax
1955
	mov dword[esi+4],ebx
1956
	;+8 next
1957
	mov eax,dword[edx+8]
1958
	mov ebx,dword[esi+8]
1959
	xchg eax,ebx
1960
	mov dword[edx+8],eax
1961
	mov dword[esi+8],ebx
1962
	ret
1285 IgorA 1963
 
1964
;input:
1965
; edi = pointer to 'TreeList' struct
1966
align 4
1967
tl_draw_caption_cur_pos:
5911 IgorA 1968
	cmp tl_capt_cy,9 ;9 - minimum caption height
1969
	jl @f
1970
	pushad
1971
		mov ebx,edi ;calculate cursor position
1972
		mov eax,tl_cur_pos
1973
		inc eax
1974
		lea edi,[txt_capt_cur]
1975
		add edi,7
1976
		call tl_convert_to_str
1977
		mov edi,ebx
1309 IgorA 1978
 
5911 IgorA 1979
		mov ebx,tl_box_left
1980
		shl ebx,16
1981
		add ebx,5*65536+3
1982
		add ebx,tl_box_top
1983
		mov ecx,tl_col_txt
1984
		or  ecx,0xc0000000 ;0x40000000 закрашивать фон цветом edi
1985
		lea edx,[txt_capt_cur]
1986
		mov edi,tl_col_zag
1987
		mcall 4 ;draw text captions
1309 IgorA 1988
 
5911 IgorA 1989
	popad
1990
	@@:
1991
	ret
1285 IgorA 1992
 
1303 IgorA 1993
;input:
5911 IgorA 1994
; tlist - pointer to 'TreeList' struct
1995
; opt - options: 0 - first element, 1 - add next element
1996
; h_mem - pointer to memory
1997
; mem_size - memory size
1303 IgorA 1998
;output:
5911 IgorA 1999
; eax - error code
1303 IgorA 2000
align 4
5911 IgorA 2001
proc tl_save_mem uses ebx ecx edx edi esi, tlist:dword, opt:dword, h_mem:dword, mem_size:dword
2002
	mov esi,dword[h_mem]
2003
	mov edi,dword[tlist]
1303 IgorA 2004
 
5911 IgorA 2005
	cmp dword[opt],0 ;add mode
2006
	je @f
2007
		stdcall tl_get_mem_size, edi,esi ;eax = размер ранее сохранённых данных
2008
		add esi,eax
2009
	@@:
1303 IgorA 2010
 
5911 IgorA 2011
	xor ebx,ebx
2012
	mov bx,tl_info_size
1303 IgorA 2013
 
5911 IgorA 2014
	call tl_get_node_count_all ;eax = all node count
1303 IgorA 2015
 
5911 IgorA 2016
	mov ecx,eax  ;вычисляем сколько памяти должно быть заполнено
2017
	imul ecx,ebx ;умножаем на размер структуры узла
2018
	add ecx,tl_save_load_heder_size+1 ;element header +1 end element sumbol
2019
	add ecx,esi  ;добавляем указатель на начало памяти (с учетом ранее записанных структур)
2020
	sub ecx,dword[h_mem] ;отнимаем указатель на начало памяти (без ранее записанных структур)
2021
	cmp ecx,dword[mem_size] ;ecx = element memory size
2022
	jg .err_mem_size
1303 IgorA 2023
 
5911 IgorA 2024
		;save tree params (in header)
2025
		mov dword[esi],'tree'
2026
		mov word[esi+4],bx
2027
		mov dword[esi+6],eax ;element count
1303 IgorA 2028
 
5911 IgorA 2029
		mov eax,tl_style
2030
		mov dword[esi+10],eax
1303 IgorA 2031
 
5911 IgorA 2032
		mov eax,tl_cur_pos
2033
		mov dword[esi+14],eax
1303 IgorA 2034
 
5911 IgorA 2035
		mov ax,tl_info_capt_offs
2036
		mov word[esi+18],ax
1303 IgorA 2037
 
5911 IgorA 2038
		mov ax,tl_info_capt_len
2039
		mov word[esi+20],ax
1303 IgorA 2040
 
5911 IgorA 2041
		;copy scroll position
2042
		mov edx,tl_p_scroll
2043
		mov eax,dword[edx+sb_offs_position]
2044
		mov dword[esi+22],eax
1309 IgorA 2045
 
5911 IgorA 2046
		add esi,tl_save_load_heder_size ;add header size
1309 IgorA 2047
 
5911 IgorA 2048
		;cycle to nodes
2049
		mov edx,tl_data_nodes
2050
		mov ecx,edx
2051
		add ecx,sizeof.TreeList
2052
		@@:
2053
			call tl_iterat_next_all
2054
			cmp edx,ecx
2055
			jle @f
2056
		;save node params
2057
		call tl_get_node_index ;eax = index of pointer [edx]
2058
		mov dword[esi],eax
1303 IgorA 2059
 
5911 IgorA 2060
		add esi,4
2061
		mov eax,dword[edx] ;eax = (type; lev; clo)
2062
		mov dword[esi],eax
2063
		add esi,4
1303 IgorA 2064
 
5911 IgorA 2065
			stdcall tl_node_poi_get_data, edi,edx ;eax - pointer node data
1303 IgorA 2066
 
5911 IgorA 2067
		;call tl_node_copy_data
2068
		push ecx edi
2069
		mov edi,eax
2070
		mov ecx,ebx
2071
		xchg esi,edi
2072
		rep movsb
2073
		mov esi,edi
2074
		pop edi ecx
2075
		;add esi,ebx
2076
		jmp @b
2077
	@@:
2078
	mov byte[esi],0 ;end of 'treelist'
2079
		xor eax,eax ;return error code
2080
	jmp @f
2081
	.err_mem_size:
2082
		mov eax,tl_err_save_memory_size
2083
	@@:
2084
	ret
2085
endp
1303 IgorA 2086
 
2087
;input:
5911 IgorA 2088
; tlist - pointer to 'TreeList' struct
2089
; opt   - options: element index + (2*(add mode)+(init mode)) shl 16
2090
; h_mem - pointer to memory
2091
; mem_size - memory size
2092
;   размер памяти, пока не используется (назначался для контроля)
2093
;   для его использования нужно доработать функцию
1303 IgorA 2094
;output:
5911 IgorA 2095
; eax - error code
2096
;memory header format:
2097
;  +0 - (4) 'tree'
2098
;  +4 - (2) info size
2099
;  +6 - (4) count nodes
2100
; +10 - (4) tlist style
2101
; +14 - (4) cursor pos
2102
; +18 - (2) info capt offs
2103
; +20 - (2) info capt len
2104
; +22 - (4) scroll pos
2105
;memory data format:
2106
; +26 - (info size + 8) * count nodes
1303 IgorA 2107
align 4
5911 IgorA 2108
proc tl_load_mem uses ebx ecx edx edi esi, tlist:dword, opt:dword, h_mem:dword, mem_size:dword
2109
locals
2110
	er_code dd ?
2111
endl
2112
	mov esi,dword[h_mem]
2113
	mov edi,dword[tlist]
1303 IgorA 2114
 
5911 IgorA 2115
	mov dword[er_code],0 ;return error code
1303 IgorA 2116
 
5911 IgorA 2117
	mov ecx,dword[opt]
2118
	cmp cx,0 ;load in array mode
2119
	je @f
2120
		;stdcall tl_get_mem_size, esi,edi ;берем размер ранее сохранённых данных
2121
		;add esi,eax
2122
		and ecx,0xffff
2123
		cld
2124
		.beg_cycle:
2125
			cmp dword[esi],'tree'
2126
			jne .no_tree
2127
			xor ebx,ebx
2128
			mov bx,word[esi+4]
2129
			add bx,8
2130
			imul ebx,dword[esi+6]
2131
			add ebx,tl_save_load_heder_size
2132
			add esi,ebx
2133
			loop .beg_cycle
2134
	@@:
1303 IgorA 2135
 
5911 IgorA 2136
	cmp dword[esi],'tree'
2137
	jne .no_tree
2138
		bt dword[opt],17 ;load in add mode
2139
		jc @f
2140
			stdcall tl_info_clear, dword edi
2141
		@@:
1303 IgorA 2142
 
5911 IgorA 2143
		xor ebx,ebx
2144
		mov bx,word[esi+4] ;info_size
2145
		cmp bx,tl_info_size
2146
		je @f
2147
			or dword[er_code],tl_err_load_info_size
2148
		@@:
2149
		mov ecx,dword[esi+6] ;count nodes
2150
		cmp ecx,1
2151
		jl .end_f
2152
		mov edx,esi ;save header pointer
2153
		add esi,tl_save_load_heder_size
1303 IgorA 2154
 
5879 IgorA 2155
		cld
2156
		@@: ;load node params
5911 IgorA 2157
			mov eax,dword[esi+4]
5879 IgorA 2158
			ror eax,16 ;eax - options (type; lev; clo)
5911 IgorA 2159
			add esi,8
2160
			stdcall tl_node_add, edi,eax,esi
5879 IgorA 2161
			stdcall tl_cur_next, edi
1303 IgorA 2162
;...
5911 IgorA 2163
			add esi,ebx
2164
			loop @b
1303 IgorA 2165
 
5911 IgorA 2166
		bt dword[opt],17 ;load in add mode
2167
		jc .no_tree
2168
			mov eax,dword[edx+14] ;set cursor pos
2169
			mov tl_cur_pos,eax
2170
			mov ebx,tl_p_scroll
2171
			cmp ebx,0
2172
			je .end_f
2173
				mov eax,dword[edx+22] ;set scroll pos
2174
				mov dword[ebx+sb_offs_position],eax
5879 IgorA 2175
				stdcall scroll_bar_vertical.draw, ebx
5911 IgorA 2176
				jmp .end_f
2177
	.no_tree:
2178
	mov dword[er_code],tl_err_load_caption
2179
	.end_f:
2180
	mov eax,dword[er_code]
2181
	ret
2182
endp
1303 IgorA 2183
 
5911 IgorA 2184
;берет размер памяти занятой функцией tl_save_mem при сохранении элементов
1328 IgorA 2185
;output:
5911 IgorA 2186
; eax - error code
1328 IgorA 2187
align 4
5911 IgorA 2188
proc tl_get_mem_size uses ebx edi, tlist:dword, h_mem:dword
2189
	mov edi,dword[tlist]
2190
	mov eax,dword[h_mem]
2191
	@@:
2192
		cmp dword[eax],'tree'
2193
		jne @f
2194
		xor ebx,ebx
2195
		mov bx,word[eax+4]
2196
		add bx,8 ;размер дополнительной информации об узле (индекс записи; индекс иконки, уровень, ...)
2197
		imul ebx,dword[eax+6]
2198
		add ebx,tl_save_load_heder_size
2199
		add eax,ebx
2200
		jmp @b
2201
	@@:
2202
	sub eax,dword[h_mem] ;отнимаем указатель на начало памяти
2203
		;и получаем размер блока памяти
2204
	ret
2205
endp
1328 IgorA 2206
 
2207
 
1303 IgorA 2208
;ascii scan key
2209
;  13    28 Enter
2210
;  32    57 Space
2211
; 178    72 Up
2212
; 177    80 Down
2213
; 176    75 Left
2214
; 179    77 Right
2215
; 182    83 Delete
2216
; 184    73 Pg Up
2217
; 183    81 Pg Dn
2218
 
2219
tl_key_ascii db 13,32,178,177,176,179,182,184,183
2220
tl_key_scan  db 28,57, 72, 80, 75, 77, 83, 73, 81
2221
 
1309 IgorA 2222
txt_capt_cur db 'Строка      ',0
2223
txt_capt_otm db 'Отмены      ',0
2224
 
5911 IgorA 2225
;этот код не мой, он преобразует число в строку
1309 IgorA 2226
;input:
2227
; eax = value
2228
; edi = string buffer
2229
align 4
2230
tl_convert_to_str:
5911 IgorA 2231
	pushad
2232
		mov dword[edi+1],0x20202020
2233
		call .str
2234
	popad
2235
	ret
1309 IgorA 2236
 
2237
align 4
2238
.str:
5948 IgorA 2239
	mov ecx,0x0a ;задается система счисления изменяются регистры ebx,eax,ecx,edx входные параметры eax - число
2240
		;преревод числа в ASCII строку взодные данные ecx=система счисленя edi адрес куда записывать, будем строку, причем конец переменной
2241
	cmp eax,ecx  ;сравнить если в eax меньше чем в ecx то перейти на @@-1 т.е. на pop eax
2242
	jb @f
2243
		xor edx,edx ;очистить edx
2244
		div ecx     ;разделить - остаток в edx
2245
		push edx    ;положить в стек
2246
		call .str   ;вызвать саму себя и так до того момента пока в eax не станет меньше чем в ecx
2247
		pop eax
2248
	@@: ;cmp al,10 ;проверить не меньше ли значение в al чем 10 (для системы счисленя 10 данная команда - лишная))
2249
	or al,0x30  ;данная команда короче  чем две выше
2250
	stosb       ;записать элемент из регистра al в ячеку памяти es:edi
2251
	ret         ;вернуться очень интересный ход т.к. пока в стеке храниться кол-во вызовов то столько раз мы и будем вызываться
1309 IgorA 2252
}