Subversion Repositories Kolibri OS

Rev

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