Subversion Repositories Kolibri OS

Rev

Rev 1390 | 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
1401 IgorA 3
; файл последний раз изменялся 09.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
 
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 ;копируем указатель на полученую память в структуру
1401 IgorA 136
    mov tl_data_img,0  ;обнуляем указатель 'data_img'
1277 IgorA 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]
1401 IgorA 177
    cmp tl_data_img,0
1277 IgorA 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 ;левая граница окна
1401 IgorA 330
    jl .no_in_wnd ;.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
1401 IgorA 576
    pushad
1277 IgorA 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:
1401 IgorA 673
    popad
1277 IgorA 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
  cmp tl_tim_undo,0
1309 IgorA 759
  je .beg1
1277 IgorA 760
 
761
  .beg0:
762
    call tl_move_perv
763
    cmp edx,ecx
764
    jle @f
765
    call tl_node_not_vis ;пропуск удаленных и отмененных
766
    cmp al,1
767
    je .beg0
768
 
1309 IgorA 769
  .beg1:
1277 IgorA 770
    call tl_move_perv
771
    cmp edx,ecx
1309 IgorA 772
    jle @f
1277 IgorA 773
    cmp dword[edx+16],0 ;td = 'time delete' -> пропуск удаленных
1309 IgorA 774
    jne .beg1
775
 
776
  @@:
777
    call tl_move_max_clo_par
778
  pop eax
1277 IgorA 779
  ret
780
 
1309 IgorA 781
 
1277 IgorA 782
;input:
783
; edx = pointer to some node struct
784
; edi = pointer to 'TreeList' struct
785
;output:
1309 IgorA 786
; edx = pointer closed parent node with maximum level
787
align 4
788
tl_move_max_clo_par: ;находит родительский закрытый узел максимального уровня
789
  push eax ebx
790
  mov eax,edx
791
  xor ebx,ebx
792
  .beg:
793
    call tl_move_par
794
    cmp byte[edx+3],1 ;родительский узел закрыт ?
795
    jne @f
796
      mov eax,edx
797
    @@:
798
    cmp ebx,edx
799
    je .end_f
800
      mov ebx,edx
801
    jmp .beg
802
  .end_f:
803
  mov edx,eax
804
  pop ebx eax
805
  ret
806
 
807
;input:
808
; edx = pointer to some node struct
809
; edi = pointer to 'TreeList' struct
810
;output:
1277 IgorA 811
; edx = pointer to next node struct
812
align 4
813
tl_move_next:
814
  mov edx,dword[edx+8]
815
  imul edx,sizeof.TreeList
1283 IgorA 816
  add edx,tl_data_nodes
1277 IgorA 817
  ret
818
 
819
;input:
820
; edx = pointer to some node struct
821
; edi = pointer to 'TreeList' struct
822
;output:
823
; edx = pointer to perv node struct
824
align 4
825
tl_move_perv:
826
  mov edx,dword[edx+4]
827
  imul edx,sizeof.TreeList
1283 IgorA 828
  add edx,tl_data_nodes
1277 IgorA 829
  ret
830
 
831
;input:
1309 IgorA 832
; ecx =
833
; edx = pointer to some node struct
834
; edi = pointer to 'TreeList' struct
835
;output:
836
; edx = pointer to parent node struct
837
align 4
838
tl_move_par: ;передвигаемся на родительский узел, если такого нет, то оставляем старое значение указателя
839
 cmp byte[edx+2],0
840
 je .end_f ;узел 0-го уровня не может быть дочерним
841
 push eax ebx esi
842
 mov esi,edx ;copy node pointer (edx)
843
 mov bl,byte[edx+2]
844
 @@:
845
   call tl_move_perv
846
   cmp edx,ecx
847
   jle @f ;все выше стоящие узлы не родительские
848
   call tl_node_not_vis ;пропуск удаленных и отмененных
849
   cmp al,1
850
   je @b
851
   cmp byte[edx+2],bl
852
   jl .end_0 ;удачно нашли родительский узел
853
   jmp @b
854
 @@:
855
   mov esi,ebx ;restore node pointer
856
 .end_0:
857
 pop esi ebx eax
858
 .end_f:
859
 ret
860
 
861
;input:
1277 IgorA 862
; edx = pointer to symbol struct
863
; edi = pointer to 'TreeList' struct
864
;output:
865
; al = 1 if sumbol not visible
1283 IgorA 866
; (node[i].td+tim_Undo<=ch_tim && node[i].td) || (node[i].tc>ch_tim-tim_Undo)
1277 IgorA 867
align 4
868
tl_node_not_vis:
869
  cmp dword[edx+16],0
870
  je @f
1283 IgorA 871
  mov eax,dword[edx+16] ;eax=node[i].td
1277 IgorA 872
  add eax,tl_tim_undo
873
  cmp eax,tl_ch_tim
874
  jg @f
875
    mov al,1
876
    ret
877
  @@:
878
 
879
  mov eax,tl_ch_tim
880
  sub eax,tl_tim_undo
