Subversion Repositories Kolibri OS

Rev

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