Subversion Repositories Kolibri OS

Rev

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

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