881
  cmp dword[edx+12],eax ;tc -> time create
882
  jle @f
883
    mov al,1
884
    ret
885
  @@:
886
  xor al,al
887
  ret
888
 
889
 
890
;input:
891
; edi = pointer to TreeInfo struct
892
; esi = coord bottom border
893
align 4
894
tl_draw_cursor: ;рисуем курсор на экране
895
  push eax ebx ecx edx esi
896
    call tl_get_display_cur_pos ;eax = cursor pos in screen
897
    cmp eax,0
898
    jl .end_f ;курсор находится выше окна, в области прокрученной скроллингом
899
 
900
    cmp tl_data_img_sys,0 ;смотрим есть ли указатель на картинку системных иконок
901
    jne @f
902
      mov ebx,tl_box_left
903
      shl ebx,16
904
      mov bx,tl_img_cx
905
      xor ecx,ecx
906
      mov cx,tl_img_cy
907
      imul ecx,eax
908
      add ecx,tl_box_top
909
      add cx,tl_capt_cy
910
 
911
      ;crop image if on the border
912
      cmp esi,ecx ;если курсор внизу и его вообще не видно
913
      jl .end_f
914
 
915
      sub esi,ecx
916
      shl ecx,16
917
      mov cx,tl_img_cy
918
      cmp si,tl_img_cy
919
      jge .crop0
920
        mov cx,si ;если курсор виден частично (попал на нижнюю границу)
921
      .crop0:
922
 
923
      mov edx,tl_col_txt
924
      mov eax,13
925
      int 0x40 ;рисуем простой прямоугольник, т.к. нет системных иконок
926
      jmp .end_f
927
    @@:
928
      mov ebx,tl_data_img_sys
929
      imul ax,tl_img_cy
930
      mov edx,tl_box_left
931
      shl edx,16
932
      mov dx,ax
933
      add edx,tl_box_top
934
      add dx,tl_capt_cy
935
 
1309 IgorA 936
      mov ecx,tl_el_focus ;проверяем в фокусе элемент или нет
937
      cmp dword[ecx],edi
938
      je .focus
939
        xor eax,eax
940
        xor ecx,ecx
941
        mov cx,tl_img_cx
942
        mov ax,tl_img_cy
943
        imul eax,ecx
944
        imul eax,4*3 ;4=icon index 3=rgb
945
        add ebx,eax
946
      .focus:
947
 
948
      mov cx,tl_img_cx
949
      shl ecx,16
950
      mov cx,tl_img_cy
951
 
1277 IgorA 952
      ;crop image if on the border
953
      cmp si,dx ;если курсор внизу и его вообще не видно
954
      jl .end_f
955
 
956
      sub si,dx
957
      cmp si,tl_img_cy
958
      jge .crop1
959
	mov cx,si ;если курсор виден частично (попал на нижнюю границу)
960
      .crop1:
961
 
962
      mov eax,7
963
      int 0x40 ;рисуем иконку курсора
964
    .end_f:
965
  pop esi edx ecx ebx eax
966
  ret
967
 
968
;input:
969
; edi = pointer to TreeInfo struct
970
; esi = coord bottom border
971
align 4
972
tl_draw_null_cursor: ;стираем курсор на экране
973
  push eax ebx ecx edx esi
974
    call tl_get_display_cur_pos ;eax = cursor pos in screen
975
    cmp eax,0
976
    jl .end_f ;курсор находится выше окна, в области прокрученной скроллингом
977
 
978
    mov ebx,tl_box_left
979
    shl ebx,16
980
    mov bx,tl_img_cx
981
    xor ecx,ecx
982
    mov cx,tl_img_cy
983
    imul ecx,eax
984
    add ecx,tl_box_top
985
    add cx,tl_capt_cy
986
 
987
    ;crop image if on the border
988
    cmp esi,ecx ;если курсор внизу и его вообще не видно
989
    jl .end_f
990
 
991
    sub esi,ecx
992
    shl ecx,16
993
    mov cx,tl_img_cy
994
    cmp si,tl_img_cy
995
    jge @f
996
      mov cx,si ;если курсор виден частично (попал на нижнюю границу)
997
    @@:
998
 
999
    mov edx,tl_col_bkg
1000
    mov eax,13
1001
    int 0x40 ;рисуем простой прямоугольник с фоновым цветом
1002
 
1003
    .end_f:
1004
  pop esi edx ecx ebx eax
1005
  ret
1006
 
1007
;input:
1008
; edi = pointer to TreeInfo struct
1009
;output:
1010
; eax = index
1011
align 4
1012
tl_get_display_cur_pos: ;берет позицию курсора, относительно экрана
1013
   mov eax,tl_cur_pos
1014
   cmp tl_p_scrol,0
1015
   je @f
1016
     push ebx
1017
       mov ebx,tl_p_scrol
1018
       mov ebx,dword[ebx+24]
1019
       sub eax,ebx ;отнимаем позицию скроллинга
1020
     pop ebx
1021
  @@:
1022
  ret
1023
 
