Subversion Repositories Kolibri OS

Rev

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