Subversion Repositories Kolibri OS

Rev

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