1024
;input:
1025
; eax = node position
1026
; edx = pointer to some node struct
1401 IgorA 1027
; edi = pointer to 'TreeList' struct
1277 IgorA 1028
; esi = coord of bottom border
1029
align 4
1030
tl_draw_node:
1031
  push eax ebx ecx edx esi
1032
 
1033
    mov ebx,1 ;1 - место под курсор и под знак +,-
1034
    bt tl_style,2 ;tl_list_box_mode
1035
    jc @f
1036
      inc ebx ;+1 - место под знак +,-
1037
    @@:
1038
    add bl,byte[edx+2];get level
1039
    imul bx,tl_img_cx
1040
    add ebx,tl_box_left
1041
 
1042
    shl ebx,16
1043
    mov bx,tl_img_cx
1044
    xor ecx,ecx
1045
    mov cx,tl_img_cy
1046
    imul ecx,eax
1047
    add ecx,tl_box_top
1048
    add cx,tl_capt_cy
1049
 
1050
    ;crop image if on the border
1051
    cmp esi,ecx ;если узел внизу и его вообще не видно
1052
    jl .end_draw
1053
 
1054
    sub esi,ecx
1055
    shl ecx,16
1056
    mov cx,tl_img_cy
1057
    cmp si,tl_img_cy
1058
    jge @f
1059
      mov cx,si ;если узел виден частично (попал на нижнюю границу)
1060
      jmp .crop ;пропускаем рисование надписи, которая скорее всего тоже вылезет за нижнюю границу
1061
    @@:
1062
      call tl_draw_node_caption
1063
    .crop:
1064
    mov esi,ecx ;save ecx
1065
 
1401 IgorA 1066
    cmp tl_data_img,0
1277 IgorA 1067
    jne .draw_img_n
1068
    push edx
1069
      mov edx,tl_col_txt
1070
      mov eax,13
1071
      int 0x40 ;draw node rect
1072
    pop edx
1073
    jmp @f
1074
    .draw_img_n:
1075
    push ebx edx esi
1076
      xor esi,esi
1077
      mov si,word[edx] ;get icon type
1078
      mov edx,ebx
1079
      ror ecx,16
1080
      mov dx,cx
1081
      mov cx,bx
1082
      ror ecx,16
1083
      mov ebx,3 ;rgb = 3 bytes
1084
      imul bx,tl_img_cx
1085
      imul bx,tl_img_cy
1086
      imul ebx,esi ;esi = icon index
1401 IgorA 1087
      add ebx,tl_data_img
1277 IgorA 1088
 
1089
      mov eax,7
1090
      int 0x40 ;draw node icon '-'
1091
    pop esi edx ebx
1092
    @@:
1093
 
1094
    mov al,byte[edx+2] ;draw minus '-'
1283 IgorA 1095
    mov ecx,tl_data_nodes
1277 IgorA 1096
    add ecx,sizeof.TreeList
1097
 
1098
    mov ah,10 ;get icon index '+' or '-' ?
1099
    cmp byte[edx+3],1
1100
    jne .close
1101
      dec ah
1102
    .close:
1103
 
1104
    call tl_draw_node_icon_opn_clo
1105
    bt tl_style,1
1106
    jae .end_draw
1107
      call tl_draw_node_icon_par_lin
1309 IgorA 1108
      call tl_draw_node_icon_par_lin_up
1277 IgorA 1109
    .end_draw:
1110
  pop esi edx ecx ebx eax
1111
  ret
1112
 
1113
;input:
1114
; ecx = pointer to 1 node struct
1401 IgorA 1115
; edx = pointer to some node struct
1277 IgorA 1116
;...
1117
align 4
1285 IgorA 1118
tl_draw_node_icon_opn_clo: ;рисует иконки открытого или закрытого узла (обычно + или -)
1277 IgorA 1119
  push eax ebx ecx edx esi
1120
    inc al
1121
    call tl_iterat_next_all ;get next visible item
1122
    cmp edx,ecx
1123
    jle @f
1124
      mov ecx,esi ;load ecx
1125
      cmp al,byte[edx+2]
1126
      jne @f
1127
      ror ebx,16
1128
      sub bx,tl_img_cx
1129
      ror ebx,16
1130
      cmp tl_data_img_sys,0
1131
      jne .draw_img_s
1132
	mov edx,tl_col_txt
1133
	mov eax,13
1134
	int 0x40 ;draw minus rect, if not system icons
1135
	jmp @f
1136
      .draw_img_s:
1137
      mov ecx,esi ;load ecx
1138
      mov edx,ebx
1139
      ror ecx,16
1140
      mov dx,cx
1141
      mov cx,bx
1142
      ror ecx,16
1143
      mov ebx,3 ;rgb = 3 bytes
1144
      imul bx,tl_img_cx
1145
      imul bx,tl_img_cy
1146
      shr eax,8
1147
      and eax,0xff
1148
      imul ebx,eax ;eax = icon index
1149
      add ebx,tl_data_img_sys
1150
      mov eax,7
1151
      int 0x40 ;draw minus icon '-'
