Subversion Repositories Kolibri OS

Rev

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