Subversion Repositories Kolibri OS

Rev

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