1152
    @@:
1153
  pop esi edx ecx ebx eax
1154
  ret
1155
 
1156
;input:
1309 IgorA 1157
; al = уровень элемента
1401 IgorA 1158
; ecx = pointer to 1 node struct
1159
; edx = pointer to some node struct
1277 IgorA 1160
;...
1161
align 4
1162
tl_draw_node_icon_par_lin:
1163
  cmp byte[edx+3],1
1164
  je .close
1165
  push eax ebx ecx edx esi
1166
    cmp al,0
1167
    je @f
1168
;    dec al
1169
;    call tl_iterat_perv ;get perv visible item
1170
 
1171
    call tl_iterat_next_all ;get next visible item
1172
    cmp edx,ecx
1173
    jle .line3 ;if end of list
1174
      cmp al,byte[edx+2]
1175
      jne .line3 ;jg ???
1176
      mov eax,3 ;line in middle element
1177
      jmp .line2
1178
    .line3:
1179
      mov eax,6 ;line in end element
1180
    .line2:
1181
 
1182
      mov ecx,esi ;load ecx
1183
      ror ebx,16
1184
      sub bx,tl_img_cx
1185
      ror ebx,16
1186
      cmp tl_data_img_sys,0
1187
      jne .draw_img_s
1188
	mov edx,tl_col_txt
1189
	mov eax,13
1190
	int 0x40 ;draw minus rect, if not system icons
1191
	jmp @f
1192
      .draw_img_s:
1309 IgorA 1193
;      mov ecx,esi ;load ecx
1277 IgorA 1194
      mov edx,ebx
1195
      ror ecx,16
1196
      mov dx,cx
1197
      mov cx,bx
1198
      ror ecx,16
1199
      mov ebx,3 ;rgb = 3 bytes
1200
      imul bx,tl_img_cx
1201
      imul bx,tl_img_cy
1202
 
1203
;      shr eax,8
1204
;      and eax,0xff
1205
      imul ebx,eax ;eax = icon index
1206
      add ebx,tl_data_img_sys
1207
      mov eax,7
1208
      int 0x40 ;draw line icon
1209
    @@:
1210
  pop esi edx ecx ebx eax
1211
  .close:
1212
  ret
1213
 
1309 IgorA 1214
 
1401 IgorA 1215
;input:
1309 IgorA 1216
; al = уровень элемента
1401 IgorA 1217
; ecx = pointer to 1 node struct
1218
; edx = pointer to some node struct
1219
; edi = pointer to 'TreeList' struct
1309 IgorA 1220
align 4
1221
tl_draw_node_icon_par_lin_up:
1401 IgorA 1222
  push eax ebx ecx edx
1223
  push esi
1309 IgorA 1224
    cmp tl_data_img_sys,0 ;if not image
1225
    je @f
1226
    cmp al,0
1227
    je @f
1228
 
1229
    xor esi,esi ;в si будем насчитывать кол-во иконок, нужных для прорисовки линии
1401 IgorA 1230
;--- цикл для вычисления колличества вертикальных линий ---
1309 IgorA 1231
    .cycle0:
1232
      call tl_iterat_perv ;get perv visible item
1233
      cmp edx,ecx
1234
      jle .cycle1 ;if begin of list
1235
 
1236
      cmp byte[edx+2],al
1401 IgorA 1237
      jle .cycle0end ;уровень верхнего элемента не требует прорисовки
1309 IgorA 1238
      inc si
1239
      jmp .cycle0
1401 IgorA 1240
    .cycle0end:
1309 IgorA 1241
      cmp si,0 ;si = кол-во иконок линии которые нужно нарисовать сверху
1242
      je @f
1243
      shl esi,16
1244
 
1245
      pop ecx ;esi->ecx
1246
      push ecx ;save esi
1247
 
1248
      ror ebx,16
1249
      sub bx,tl_img_cx
1250
      ror ebx,16
1251
 
1252
      mov edx,ebx
1253
      ror ecx,16
1254
      mov dx,cx
1255
      mov cx,bx
1256
      ror ecx,16
1257
      mov cx,tl_img_cy ;restore size y (if crop)
1258
      mov ebx,3 ;rgb = 3 bytes
1259
      imul bx,tl_img_cx
1260
      imul bx,tl_img_cy
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
1401 IgorA 1266
;--- цикл для рисования вертикальной линии ---
1267
      .cycle1:
1309 IgorA 1268
      sub dx,tl_img_cy ;поднимаем координату y вверх
1269
      cmp dx,si
1270
      jl @f
1271
        cmp esi,0x10000
1272
        jl @f
1273
        int 0x40 ;draw line icon
1274
        sub esi,0x10000 ;уменьшаем счетчик иконок
1401 IgorA 1275
      jmp .cycle1
1309 IgorA 1276
    @@:
1401 IgorA 1277
  pop esi
1278
  pop edx ecx ebx eax
1309 IgorA 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 ***
1401 IgorA 1473
	cmp eax,tl_info_max_count
1277 IgorA 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
1401 IgorA 2011
  push eax ecx edx edi
1277 IgorA 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
1401 IgorA 2018
      mov ecx,tl_data_nodes
1277 IgorA 2019
      imul eax,sizeof.TreeList
1401 IgorA 2020
      add eax,ecx ;eax = pointer to some node struct
2021
      add ecx,sizeof.TreeList ;ecx = pointer to 1 node struct
2022
 
1277 IgorA 2023
      mov edx,eax
1401 IgorA 2024
      call tl_iterat_perv ;проверяем есть ли верхний узел
2025
      cmp edx,ecx
2026
      jle @f ;если верхнего узла не то текущий узел не двигаем
2027
 
2028
      inc word[eax+2]
1277 IgorA 2029
    @@:
1401 IgorA 2030
  pop edi edx ecx eax
1277 IgorA 2031
  pop ebp
2032
  ret 4
2033
 
2034
align 4
2035
tl_node_lev_dec: ;уменьшить уровень
2036
  push ebp
2037
  mov ebp,esp
1401 IgorA 2038
  push eax edi
1277 IgorA 2039
    mov edi,dword[ebp+8]
2040
    call tl_get_cur_node_index ;eax=po_t
2041
    cmp eax,2
2042
    jl @f
2043
      imul eax,sizeof.TreeList
1283 IgorA 2044
      add eax,tl_data_nodes
1401 IgorA 2045
      cmp word[eax+2],0
1277 IgorA 2046
      je @f
1401 IgorA 2047
      dec word[eax+2]
1277 IgorA 2048
    @@:
1401 IgorA 2049
  pop edi eax
1277 IgorA 2050
  pop ebp
2051
  ret 4
2052
 
1285 IgorA 2053
align 4
2054
tl_node_move_up: ;перемещаем узел вверх
2055
  push ebp
2056
  mov ebp,esp
2057
  push eax ebx ecx edx edi esi
2058
    mov edi,dword[ebp+8]
2059
    call tl_get_cur_node_index ;eax=po_t
2060
    cmp eax,2
2061
    jl @f
2062
      mov ebx,eax ;copy index of node struct
2063
      mov edx,tl_data_nodes
2064
      mov ecx,edx
2065
      add ecx,sizeof.TreeList
2066
      imul eax,sizeof.TreeList
2067
      add eax,edx ;eax = pointer to 2 node struct
2068
      mov edx,eax ;edx = pointer to 2 node struct
2069
      mov esi,eax ;esi = pointer to 2 node struct
2070
      call tl_iterat_perv ;edx = pointer to 1 node struct
2071
      call tl_get_node_index ;eax = index of 1 node struct
2072
      cmp edx,ecx
2073
      jle @f
2074
        cmp dword[edx+8],ebx ;+8 next
2075
        jne .po8
2076
          call tl_node_move_po6 ;узлы идут подряд меняем 6 ссылок
2077
          jmp .cur_mov
2078
        .po8:
2079
          call tl_node_move_po8 ;узлы идут не подряд меняем 8 ссылок
2080
        .cur_mov:
2081
          push dword edi
2082
          call tl_cur_perv
2083
          push dword edi
2084
          call tl_draw
2085
    @@:
2086
  pop esi edi edx ecx ebx eax
2087
  pop ebp
2088
  ret 4
2089
 
2090
align 4
2091
tl_node_move_down: ;перемещаем узел вниз
2092
  push ebp
2093
  mov ebp,esp
2094
  push eax ebx ecx edx edi esi
2095
    mov edi,dword[ebp+8]
2096
    call tl_get_cur_node_index ;eax=po_t
2097
    cmp eax,2
2098
    jl @f
2099
      mov ebx,eax ;copy index of node struct
2100
      mov edx,tl_data_nodes
2101
      mov ecx,edx
2102
      add ecx,sizeof.TreeList
2103
      imul eax,sizeof.TreeList
2104
      add eax,edx ;eax = pointer to 1 node struct
2105
      mov edx,eax ;edx = pointer to 1 node struct
2106
      mov esi,eax ;esi = pointer to 1 node struct
2107
      call tl_iterat_next ;edx = pointer to 2 node struct
2108
      call tl_get_node_index ;eax = index of 2 node struct
2109
      cmp edx,ecx
2110
      jle @f
2111
        cmp dword[esi+8],eax ;+8 next
2112
        jne .po8
2113
          xchg eax,ebx ;меняе порядок следования заменяемых узлов
2114
          xchg edx,esi
2115
          call tl_node_move_po6 ;узлы идут подряд меняем 6 ссылок
2116
          jmp .cur_mov
2117
        .po8: ;а тут порядок следования узлов не меняем
2118
          call tl_node_move_po8 ;узлы идут не подряд меняем 8 ссылок
2119
        .cur_mov:
2120
          push dword edi
2121
          call tl_cur_next
2122
          push dword edi
2123
          call tl_draw
2124
    @@:
2125
  pop esi edi edx ecx ebx eax
2126
  pop ebp
2127
  ret 4
2128
 
2129
align 4
2130
tl_node_move_po6:
2131
  mov ecx,edx ;save node pointer
2132
  call tl_move_perv
2133
  mov dword[edx+8],ebx
2134
 
2135
  mov edx,esi
2136
  call tl_move_next
2137
  mov dword[edx+4],eax
2138
  mov edx,ecx ;restore node pointer
2139
 
2140
  ;+4 perv
2141
  mov ecx,dword[edx+4]
2142
  mov dword[esi+4],ecx
2143
  ;+8 next
2144
  mov ecx,dword[esi+8]
2145
  mov dword[edx+8],ecx
2146
 
2147
  mov dword[edx+4],ebx
2148
  mov dword[esi+8],eax
2149
  ret
2150
 
2151
;input
2152
;eax = index 1 node struct
2153
;ebx = index 2 node struct
2154
;edx = pointer 1 node struct
2155
;esi = pointer 2 node struct
2156
;edi = pointer to 'TreeList' struct
2157
;output:
2158
;eax = ?
2159
;ebx = ?
2160
;ecx = ?
2161
align 4
2162
tl_node_move_po8:
2163
;  push ecx
2164
  mov ecx,edx ;save node pointer
2165
  call tl_move_perv
2166
  mov dword[edx+8],ebx
2167
  mov edx,ecx
2168
  call tl_move_next
2169
  mov dword[edx+4],ebx
2170
  mov edx,esi
2171
  call tl_move_perv
2172
  mov dword[edx+8],eax
2173
  mov edx,esi
2174
  call tl_move_next
2175
  mov dword[edx+4],eax
2176
  mov edx,ecx ;restore node pointer
2177
;  pop ecx
2178
 
2179
  ;+4 perv
2180
  mov eax,dword[edx+4]
2181
  mov ebx,dword[esi+4]
2182
  xchg eax,ebx
2183
  mov dword[edx+4],eax
2184
  mov dword[esi+4],ebx
2185
  ;+8 next
2186
  mov eax,dword[edx+8]
2187
  mov ebx,dword[esi+8]
2188
  xchg eax,ebx
2189
  mov dword[edx+8],eax
2190
  mov dword[esi+8],ebx
2191
  ret
2192
 
2193
;input:
2194
; edi = pointer to 'TreeList' struct
2195
align 4
2196
tl_draw_caption_cur_pos:
2197
  cmp tl_capt_cy,9 ;9 - minimum caption height
2198
  jl @f
2199
  push eax ebx ecx edx edi esi
1309 IgorA 2200
    mov ebx,edi ;calculate cursor position
2201
    mov eax,tl_cur_pos
2202
    inc eax
2203
    lea edi,[txt_capt_cur]
2204
    add edi,7
2205
    call tl_convert_to_str
2206
    mov edi,ebx
2207
 
2208
    mov eax,4 ;draw text captions
2209
    mov ebx,tl_box_left
2210
    shl ebx,16
2211
    add ebx,5*65536+3
2212
    add ebx,tl_box_top
2213
    mov ecx,tl_col_txt
2214
    or	ecx,0xc0000000 ;0x40000000 закрашивать фон цветом edi
2215
    lea edx,[txt_capt_cur]
1285 IgorA 2216
    mov edi,tl_col_zag
2217
    int 0x40
1309 IgorA 2218
 
1285 IgorA 2219
  pop esi edi edx ecx ebx eax
2220
  @@:
2221
  ret
2222
 
1303 IgorA 2223
;input:
2224
;dword[ebp+ 8] - memory size
2225
;dword[ebp+12] - pointer to memory
2226
;dword[ebp+16] - options: 0 - first element, 1 - add next element
2227
;dword[ebp+20] - pointer to 'TreeList' struct
2228
;output:
2229
;dword[ebp+ 8] - error code
2230
align 4
2231
tl_save_mem:
2232
  push ebp
2233
  mov ebp,esp
2234
    push eax ebx ecx edx edi esi
2235
    mov esi,dword[ebp+12]
2236
    mov edi,dword[ebp+20]
2237
 
2238
    cmp dword[ebp+16],0 ;add mode
2239
    je @f
1328 IgorA 2240
      push dword edi
2241
      push dword esi
2242
      call tl_get_mem_size ;берем размер ранее сохранённых данных
2243
      pop ebx
1303 IgorA 2244
      add esi,ebx
2245
    @@:
2246
 
2247
    xor ebx,ebx
2248
    mov bx,tl_info_size
2249
 
2250
    call tl_get_node_count_all ;eax = all node count
2251
 
2252
    mov ecx,eax  ;вычисляем сколько памяти должно быть заполнено
2253
    imul ecx,ebx ;умножаем на размер структуры узла
2254
    add ecx,tl_save_load_heder_size+1 ;element header +1 end element sumbol
2255
    add ecx,esi  ;добавляем указатель на начало памяти (с учетом ранее записанных структур)
2256
    sub ecx,dword[ebp+12] ;отнимаем указатель на начало памяти (без ранее записанных структур)
2257
    cmp ecx,dword[ebp+8]  ;ecx = element memory size
2258
    jg .err_mem_size
2259
 
1309 IgorA 2260
    ;save tree params (in header)
1303 IgorA 2261
    mov dword[esi],0x65657274 ;0x65657274 = 'tree'
2262
    mov word[esi+4],bx
2263
    mov dword[esi+6],eax ;element count
2264
 
2265
    mov eax,tl_style
1309 IgorA 2266
    mov dword[esi+10],eax
1303 IgorA 2267
 
2268
    mov eax,tl_cur_pos
1309 IgorA 2269
    mov dword[esi+14],eax
1303 IgorA 2270
 
2271
    mov ax,tl_info_capt_offs
1309 IgorA 2272
    mov word[esi+18],ax
1303 IgorA 2273
 
2274
    mov ax,tl_info_capt_len
1309 IgorA 2275
    mov word[esi+20],ax
1303 IgorA 2276
 
1309 IgorA 2277
    ;copy scroll position
2278
    mov edx,tl_p_scrol
2279
    mov eax,dword[edx+24] ;+24 .position
2280
    mov dword[esi+22],eax
2281
 
2282
    add esi,tl_save_load_heder_size ;add header size
2283
 
1303 IgorA 2284
    ;cycle to nodes
2285
    mov edx,tl_data_nodes
2286
    mov ecx,edx
2287
    add ecx,sizeof.TreeList
2288
    @@:
2289
      call tl_iterat_next_all
2290
      cmp edx,ecx
2291
      jle @f
2292
;save node params
2293
call tl_get_node_index ;eax = index of pointer [edx]
2294
mov dword[esi],eax
2295
 
2296
add esi,4
2297
mov eax,dword[edx] ;eax = (type; lev; clo)
2298
mov dword[esi],eax
2299
add esi,4
2300
 
2301
push dword edi
2302
push dword edx
2303
call tl_node_poi_get_data
2304
pop dword eax
2305
 
2306
;call tl_node_copy_data
2307
push ecx edi
2308
  mov edi,eax
2309
  mov ecx,ebx
2310
  xchg esi,edi
2311
  rep movsb
2312
  mov esi,edi
2313
pop edi ecx
2314
;add esi,ebx
2315
      jmp @b
2316
    @@:
2317
    mov byte[esi],0 ;end of 'treelist'
2318
    mov dword[ebp+20],0 ;return error code
2319
    jmp @f
2320
      .err_mem_size:
2321
      or dword[ebp+20],tl_err_save_memory_size
2322
    @@:
2323
    pop esi edi edx ecx ebx eax
2324
  pop ebp
2325
  ret 12
2326
 
2327
;input:
2328
;dword[ebp+ 8] - memory size
2329
;dword[ebp+12] - pointer to memory
2330
;word[ebp+16] - options: element index
2331
;word[ebp+18] - options: 2*(add mode)+(init mode)
2332
;dword[ebp+20] - pointer to 'TreeList' struct
2333
;output:
2334
;dword[ebp+ 8] - error code
2335
align 4
2336
tl_load_mem:
2337
  push ebp
2338
  mov ebp,esp
2339
    push eax ebx ecx edx edi esi
2340
    mov esi,dword[ebp+12]
2341
    mov edi,dword[ebp+20]
2342
 
2343
    mov dword[ebp+20],0 ;return error code
2344
 
2345
    xor ecx,ecx
2346
    mov cx,word[ebp+16]
2347
    cmp cx,0 ;load in array mode
2348
    je @f
1328 IgorA 2349
;      push dword edi
2350
;      push dword esi
2351
;      call tl_get_mem_size ;берем размер ранее сохранённых данных
2352
;      pop ebx
2353
;      add esi,ebx
1303 IgorA 2354
      .beg_cycle:
1390 IgorA 2355
      cmp dword[esi],'tree'
1303 IgorA 2356
      jne .no_tree
2357
      xor ebx,ebx
2358
      mov bx,word[esi+4]
1328 IgorA 2359
      add bx,8
1303 IgorA 2360
      imul ebx,dword[esi+6]
2361
      add ebx,tl_save_load_heder_size
2362
      add esi,ebx
2363
      loop .beg_cycle
2364
    @@:
2365
 
1390 IgorA 2366
    cmp dword[esi],'tree'
1303 IgorA 2367
    jne .no_tree
2368
      bt word[ebp+18],1 ;load in add mode
2369
      jc @f
2370
        push dword edi
2371
        call tl_info_clear
2372
      @@:
2373
 
2374
      xor ebx,ebx
2375
      mov bx,word[esi+4] ;info_size
2376
      cmp bx,tl_info_size
2377
      je @f
2378
        or dword[ebp+20],tl_err_load_info_size
2379
      @@:
2380
      mov ecx,dword[esi+6] ;count nodes
2381
      cmp ecx,1
2382
      jl .end_f
1309 IgorA 2383
      mov edx,esi ;save header pointer
1303 IgorA 2384
      add esi,tl_save_load_heder_size
2385
 
2386
      @@:
2387
;load node params
2388
push dword edi
2389
mov eax,dword[esi+4]
2390
ror eax,16
2391
push dword eax ;options (type; lev; clo)
2392
add esi,8
2393
push dword esi
2394
call tl_node_add
2395
 
2396
push dword edi
2397
call tl_cur_next
2398
;...
2399
add esi,ebx
2400
        loop @b
2401
 
1309 IgorA 2402
      bt word[ebp+18],1 ;load in add mode
2403
      jc .no_tree
2404
        mov eax,dword[edx+14] ;set cursor pos
2405
        mov tl_cur_pos,eax
2406
        mov eax,dword[edx+22] ;set scroll pos
2407
        mov ebx,tl_p_scrol
2408
        cmp ebx,0
2409
        je .end_f
2410
          mov dword[ebx+24],eax ;+24 .position
2411
          push dword ebx ;pointer to scroll struct
2412
          call scroll_bar_vertical.draw
2413
 
1303 IgorA 2414
      jmp .end_f
2415
    .no_tree:
2416
      mov dword[ebp+20],tl_err_load_caption
2417
    .end_f:
2418
    pop esi edi edx ecx ebx eax
2419
  pop ebp
2420
  ret 12
2421
 
1328 IgorA 2422
;input:
2423
;dword[ebp+ 8] - pointer to memory
2424
;dword[ebp+12] - pointer to 'TreeList' struct
2425
;output:
2426
;dword[ebp+ 8] - error code
2427
align 4
2428
tl_get_mem_size: ;берет размер памяти занятой функцией tl_save_mem при сохранении элементов
2429
  push ebp
2430
  mov ebp,esp
2431
    push ebx edi esi
2432
    mov esi,dword[ebp+ 8]
2433
    mov edi,dword[ebp+12]
2434
    @@:
1390 IgorA 2435
      cmp dword[esi],'tree'
1328 IgorA 2436
      jne @f
2437
      xor ebx,ebx
2438
      mov bx,word[esi+4]
2439
      add bx,8 ;размер дополнительной информации об узле (индекс записи; индекс иконки, уровень, ...)
2440
      imul ebx,dword[esi+6]
2441
      add ebx,tl_save_load_heder_size
2442
      add esi,ebx
2443
      jmp @b
2444
    @@:
2445
    sub esi,dword[ebp+ 8]
2446
    mov dword[ebp+12],esi ;возвращаем размер блока памяти
2447
    pop esi edi edx
2448
  pop ebp
2449
  ret 4
2450
 
2451
 
1303 IgorA 2452
;ascii scan key
2453
;  13    28 Enter
2454
;  32    57 Space
2455
; 178    72 Up
2456
; 177    80 Down
2457
; 176    75 Left
2458
; 179    77 Right
2459
; 182    83 Delete
2460
; 184    73 Pg Up
2461
; 183    81 Pg Dn
2462
 
2463
tl_key_ascii db 13,32,178,177,176,179,182,184,183
2464
tl_key_scan  db 28,57, 72, 80, 75, 77, 83, 73, 81
2465
 
1309 IgorA 2466
txt_capt_cur db '‘ва®Є       ',0
2467
txt_capt_otm db 'Ћв¬Ґ­л      ',0
2468
 
2469
;этот код не мой, он преобразует число в строку
2470
;input:
2471
; eax = value
2472
; edi = string buffer
2473
align 4
2474
tl_convert_to_str:
2475
  pushad
2476
    mov dword[edi+1],0x20202020
2477
    call .str
2478
  popad
2479
  ret
2480
 
2481
align 4
2482
.str:
2483
  mov ecx,0x0a ;задается система счисления изменяются регистры ebx,eax,ecx,edx входные параметры eax - число
2484
    ;преревод числа в ASCII строку взодные данные ecx=система счисленя edi адрес куда записывать, будем строку, причем конец переменной
2485
  cmp eax,ecx  ;сравнить если в eax меньше чем в ecx то перейти на @@-1 т.е. на pop eax
2486
  jb @f
2487
  xor edx,edx  ;очистить edx
2488
  div ecx      ;разделить - остаток в edx
2489
  push edx     ;положить в стек
2490
  ;dec edi             ;смещение необходимое для записи с конца строки
2491
  call .str;перейти на саму себя т.е. вызвать саму себя и так до того момента пока в eax не станет меньше чем в ecx
2492
  pop eax
2493
  @@: ;cmp al,10 ;проверить не меньше ли значение в al чем 10 (для системы счисленя 10 данная команда - лишная))
2494
  ;sbb al,$69  ;- честно данная инструкция меня заставляет задуматься т.е. я не знаю как это работает
2495
  ;das        ;после данной команды как бы происходит уменьшение al на 66h  (в книге написано другое)
2496
  or al,0x30  ;данная команда короче  чем две выше
2497
  stosb       ;записать элемент из регистра al в ячеку памяти es:edi
2498
  ret         ;вернуться чень интересный ход т.к. пока в стеке храниться кол-во вызовов то столько раз мы и будем вызываться
2499
}