kolibrios/programs/develop/libraries/box_lib/trunk/tree_list.mac
IgorA 4a0abac115 Update 'TreeList':
1) update fun 'tl_key' - add keys: [Pg Up], [Pg Dn]; scan codes (66.2)
2) add new fun: 'tl_save_mem', 'tl_load_mem'
3) new param 'tl_info_capt_len'

git-svn-id: svn://kolibrios.org@1303 a494cfbc-eb01-0410-851d-a64ba20cac60
2009-12-02 11:18:26 +00:00

2263 lines
51 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

; макрос для системной библиотеки box_lib.obj
; элемент TreeList для Kolibri OS
; файл последний раз изменялся 2.12.2009 IgorA
; на код применена GPL2 лицензия
sizeof.TreeList equ 20
;struct TreeList
; type dw ? ;+ 0 тип элемента, или индекс иконки для узла
; lev db ? ;+ 2 уровень элемента
; clo db ? ;+ 3 флаг закрытия, или открытия (имеет смысл для родительского узла)
; perv dd ? ;+ 4 индекс предыдущего элемента
; next dd ? ;+ 8 индекс последующего элемента
; tc dd ? ;+12 врем. создания
; td dd ? ;+16 врем. удаления
;ends
tl_info_size equ word[edi +4] ;размер данных выделяемых для каждого узла (пользовательськие данные + текст для подписи)
tl_style equ dword[edi+10] ;стили элемента
tl_data_nodes equ dword[edi+14] ;указатель на структуры узлов
tl_img_cx equ word[edi+22] ;ширина иконок
tl_img_cy equ word[edi+24] ;высота иконок
tl_data_img_sys equ dword[edi+26] ;указатель на системные изображения (стрелки, плюсики)
tl_ch_tim equ dword[edi+30] ;количество изменений в файле
tl_tim_undo equ dword[edi+38] ;количество отмененных действий
tl_cur_pos equ dword[edi+42] ;позиция курсора
tl_col_bkg equ dword[edi+46] ;цвет фона
tl_col_zag equ dword[edi+50] ;цвет заголовка
tl_col_txt equ dword[edi+54] ;цвет текста
tl_box_left equ dword[edi+58]
tl_box_top equ dword[edi+62]
tl_box_width equ dword[edi+66]
tl_box_height equ dword[edi+70]
tl_capt_cy equ word[edi+74] ;высота подписи
tl_info_capt_offs equ word[edi+76] ;сдвиг для начала текста (подписи узла)
tl_info_capt_len equ word[edi+78] ;длинна текста подписи узла (если = 0 то до конца структуры)
tl_el_focus equ dword[edi+80] ;указатель на структуру элемента в фокусе
tl_p_scrol equ dword[edi+84] ;указатель на структуру скроллинга
tl_sb_draw equ dword[edi+88] ;указатель на функцию перерисовывающую скроллинг
tl_on_press equ dword[edi+96] ;указатель на функцию, которая вызывается при нажатии Enter
;константы стиля
tl_key_no_edit equ 1b ;элемент нельзя редактировать на клавиатуре (изменять уровни, удалять)
tl_draw_par_line equ 10b ;рисовать линии к родительскому узлу
tl_list_box_mode equ 100b ;стиль не отображает уровни (как в ListBox все одного уровня)
;константы для функций
tl_err_save_memory_size equ 10b ;не хватает памяти для сохранения элемента
tl_err_load_caption equ 1b ;в памяти нет заголовка 'tree'
tl_err_load_info_size equ 100b ;не совпадает размер информационной структуры при открытии
tl_load_mode_add equ 0x20000 ;опция считывания в режиме добавления информации
tl_save_load_heder_size equ 26 ;размер заголовка для записи/чтения элементов
;data_info dd ? ;+ 0 указатель на основные даные
;info_max_count dd ? ;+ 6 максимальное колличество структур
;data_img dd ? ;+18 указатель на изображения
;ls_tim dd ? ;+34 время последнего сохранения
;on_activate dd ? ;+92 указатель на функцию при активировании узла
struc tree_list info_size,info_max_count,style, img_cx,img_cy,\
col_bkg,col_zag,col_txt, box_l,box_t,box_w,box_h, capt_cy,info_capt_offs,\
info_capt_len,el_focus, p_scrol,p_sb_draw,on_press {
.data_info dd 0
.info_size dw info_size
.info_max_count dd info_max_count
.style dd style
.data_nodes dd 0
.data_img dd 0
.img_cx dw img_cx
.img_cy dw img_cy
.data_img_sys dd 0
.ch_tim dd 0
.ls_tim dd 0
.tim_undo dd 0
.cur_pos dd 0
.col_bkg dd col_bkg
.col_zag dd col_zag
.col_txt dd col_txt
.box_left dd box_l
.box_top dd box_t
.box_width dd box_w
.box_height dd box_h
.capt_cy dw capt_cy
.info_capt_offs dw info_capt_offs
.info_capt_len dw info_capt_len
.el_focus dd el_focus
.p_scrol dd p_scrol
.p_sb_draw dd p_sb_draw
.on_activate dd 0
.on_press dd on_press
}
;-----------------------------------------------------------------------------
;функция для выделения памяти
;input:
; ecx = size data
;otput:
; eax = pointer to memory
align 4
mem_Alloc:
push ebx
mov eax,68
mov ebx,12
int 0x40
pop ebx
ret
;-----------------------------------------------------------------------------
;функция для освобождения памяти
;input:
; ecx = pointer to memory
align 4
mem_Free:
push eax ebx
cmp ecx,0
jz @f
mov eax,68
mov ebx,13
int 0x40
@@:
pop ebx eax
ret
macro use_tree_list
{
align 4
tl_data_init: ;выделние памяти для структур списка и основной информации (конструктор)
push ebp
mov ebp,esp
push eax ecx edi
mov edi,dword[ebp+8]
xor ecx,ecx
mov cx,tl_info_size
imul ecx,dword[edi+6]
call mem_Alloc
mov dword[edi],eax ;копируем указатель на полученую память в структуру
mov dword[edi+18],0 ;обнуляем указатель 'data_img'
mov tl_data_img_sys,0 ;обнуляем указатель 'data_img_sys'
mov ecx,sizeof.TreeList
imul ecx,dword[edi+6]
call mem_Alloc
mov tl_data_nodes,eax ;копируем указатель на полученую память в структуру
push dword edi
call tl_info_clear
;настройки дочернего скроллинга
cmp tl_p_scrol,0
je @f
mov eax,tl_p_scrol
;*** цветовые настройки ***
mov ecx,tl_col_bkg
mov dword[eax+28],ecx ;+28 .bckg_col
mov ecx,tl_col_zag
mov dword[eax+32],ecx ;+32 .frnt_col
mov ecx,tl_col_txt
mov dword[eax+36],ecx ;+32 .line_col
;*** настройки размеров ***
mov ecx,tl_box_left
add ecx,tl_box_width
mov word[eax+2],cx
mov ecx,tl_box_height
mov word[eax+4],cx
mov ecx,tl_box_top
mov word[eax+6],cx
@@:
pop edi ecx eax
pop ebp
ret 4
align 4
tl_data_clear: ;очистка памяти элемента (деструктор)
push ebp
mov ebp,esp
push ecx edi
mov edi,dword[ebp+8]
cmp dword[edi+18],0 ;data_img
je @f
mov ecx,dword[edi+18]
call mem_Free ;чистка системных иконок
@@:
cmp tl_data_img_sys,0
je @f
mov ecx,tl_data_img_sys
call mem_Free ;чистка системных иконок
@@:
mov ecx,dword[edi]
call mem_Free
mov ecx,tl_data_nodes
call mem_Free
pop edi ecx
pop ebp
ret 4
align 4
tl_info_clear: ;очистка списка (информации)
push ebp
mov ebp,esp
push eax ecx edi
mov edi,dword[ebp+8]
mov tl_ch_tim,0
mov dword[edi+34],0 ;ls_tim
mov tl_tim_undo,0
mov tl_cur_pos,0
;xor ecx,ecx
mov ecx,sizeof.TreeList
imul ecx,dword[edi+6]
mov eax,tl_data_nodes
@@:
mov byte[eax],0 ;чистим узлы 0-ми
inc eax
loop @b
mov eax,tl_data_nodes ;указатель на 0-й узел
mov dword[eax+8],1 ;указатель next в 0-м узле приравниваем к 1
cmp tl_p_scrol,0 ;обработка скроллинга
je @f
mov eax,tl_p_scrol
mov dword[eax+24],0 ;+24 .position
call tb_scrol_resize
@@:
pop edi ecx eax
pop ebp
ret 4
align 4
tl_key: ;реакция на клавиатуру
push ebp
mov ebp,esp
push ebx ecx edi
mov edi,dword[ebp+8]
mov ebx,tl_el_focus
cmp dword[ebx],edi
jne .no_focus ;элемент не в фокусе
push eax
mov eax,66
mov ebx,2
int 0x40 ;получить режим ввода с клавиатуры
lea ecx,[tl_key_scan]
cmp eax,1 ;1 = сканкоды
je @f
lea ecx,[tl_key_ascii]
@@:
pop eax
xor bx,bx
cmp ah,byte[ecx] ;Enter
jne @f
cmp tl_on_press,0
je @f
call tl_on_press
@@:
cmp ah,byte[ecx+1] ;Space
jne @f
push dword edi
call tl_node_close_open
@@:
cmp ah,byte[ecx+2] ;Up
jne @f
push dword edi
call tl_cur_perv
@@:
cmp ah,byte[ecx+3] ;Down
jne @f
push dword edi
call tl_cur_next
@@:
cmp ah,byte[ecx+7] ;Page Up
jne @f
push dword edi
call tl_cur_page_up
@@:
cmp ah,byte[ecx+8] ;Page Down
jne @f
push dword edi
call tl_cur_page_down
@@:
bt tl_style,0 ;tl_key_no_edit
jc .no_edit
cmp ah,byte[ecx+4] ;Left
jne @f
push dword edi
call tl_node_lev_dec
mov bx,1
@@:
cmp ah,byte[ecx+5] ;Right
jne @f
push dword edi
call tl_node_lev_inc
mov bx,1
@@:
cmp ah,byte[ecx+6] ;Delete
jne @f
push dword edi
call tl_node_delete
mov bx,1
@@:
.no_edit:
cmp bx,1
jne .no_focus
push dword edi
call tl_draw
.no_focus:
pop edi ecx ebx
pop ebp
ret 4
align 4
tl_mouse: ;реакция на мышь
push ebp
mov ebp,esp
push eax ebx ecx edx edi esi
mov edi,dword[ebp+8]
mov eax,37
mov ebx,2
int 0x40
bt eax,0 ;left mouse button press
jae .no_draw
mov eax,37
mov ebx,1
int 0x40
mov ebx,tl_box_left
shl ebx,16
cmp eax,ebx ;левая граница окна
jl .no_in_wnd
mov ebx,tl_box_left
add ebx,tl_box_width
shl ebx,16
cmp eax,ebx ;правая граница окна
jg .no_in_wnd
mov ebx,tl_box_top
add ebx,tl_box_height
cmp ax,bx ;нижняя граница окна
jg .no_in_wnd
sub ebx,tl_box_height
add bx,tl_capt_cy
cmp ax,bx ;верхняя граница окна + высота подписи
jl .no_in_wnd
mov esi,tl_el_focus
mov dword[esi],edi ;set focus
; if '+' or '-' press
mov esi,eax
shr esi,16
sub esi,tl_box_left ;esi = mouse x coord in element window
and eax,0xffff
sub ax,bx
xor edx,edx
xor ecx,ecx
mov cx,tl_img_cy
div ecx
cmp tl_p_scrol,0 ;учитываем скроллинг
je @f
mov edx,tl_p_scrol
add eax,dword[edx+24] ;добавляем скроллинг на верху
@@:
mov ecx,eax
call tl_get_node_count ;eax = node count
cmp eax,ecx
jl @f
mov eax,ecx ;если курсор не вышел за пределы узлов, восстанавливаем старое значение eax
@@:
cmp eax,tl_cur_pos ;если новое значение курсора совпало с предыдущим
je @f ;то не стираем курсор
push esi
mov esi,tl_box_top
add esi,tl_box_height ;esi = coord bottom border
call tl_draw_null_cursor ;стираем курсор
pop esi
@@:
mov tl_cur_pos,eax
; if '+' or '-' press
call tl_get_cur_node_index ;eax = node index
cmp eax,2
jl .no_open_close ;курсор стоит на пустом месте, без узлов
imul eax,sizeof.TreeList
add eax,tl_data_nodes
xor bx,bx
mov bl,byte[eax+2] ;+2 lev сохраняем уровень текущего узла
inc bx ;+ поле для курсора
cmp si,tl_img_cx
jl .no_open_close ;мышей попали на левое поле для курсора, где точно нет '+' и '-'
mov eax,esi
xor edx,edx
xor ecx,ecx
mov cx,tl_img_cx
div ecx
cmp ax,bx
jne .no_open_close
push dword edi
call tl_node_close_open
.no_open_close:
mov esi,tl_box_top
add esi,tl_box_height ;esi = coord bottom border
call tl_draw_cursor ;перерисовка курсора
call tl_draw_caption_cur_pos
jmp .no_draw
.no_in_wnd: ;не попали в окно - потеря фокуса (при условии что фокус был на данном эелементе)
mov ebx,tl_el_focus
cmp dword[ebx],edi
jne .no_draw ;элемент не в фокусе
mov dword[ebx],0 ;reset focus
.no_draw:
pop esi edi edx ecx ebx eax
pop ebp
ret 4
align 4
tl_info_undo: ;отмена действия
push ebp
mov ebp,esp
push eax edi
mov edi,dword[ebp+8]
mov eax,tl_tim_undo
cmp tl_ch_tim,eax
jbe @f
inc tl_tim_undo
call tb_scrol_resize ;обработка скроллинга
@@:
pop edi eax
pop ebp
ret 4
align 4
tl_info_redo: ;повтор действия
push ebp
mov ebp,esp
push edi
mov edi,dword[ebp+8]
cmp tl_tim_undo,1
jl @f
dec tl_tim_undo
call tb_scrol_resize ;обработка скроллинга
@@:
pop edi
pop ebp
ret 4
align 4
tl_info_set_undo: ;удаление отмененных действий
; push ebp
; mov ebp,esp
; push edi
; mov edi,dword[ebp+8]
; mov [dragk],0 ;заканчиваем выделение от клавиатуры
cmp tl_tim_undo,1
jl .no_work
push eax ebx ecx edx
mov edx,tl_data_nodes
mov ecx,edx
add ecx,sizeof.TreeList
call tl_move_next ;long i=node[0].next;
mov eax,tl_tim_undo
sub tl_ch_tim,eax ;ch_tim-=tim_undo;
mov eax,tl_ch_tim
cmp [edi+34],eax ;if(ls_tim>ch_tim)
jle @f
mov dword[edi+34],0 ;ls_tim=0
@@:
cmp edx,ecx
jle @f
;if(node[i].tc>ch_tim){ // если создание символа было отменено
cmp dword[edx+12],eax
jle .no_u1
mov dword[edx+12],0
mov dword[edx+16],0
mov ebx, dword[edx+4]
imul ebx,sizeof.TreeList
add ebx, tl_data_nodes ;.next
push dword[edx+8] ;node[node[i].perv].next=node[i].next;
pop dword[ebx+8]
mov ebx, dword[edx+8]
imul ebx,sizeof.TreeList
add ebx, tl_data_nodes ;.perv
push dword[edx+4] ;node[node[i].next].perv=node[i].perv;
pop dword[ebx+4]
.no_u1:
;else if(node[i].td>ch_tim) node[i].td=0; // если удаление символа было отменено
cmp dword[edx+16],eax
jle .no_u2
mov dword[edx+16],0
.no_u2:
call tl_move_next
jmp @b
@@:
mov tl_tim_undo,0
; mov eax,[edi+?] ;co_tim
; cmp tl_ch_tim,eax ;ch_tim
; jge @f
; mov [edi+?],0 ;co_tim
; @@:
pop edx ecx ebx eax
.no_work:
; pop edi
; pop ebp
; ret 4
ret
align 4
tl_draw: ;вывод списка на экран
push ebp
mov ebp,esp
push eax ebx ecx edx edi esi
;draw dir_list main rect
mov edi,dword[ebp+8]
mov ebx,tl_box_left
shl ebx,16
add ebx,tl_box_width
mov ecx,tl_box_top
shl ecx,16
mov cx,tl_capt_cy
mov edx,tl_col_zag
mov eax,13
int 0x40 ;draw window caption
add ecx,tl_box_top
shl ecx,16
add ecx,tl_box_height
sub cx,tl_capt_cy
mov edx,tl_col_bkg
int 0x40 ;draw window client rect
cmp tl_capt_cy,9 ;9 - minimum caption height
jl @f
mov eax,4 ;draw text captions
mov ebx,tl_box_left
shl ebx,16
add ebx,5*65536+3
add ebx,tl_box_top
mov ecx,tl_col_txt
or ecx,0x80000000
lea edx,[txt_capt_cur]
int 0x40
mov ebx,tl_box_left
shl ebx,16
add ebx,100*65536+3
add ebx,tl_box_top
lea edx,[txt_capt_otm]
int 0x40
mov eax,47 ;draw
mov ebx,0x40000
mov ecx,tl_cur_pos
inc ecx
mov edx,tl_box_left
shl edx,16
add edx,50*65536+3
add edx,tl_box_top
mov esi,tl_col_txt
int 0x40
mov ecx,tl_tim_undo
mov edx,tl_box_left
shl edx,16
add edx,140*65536+3
add edx,tl_box_top
mov esi,tl_col_txt
int 0x40
@@:
;---debug---
;mov ecx,0
;@@:
;call DebugSymb
;inc ecx
;cmp ecx,10
;jge @f
;jmp @b
;@@:
;---debug---
;cycle to nodes
xor eax,eax
mov edx,tl_data_nodes
mov ecx,edx
add ecx,sizeof.TreeList
;*** пропуск узлов, которые промотаны скроллингом ***
cmp tl_p_scrol,0 ;если есть указатель на скроллинг
je .end_c1
mov esi,tl_p_scrol
cmp dword[esi+24],0 ;если скроллинг на верху, выходим
je .end_c1
@@:
call tl_iterat_next
cmp edx,ecx
jle .end_draw
inc eax
cmp eax,dword[esi+24]
jge .end_c1
jmp @b
.end_c1:
xor eax,eax
mov esi,tl_box_top
add esi,tl_box_height ;esi = coord bottom border
@@:
call tl_iterat_next
cmp edx,ecx
jle @f
call tl_draw_node
inc eax
jmp @b
@@:
call tl_draw_cursor
.end_draw:
pop esi edi edx ecx ebx eax
pop ebp
ret 4
;input:
; ecx = pointer to 1 node struct
; edx = pointer to some node struct
; edi = pointer to 'TreeList' struct
;output:
; edx = pointer to next node struct
align 4
tl_iterat_next:
push bx
mov bl,0x7f
cmp byte[edx+3],1
jne @f
mov bl,byte[edx+2]
@@:
cmp tl_tim_undo,0
je .else
push eax
.beg0:
call tl_move_next
cmp edx,ecx
jle @f
call tl_node_not_vis ;пропуск удаленных и отмененных
cmp al,1
je .beg0
cmp bl,byte[edx+2] ;пропуск закрытых
jl .beg0
@@:
pop eax
pop bx
ret
.else:
call tl_move_next
cmp edx,ecx
jle .endif
cmp dword[edx+16],0 ;td = 'time delete' -> пропуск удаленных
jne .else
cmp bl,byte[edx+2] ;пропуск закрытых
jl .else
.endif:
pop bx
ret
;input:
; ecx = pointer to 1 node struct
; edx = pointer to some node struct
; edi = pointer to 'TreeList' struct
align 4
tl_iterat_next_all:
cmp tl_tim_undo,0
je .else
push eax
@@:
call tl_move_next
cmp edx,ecx
jle @f
call tl_node_not_vis
cmp al,1
je @b
@@:
pop eax
ret
.else:
call tl_move_next
cmp edx,ecx
jle .endif
cmp dword[edx+16],0 ;td -> time delete
jne .else
.endif:
ret
;input:
; ecx = pointer to 1 node struct
; edx = pointer to some node struct
; edi = pointer to 'TreeList' struct
align 4
tl_iterat_perv:
push bx
mov bl,0x7f
cmp byte[edx+3],1
jne @f
mov bl,byte[edx+2]
@@:
cmp tl_tim_undo,0
je .else
push eax
.beg0:
call tl_move_perv
cmp edx,ecx
jle @f
call tl_node_not_vis ;пропуск удаленных и отмененных
cmp al,1
je .beg0
cmp bl,byte[edx+2] ;пропуск закрытых
jl .beg0
@@:
pop eax
pop bx
ret
.else:
call tl_move_perv
cmp edx,ecx
jle .endif
cmp dword[edx+16],0 ;td = 'time delete' -> пропуск удаленных
jne .else
cmp bl,byte[edx+2] ;пропуск закрытых
jl .else
.endif:
pop bx
ret
;input:
; edx = pointer to some node struct
; edi = pointer to 'TreeList' struct
;output:
; edx = pointer to next node struct
align 4
tl_move_next:
mov edx,dword[edx+8]
imul edx,sizeof.TreeList
add edx,tl_data_nodes
ret
;input:
; edx = pointer to some node struct
; edi = pointer to 'TreeList' struct
;output:
; edx = pointer to perv node struct
align 4
tl_move_perv:
mov edx,dword[edx+4]
imul edx,sizeof.TreeList
add edx,tl_data_nodes
ret
;input:
; edx = pointer to symbol struct
; edi = pointer to 'TreeList' struct
;output:
; al = 1 if sumbol not visible
; (node[i].td+tim_Undo<=ch_tim && node[i].td) || (node[i].tc>ch_tim-tim_Undo)
align 4
tl_node_not_vis:
cmp dword[edx+16],0
je @f
mov eax,dword[edx+16] ;eax=node[i].td
add eax,tl_tim_undo
cmp eax,tl_ch_tim
jg @f
mov al,1
ret
@@:
mov eax,tl_ch_tim
sub eax,tl_tim_undo
cmp dword[edx+12],eax ;tc -> time create
jle @f
mov al,1
ret
@@:
xor al,al
ret
;input:
; edi = pointer to TreeInfo struct
; esi = coord bottom border
align 4
tl_draw_cursor: ;рисуем курсор на экране
push eax ebx ecx edx esi
call tl_get_display_cur_pos ;eax = cursor pos in screen
cmp eax,0
jl .end_f ;курсор находится выше окна, в области прокрученной скроллингом
cmp tl_data_img_sys,0 ;смотрим есть ли указатель на картинку системных иконок
jne @f
mov ebx,tl_box_left
shl ebx,16
mov bx,tl_img_cx
xor ecx,ecx
mov cx,tl_img_cy
imul ecx,eax
add ecx,tl_box_top
add cx,tl_capt_cy
;crop image if on the border
cmp esi,ecx ;если курсор внизу и его вообще не видно
jl .end_f
sub esi,ecx
shl ecx,16
mov cx,tl_img_cy
cmp si,tl_img_cy
jge .crop0
mov cx,si ;если курсор виден частично (попал на нижнюю границу)
.crop0:
mov edx,tl_col_txt
mov eax,13
int 0x40 ;рисуем простой прямоугольник, т.к. нет системных иконок
jmp .end_f
@@:
mov ebx,tl_data_img_sys
imul ax,tl_img_cy
mov cx,tl_img_cx
shl ecx,16
mov cx,tl_img_cy
mov edx,tl_box_left
shl edx,16
mov dx,ax
add edx,tl_box_top
add dx,tl_capt_cy
;crop image if on the border
cmp si,dx ;если курсор внизу и его вообще не видно
jl .end_f
sub si,dx
cmp si,tl_img_cy
jge .crop1
mov cx,si ;если курсор виден частично (попал на нижнюю границу)
.crop1:
mov eax,7
int 0x40 ;рисуем иконку курсора
.end_f:
pop esi edx ecx ebx eax
ret
;input:
; edi = pointer to TreeInfo struct
; esi = coord bottom border
align 4
tl_draw_null_cursor: ;стираем курсор на экране
push eax ebx ecx edx esi
call tl_get_display_cur_pos ;eax = cursor pos in screen
cmp eax,0
jl .end_f ;курсор находится выше окна, в области прокрученной скроллингом
mov ebx,tl_box_left
shl ebx,16
mov bx,tl_img_cx
xor ecx,ecx
mov cx,tl_img_cy
imul ecx,eax
add ecx,tl_box_top
add cx,tl_capt_cy
;crop image if on the border
cmp esi,ecx ;если курсор внизу и его вообще не видно
jl .end_f
sub esi,ecx
shl ecx,16
mov cx,tl_img_cy
cmp si,tl_img_cy
jge @f
mov cx,si ;если курсор виден частично (попал на нижнюю границу)
@@:
mov edx,tl_col_bkg
mov eax,13
int 0x40 ;рисуем простой прямоугольник с фоновым цветом
.end_f:
pop esi edx ecx ebx eax
ret
;input:
; edi = pointer to TreeInfo struct
;output:
; eax = index
align 4
tl_get_display_cur_pos: ;берет позицию курсора, относительно экрана
mov eax,tl_cur_pos
cmp tl_p_scrol,0
je @f
push ebx
mov ebx,tl_p_scrol
mov ebx,dword[ebx+24]
sub eax,ebx ;отнимаем позицию скроллинга
pop ebx
@@:
ret
;input:
; eax = node position
; edx = pointer to some node struct
; edi = pointer to TreeInfo struct
; esi = coord of bottom border
align 4
tl_draw_node:
push eax ebx ecx edx esi
mov ebx,1 ;1 - место под курсор и под знак +,-
bt tl_style,2 ;tl_list_box_mode
jc @f
inc ebx ;+1 - место под знак +,-
@@:
add bl,byte[edx+2];get level
imul bx,tl_img_cx
add ebx,tl_box_left
shl ebx,16
mov bx,tl_img_cx
xor ecx,ecx
mov cx,tl_img_cy
imul ecx,eax
add ecx,tl_box_top
add cx,tl_capt_cy
;crop image if on the border
cmp esi,ecx ;если узел внизу и его вообще не видно
jl .end_draw
sub esi,ecx
shl ecx,16
mov cx,tl_img_cy
cmp si,tl_img_cy
jge @f
mov cx,si ;если узел виден частично (попал на нижнюю границу)
jmp .crop ;пропускаем рисование надписи, которая скорее всего тоже вылезет за нижнюю границу
@@:
call tl_draw_node_caption
.crop:
mov esi,ecx ;save ecx
cmp dword[edi+18],0 ;data_img
jne .draw_img_n
push edx
mov edx,tl_col_txt
mov eax,13
int 0x40 ;draw node rect
pop edx
jmp @f
.draw_img_n:
push ebx edx esi
xor esi,esi
mov si,word[edx] ;get icon type
mov edx,ebx
ror ecx,16
mov dx,cx
mov cx,bx
ror ecx,16
mov ebx,3 ;rgb = 3 bytes
imul bx,tl_img_cx
imul bx,tl_img_cy
imul ebx,esi ;esi = icon index
add ebx,dword[edi+18] ;data_img
mov eax,7
int 0x40 ;draw node icon '-'
pop esi edx ebx
@@:
mov al,byte[edx+2] ;draw minus '-'
mov ecx,tl_data_nodes
add ecx,sizeof.TreeList
mov ah,10 ;get icon index '+' or '-' ?
cmp byte[edx+3],1
jne .close
dec ah
.close:
call tl_draw_node_icon_opn_clo
bt tl_style,1
jae .end_draw
call tl_draw_node_icon_par_lin
.end_draw:
pop esi edx ecx ebx eax
ret
;input:
; ecx = pointer to 1 node struct
;...
align 4
tl_draw_node_icon_opn_clo: ;рисует иконки открытого или закрытого узла (обычно + или -)
push eax ebx ecx edx esi
inc al
call tl_iterat_next_all ;get next visible item
cmp edx,ecx
jle @f
mov ecx,esi ;load ecx
cmp al,byte[edx+2]
jne @f
ror ebx,16
sub bx,tl_img_cx
ror ebx,16
cmp tl_data_img_sys,0
jne .draw_img_s
mov edx,tl_col_txt
mov eax,13
int 0x40 ;draw minus rect, if not system icons
jmp @f
.draw_img_s:
mov ecx,esi ;load ecx
mov edx,ebx
ror ecx,16
mov dx,cx
mov cx,bx
ror ecx,16
mov ebx,3 ;rgb = 3 bytes
imul bx,tl_img_cx
imul bx,tl_img_cy
shr eax,8
and eax,0xff
imul ebx,eax ;eax = icon index
add ebx,tl_data_img_sys
mov eax,7
int 0x40 ;draw minus icon '-'
@@:
pop esi edx ecx ebx eax
ret
;input:
;...
align 4
tl_draw_node_icon_par_lin:
cmp byte[edx+3],1
je .close
push eax ebx ecx edx esi
cmp al,0
je @f
; dec al
; call tl_iterat_perv ;get perv visible item
call tl_iterat_next_all ;get next visible item
cmp edx,ecx
jle .line3 ;if end of list
cmp al,byte[edx+2]
jne .line3 ;jg ???
mov eax,3 ;line in middle element
jmp .line2
.line3:
mov eax,6 ;line in end element
.line2:
mov ecx,esi ;load ecx
ror ebx,16
sub bx,tl_img_cx
ror ebx,16
cmp tl_data_img_sys,0
jne .draw_img_s
mov edx,tl_col_txt
mov eax,13
int 0x40 ;draw minus rect, if not system icons
jmp @f
.draw_img_s:
mov ecx,esi ;load ecx
mov edx,ebx
ror ecx,16
mov dx,cx
mov cx,bx
ror ecx,16
mov ebx,3 ;rgb = 3 bytes
imul bx,tl_img_cx
imul bx,tl_img_cy
; shr eax,8
; and eax,0xff
imul ebx,eax ;eax = icon index
add ebx,tl_data_img_sys
mov eax,7
int 0x40 ;draw line icon
@@:
pop esi edx ecx ebx eax
.close:
ret
;input:
; edi = pointer to TreeInfo struct
;output:
; eax = rows
align 4
tl_get_rows_count:
push ecx edx
mov eax,tl_box_height
sub ax,tl_capt_cy
xor ecx,ecx
mov cx,tl_img_cy
xor edx,edx
div ecx
pop edx ecx
ret
;input:
; eax = node position
; ebx = [координата по оси x]*65536 + [img_cx]
; ecx = [координата по оси y]*65536 + [img_cy]
; edx = pointer to some node struct
; edi = pointer to TreeInfo struct
align 4
tl_draw_node_caption:
push ebx ecx edx esi
xor esi,esi
mov si,tl_info_size
cmp si,tl_info_capt_offs
jle @f ;if caption size <= 0
push eax
call tl_get_node_index ;eax = node index
imul esi,eax
pop eax
add si,tl_info_capt_offs
add esi,dword[edi]
mov edx,esi
shr ebx,16
add bx,tl_img_cx ;сдвигаем надпись по горизонтали --->
add bx,3 ;отступ
;bx = coord. x
call tl_strlen ;eax = strlen
call tl_get_draw_text_len
mov cx,bx
ror ecx,16
mov ebx,ecx
add bx,tl_img_cy ;выравнивиние по нижней границе иконки
sub bx,9 ;отнимаем высоту текста
mov ecx,tl_col_txt
and ecx,0xffffff
; or ecx,0x80000000 ;text is ASCIIZ
mov eax,4
int 0x40
@@:
pop esi edx ecx ebx
ret
;input:
; eax = strlen
; ebx = text coord x
;output:
; esi = text len
align 4
tl_get_draw_text_len:
push eax ecx edx
mov esi,eax ;берем длинну строки
mov eax,tl_box_left
add eax,tl_box_width
cmp eax,ebx
jle .text_null ;если подпись полностью вся за экраном
sub eax,ebx
xor edx,edx
mov ecx,6 ;ширина системного шрифта
div ecx ;смотрим сколько символов может поместиться на экране
cmp esi,eax
jl @f
mov esi,eax ;если длинна текста меньше, чем все место под строку
jmp @f
.text_null:
xor esi,esi
@@:
pop edx ecx eax
ret
;input:
; esi = pointer to string
;output:
; eax = strlen
align 4
tl_strlen:
mov eax,esi
@@:
cmp byte[eax],0
je @f
inc eax
loop @b
@@:
sub eax,esi
ret
;input:
;dword[ebp+ 8] - pointer to node info
;dword[ebp+12] - options
;dword[ebp+16] - pointer to 'TreeList' struct
align 4
tl_node_add: ;добавить узел
push ebp
mov ebp,esp
push eax ebx ecx edx edi
mov edi,dword[ebp+16]
call tl_info_set_undo
mov ebx,sizeof.TreeList
imul ebx,dword[edi+6] ;+6 макс. количество узлов
add ebx,tl_data_nodes
;--
call tl_get_cur_node_index ;eax=po_t
imul eax,sizeof.TreeList
add eax,tl_data_nodes
mov edx,eax
call tl_move_perv
call tl_get_node_index ;eax = index of pointer [edx]
;--
mov edx,sizeof.TreeList
shl edx,1
add edx,tl_data_nodes
@@: ;for(i=2;i<nodeMax;i++)
cmp dword [edx+12],0
jne .u0
cmp dword [edx+16],0
jne .u0
inc tl_ch_tim
mov cx,word[ebp+14] ;get type
mov word[edx],cx
mov cl,byte[ebp+13]
mov byte[edx+3],cl ;node[i].clo
mov byte[edx+2], 0 ;node[i].lev=0
bt tl_style,2 ;tl_list_box_mode
jc .l_box_m
mov cl,byte[ebp+12]
mov byte[edx+2],cl ;node[i].lev
.l_box_m:
push tl_ch_tim ;node[i].tc=ch_tim;
pop dword[edx+12]
mov dword[edx+4], eax ;node[i].perv=po_t;
;*** copy node data ***
push esi
xor ecx,ecx
mov cx,tl_info_size
mov esi,ecx
push eax
call tl_get_node_index ;eax = node index
imul esi,eax
pop eax
add esi,dword[edi]
mov edi,dword[ebp+8] ;pointer to node data
xchg edi,esi
rep movsb
mov esi,edi
mov edi,dword[ebp+16] ;restore edi
mov cx,tl_info_capt_offs
cmp cx,tl_info_size
jge .no_text_data
cmp tl_info_capt_len,0 ;проверяем есть ли ограничение на длинну строки
je .no_len_ogran
add cx,tl_info_capt_len
and ecx,0xffff
add esi,ecx
mov cx,tl_info_size
sub esi,ecx
.no_len_ogran:
dec esi
mov byte[esi],0
.no_text_data:
pop esi ;restore esi
mov ecx,eax
imul ecx,sizeof.TreeList
add ecx,tl_data_nodes ; *** ecx = node[po_t] ***
add ecx,8 ; *** ecx = node[po_t].next ***
push dword [ecx] ;node[i].next=node[po_t].next;
pop dword [edx+8]
call tl_get_node_index ;*** eax = i ***
cmp eax,dword[edi+6] ;info_max_count
jge .u0
mov [ecx],eax ;node[po_t].next=i; // ссылки перенаправляем
mov ecx,[edx+8] ; *** ecx = node[i].next ***
imul ecx,sizeof.TreeList
add ecx,tl_data_nodes ; *** ecx = node[node[i].next] ***
mov [ecx+4],eax ;node[node[i].next].perv=i;
call tb_scrol_resize ;обработка скроллинга
jmp @f
.u0:
add edx,sizeof.TreeList
cmp edx,ebx ;enf of node memory ?
jle @b
@@:
pop edi edx ecx ebx eax
pop ebp
ret 12
;input:
; edi = pointer to TreeInfo struct
align 4
tb_scrol_resize:
push eax ecx edx
cmp tl_p_scrol,0 ;обработка скроллинга
je @f
call tl_get_node_count ;eax = node count
mov ecx,eax
call tl_get_rows_count
cmp ecx,eax
jg .ye_sb
xor ecx,ecx
.ye_sb:
mov edx,tl_p_scrol
mov dword[edx+20],eax ;+20 .cur_area
mov dword[edx+16],ecx ;+16 .max_area
push dword edx ;pointer to scroll struct
mov edx,tl_sb_draw ;pointer to scroll draw function
call dword[edx]
@@:
pop edx ecx eax
ret
;input:
;dword[ebp+ 8] - pointer to node info
;dword[ebp+12] - pointer to 'TreeList' struct
align 4
tl_node_set_data:
push ebp
mov ebp,esp
push eax ecx edx edi esi
mov edi,dword[ebp+12]
call tl_get_cur_node_index ;eax=po_t
cmp eax,2
jl @f
xor ecx,ecx
mov cx,tl_info_size
imul eax,ecx
add eax,dword[edi]
mov edi,eax
mov esi,dword[ebp+8] ;pointer to node data
rep movsb
mov esi,edi
mov edi,dword[ebp+12] ;restore edi
mov cx,tl_info_capt_offs
cmp cx,tl_info_size
jge .no_text_data
mov ax,tl_info_capt_len ;проверяем есть ли ограничение на длинну текста
cmp ax,0
je .no_limit
add cx,ax ;cx = tl_info_capt_offs + tl_info_capt_len
and ecx,0xffff
xor eax,eax
mov ax,tl_info_size
cmp eax,ecx
jl .no_limit ;пользователь задал слишком большую длинну текста
add esi,ecx
sub esi,eax
.no_limit:
dec esi
mov byte[esi],0 ;обнуляем последний символ подписи, что-бы не глючило если пользователь задал неправильную структуру
.no_text_data:
@@:
pop esi edi edx ecx eax
pop ebp
ret 8
;input:
;dword[ebp+ 8] - pointer to 'TreeList' struct
align 4
tl_node_get_data: ;взять указатель на данные узла под курсором
push ebp
mov ebp,esp
push eax ecx edi
mov edi,dword[ebp+8]
call tl_get_cur_node_index ;eax=po_t
mov dword[ebp+8],0 ;if return 0 pointer
cmp eax,2
jl @f
xor ecx,ecx
mov cx,tl_info_size
imul eax,ecx
add eax,dword[edi]
mov dword[ebp+8],eax ;return node data pointer
@@:
pop edi ecx eax
pop ebp
ret
;input:
;dword[ebp+ 8] - node index
;dword[ebp+12] - pointer to 'TreeList' struct
align 4
tl_node_poi_get_info: ;взять указатель на структуру узла в указанной позиции
push ebp
mov ebp,esp
push eax ecx edx edi
mov edi,dword[ebp+12]
mov eax,dword[ebp+8]
;cycle to nodes
mov edx,tl_data_nodes
mov ecx,edx
add ecx,sizeof.TreeList
@@:
call tl_iterat_next_all
cmp edx,ecx
jle @f
dec eax
cmp eax,0
jg @b
jmp .find
@@:
xor edx,edx
.find:
mov dword[ebp+12],edx
pop edi edx ecx eax
pop ebp
ret 4
;input:
;dword[ebp+ 8] - node param struct
;dword[ebp+12] - pointer to 'TreeList' struct
align 4
tl_node_poi_get_next_info: ;взять указатель на следущую структуру узла
push ebp
mov ebp,esp
push ecx edx edi
mov edi,dword[ebp+12]
mov edx,dword[ebp+8]
mov ecx,tl_data_nodes
add ecx,sizeof.TreeList
call tl_iterat_next_all
cmp edx,ecx
jg @f
xor edx,edx
@@:
mov dword[ebp+12],edx
pop edi edx ecx
pop ebp
ret 4
;input:
;dword[ebp+ 8] - node param struct
;dword[ebp+12] - pointer to 'TreeList' struct
align 4
tl_node_poi_get_data: ;взять указатель на данные узла
push ebp
mov ebp,esp
push eax ecx edi
mov edi,dword[ebp+12]
mov edx,dword[ebp+8]
mov dword[ebp+12],0
call tl_get_node_index ;eax = node index
cmp eax,2
jl @f
xor ecx,ecx
mov cx,tl_info_size
imul eax,ecx
add eax,dword[edi]
mov dword[ebp+12],eax ;return node data pointer
@@:
pop edi ecx eax
pop ebp
ret 4
;input:
; edi = pointer 'tl' struct
;output:
; eax = index of current node
align 4
tl_get_cur_node_index: ;берет позицию под курсором
push ecx edx
;cycle to nodes
xor eax,eax
mov edx,tl_data_nodes
mov ecx,edx
add ecx,sizeof.TreeList
@@:
call tl_iterat_next
cmp edx,ecx
jle @f
cmp eax,tl_cur_pos
je @f
inc eax
jmp @b
@@:
mov eax,edx
sub eax,tl_data_nodes
xor edx,edx
mov ecx,sizeof.TreeList
div ecx
pop edx ecx
ret
;input:
; edx = pointer node memory
; edi = pointer 'tl' struct
;output:
; eax = struct index of current node
align 4
tl_get_node_index: ;берет позицию указанного символа
push ecx edx
mov eax,edx
sub eax,tl_data_nodes
xor edx,edx
mov ecx,sizeof.TreeList
div ecx
pop edx ecx
ret
align 4
tl_node_delete: ;удалить узел
push ebp
mov ebp,esp
push eax edx edi
mov edi,dword[ebp+8]
call tl_get_cur_node_index ;eax=po_t
cmp eax,2
jl @f
imul eax,sizeof.TreeList
add eax,tl_data_nodes
mov edx,eax
inc tl_ch_tim
mov eax,tl_ch_tim
mov dword[edx+16],eax
call tb_scrol_resize ;обработка скроллинга
@@:
pop edi edx eax
pop ebp
ret 4
align 4
tl_cur_beg: ;поставить курсор на первый узел
push ebp
mov ebp,esp
push edi
mov edi,dword[ebp+8]
mov tl_cur_pos,0
cmp tl_p_scrol,0
je @f
mov edi,tl_p_scrol
mov dword[edi+24],0
push dword edi
mov edi,dword[ebp+8]
mov edi,tl_sb_draw
call dword[edi]
@@:
pop edi
pop ebp
ret 4
align 4
tl_cur_next: ;перенести курсор на 1 позицию ниже
push ebp
mov ebp,esp
push eax ebx edi esi
mov edi,dword[ebp+8]
call tl_get_node_count ;eax = node count
;inc eax
cmp tl_cur_pos,eax
jge .no_redraw
mov esi,tl_box_top
add esi,tl_box_height ;esi = coord bottom border
call tl_draw_null_cursor ;стираем курсор
inc tl_cur_pos
cmp tl_p_scrol,0 ;if not scrol struct
je @f
call tl_get_rows_count ;eax = rows count
mov ebx,tl_p_scrol
add eax,dword[ebx+24] ;.position +24
cmp tl_cur_pos,eax
jl @f
inc dword[ebx+24] ;.position +24
push dword ebx
mov edi,tl_sb_draw ;перерисовка скроллинга
call dword[edi]
mov edi,dword[ebp+8] ;restore edi
push dword edi
call tl_draw ;полная перерисовка окна
jmp .no_redraw
@@:
mov edi,dword[ebp+8] ;restore edi
call tl_draw_cursor ;перерисовка курсора
call tl_draw_caption_cur_pos
.no_redraw:
pop esi edi ebx eax
pop ebp
ret 4
;input:
; edi = pointer 'tl' struct
;output:
; eax = struct index of current node
align 4
tl_get_node_count: ;берет число всех видимых узлов (не считая закрытых дочерних)
push ecx edx
;cycle to nodes
xor eax,eax
mov edx,tl_data_nodes
mov ecx,edx
add ecx,sizeof.TreeList
@@:
call tl_iterat_next
cmp edx,ecx
jle @f
inc eax
jmp @b
@@:
pop edx ecx
ret
;input:
; edi = pointer 'tl' struct
;output:
; eax = struct index of current node
align 4
tl_get_node_count_all: ;берет число всех видимых узлов (считая закрытые дочерние)
push ecx edx
;cycle to nodes
xor eax,eax
mov edx,tl_data_nodes
mov ecx,edx
add ecx,sizeof.TreeList
@@:
call tl_iterat_next_all
cmp edx,ecx
jle @f
inc eax
jmp @b
@@:
pop edx ecx
ret
align 4
tl_cur_perv: ;перенести курсор на 1 позицию выше
push ebp
mov ebp,esp
push eax edi esi
mov edi,dword[ebp+8]
cmp tl_cur_pos,0
je .no_redraw
mov esi,tl_box_top
add esi,tl_box_height ;esi = coord bottom border
call tl_draw_null_cursor ;стираем курсор
dec tl_cur_pos ;двигаем курсор вверх
cmp tl_p_scrol,0 ;если есть указатель на скроллинг
je @f
mov eax,tl_p_scrol
cmp dword[eax+24],0 ;если скроллинг на верху, выходим
je @f
mov edi,tl_cur_pos
cmp edi,dword[eax+24] ;если курсор ушел выше скроллинга, тогда опускаем скроллинг
jge @f
dec dword[eax+24]
push dword eax
mov edi,dword[ebp+8]
mov edi,tl_sb_draw ;.redraw
call dword[edi]
mov edi,dword[ebp+8] ;restore edi
push dword edi
call tl_draw ;полная перерисовка окна
jmp .no_redraw
@@:
mov edi,dword[ebp+8] ;restore edi
;mov esi,tl_box_top
;add esi,tl_box_height ;esi = coord bottom border
call tl_draw_cursor ;перерисовка курсора
call tl_draw_caption_cur_pos
.no_redraw:
pop esi edi eax
pop ebp
ret 4
align 4
tl_cur_page_up: ;перенести курсор на 1 страницу выше
push ebp
mov ebp,esp
push eax edi esi
mov edi,dword[ebp+8]
cmp tl_p_scrol,0 ;если есть указатель на скроллинг
je .no_redraw
mov esi,tl_p_scrol
call tl_get_rows_count ;eax = rows count
cmp tl_cur_pos,0
jne @f
cmp dword[esi+24],0 ;если скроллинг на верху, выходим
jne @f
jmp .no_redraw
@@:
cmp tl_cur_pos,eax ;проверяем позицию курсора и кол-во сток на странице
jl @f ;если меньше, то приравниваем к 0, что-бы не отнять больше чем надо
sub tl_cur_pos,eax
jmp .cursor
@@:
mov tl_cur_pos,0
.cursor:
cmp dword[esi+24],eax
jl @f
sub dword[esi+24],eax
jmp .scroll
@@:
mov dword[esi+24],0
.scroll:
;перерисовки окна и скроллинга
push dword edi
call tl_draw ;draw window
push dword esi
mov eax,dword[ebp+8]
mov eax,tl_sb_draw ;.redraw
call dword[eax]
.no_redraw:
pop esi edi eax
pop ebp
ret 4
align 4
tl_cur_page_down: ;перенести курсор на 1 страницу ниже
push ebp
mov ebp,esp
push eax ebx ecx edi esi
;eax - кол-во строк на странице
;ebx - макс. позиция курсора
;ecx - макс. позиция скроллинга
mov edi,dword[ebp+8]
cmp tl_p_scrol,0 ;если есть указатель на скроллинг
je .no_redraw
mov esi,tl_p_scrol
call tl_get_node_count ;eax = node count
mov ebx,eax
call tl_get_rows_count ;eax = rows count
mov ecx,ebx
inc ecx ;если нижний узел виден на половину
cmp ecx,eax ;if (ecx>eax) { ecx=ecx-eax } else { ecx=0 }
jl @f
sub ecx,eax ;уменьшаем максимальную позицию скроллинга, так что-бы были видны последние узлы
jmp .control
@@:
xor ecx,ecx ;ecx=0 - все узлы влазят в экран, скроллинг не нужен
.control:
cmp tl_cur_pos,ebx ;курсор внизу ?
jl @f
cmp dword[esi+24],ecx ;скроллинг внизу ?
jl @f
jmp .no_redraw
@@:
add tl_cur_pos,eax ;перемещаем курсор
cmp tl_cur_pos,ebx
jl @f
mov tl_cur_pos,ebx
@@:
add dword[esi+24],eax ;перемещаем скроллинг
cmp dword[esi+24],ecx
jl @f
mov dword[esi+24],ecx
@@:
;перерисовки окна и скроллинга
push dword edi
call tl_draw ;draw window
push dword esi
mov eax,dword[ebp+8]
mov eax,tl_sb_draw ;.redraw
call dword[eax]
.no_redraw:
pop esi edi ecx ebx eax
pop ebp
ret 4
align 4
tl_node_close_open: ;открыть/закрыть узел (работает с узлами которые имеют дочерние узлы)
push ebp
mov ebp,esp
push eax edx edi
mov edi,dword[ebp+8]
call tl_get_cur_node_index ;eax = позиция узла на котором стоит курсор
cmp eax,2 ;курсор стоит на узле ?
jl @f
imul eax,sizeof.TreeList
add eax,tl_data_nodes
;eax = указатель на структуру узла выбранного курсором
push dword edi
push dword eax
call tl_node_poi_get_next_info
pop dword edx ;edx = указатель на структуру узла который идет после узла eax
cmp edx,0 ;есть ли узлы ниже выбранного нами ?
je @f
mov dl,byte[edx+2] ;берем уровень нижнего узла
cmp byte[eax+2],dl ;+2 = .lev
jge @f ;если нижние узлы меньшего уровня, значит они не дочерние, конец функции
xor byte[eax+3],1 ;+3 = .clo *** открытие/закрытие узла ***
call tb_scrol_resize ;обработка скроллинга
push dword edi
call tl_draw ;обновление окна
@@:
pop edi edx eax
pop ebp
ret 4
align 4
tl_node_lev_inc: ;увеличить уровень
push ebp
mov ebp,esp
push eax edx edi
mov edi,dword[ebp+8]
bt tl_style,2 ;tl_list_box_mode
jc @f
call tl_get_cur_node_index ;eax=po_t
cmp eax,2
jl @f
imul eax,sizeof.TreeList
add eax,tl_data_nodes
mov edx,eax
inc word[edx+2]
@@:
pop edi edx eax
pop ebp
ret 4
align 4
tl_node_lev_dec: ;уменьшить уровень
push ebp
mov ebp,esp
push eax edx edi
mov edi,dword[ebp+8]
call tl_get_cur_node_index ;eax=po_t
cmp eax,2
jl @f
imul eax,sizeof.TreeList
add eax,tl_data_nodes
mov edx,eax
cmp word[edx+2],0
je @f
dec word[edx+2]
@@:
pop edi edx eax
pop ebp
ret 4
align 4
tl_node_move_up: ;перемещаем узел вверх
push ebp
mov ebp,esp
push eax ebx ecx edx edi esi
mov edi,dword[ebp+8]
call tl_get_cur_node_index ;eax=po_t
cmp eax,2
jl @f
mov ebx,eax ;copy index of node struct
mov edx,tl_data_nodes
mov ecx,edx
add ecx,sizeof.TreeList
imul eax,sizeof.TreeList
add eax,edx ;eax = pointer to 2 node struct
mov edx,eax ;edx = pointer to 2 node struct
mov esi,eax ;esi = pointer to 2 node struct
call tl_iterat_perv ;edx = pointer to 1 node struct
call tl_get_node_index ;eax = index of 1 node struct
cmp edx,ecx
jle @f
cmp dword[edx+8],ebx ;+8 next
jne .po8
call tl_node_move_po6 ;узлы идут подряд меняем 6 ссылок
jmp .cur_mov
.po8:
call tl_node_move_po8 ;узлы идут не подряд меняем 8 ссылок
.cur_mov:
push dword edi
call tl_cur_perv
push dword edi
call tl_draw
@@:
pop esi edi edx ecx ebx eax
pop ebp
ret 4
align 4
tl_node_move_down: ;перемещаем узел вниз
push ebp
mov ebp,esp
push eax ebx ecx edx edi esi
mov edi,dword[ebp+8]
call tl_get_cur_node_index ;eax=po_t
cmp eax,2
jl @f
mov ebx,eax ;copy index of node struct
mov edx,tl_data_nodes
mov ecx,edx
add ecx,sizeof.TreeList
imul eax,sizeof.TreeList
add eax,edx ;eax = pointer to 1 node struct
mov edx,eax ;edx = pointer to 1 node struct
mov esi,eax ;esi = pointer to 1 node struct
call tl_iterat_next ;edx = pointer to 2 node struct
call tl_get_node_index ;eax = index of 2 node struct
cmp edx,ecx
jle @f
cmp dword[esi+8],eax ;+8 next
jne .po8
xchg eax,ebx ;меняе порядок следования заменяемых узлов
xchg edx,esi
call tl_node_move_po6 ;узлы идут подряд меняем 6 ссылок
jmp .cur_mov
.po8: ;а тут порядок следования узлов не меняем
call tl_node_move_po8 ;узлы идут не подряд меняем 8 ссылок
.cur_mov:
push dword edi
call tl_cur_next
push dword edi
call tl_draw
@@:
pop esi edi edx ecx ebx eax
pop ebp
ret 4
align 4
tl_node_move_po6:
mov ecx,edx ;save node pointer
call tl_move_perv
mov dword[edx+8],ebx
mov edx,esi
call tl_move_next
mov dword[edx+4],eax
mov edx,ecx ;restore node pointer
;+4 perv
mov ecx,dword[edx+4]
mov dword[esi+4],ecx
;+8 next
mov ecx,dword[esi+8]
mov dword[edx+8],ecx
mov dword[edx+4],ebx
mov dword[esi+8],eax
ret
;input
;eax = index 1 node struct
;ebx = index 2 node struct
;edx = pointer 1 node struct
;esi = pointer 2 node struct
;edi = pointer to 'TreeList' struct
;output:
;eax = ?
;ebx = ?
;ecx = ?
align 4
tl_node_move_po8:
; push ecx
mov ecx,edx ;save node pointer
call tl_move_perv
mov dword[edx+8],ebx
mov edx,ecx
call tl_move_next
mov dword[edx+4],ebx
mov edx,esi
call tl_move_perv
mov dword[edx+8],eax
mov edx,esi
call tl_move_next
mov dword[edx+4],eax
mov edx,ecx ;restore node pointer
; pop ecx
;+4 perv
mov eax,dword[edx+4]
mov ebx,dword[esi+4]
xchg eax,ebx
mov dword[edx+4],eax
mov dword[esi+4],ebx
;+8 next
mov eax,dword[edx+8]
mov ebx,dword[esi+8]
xchg eax,ebx
mov dword[edx+8],eax
mov dword[esi+8],ebx
ret
;input:
; edi = pointer to 'TreeList' struct
align 4
tl_draw_caption_cur_pos:
cmp tl_capt_cy,9 ;9 - minimum caption height
jl @f
push eax ebx ecx edx edi esi
mov eax,47 ;draw
mov ebx,0x40000
mov ecx,tl_cur_pos
inc ecx
mov edx,tl_box_left
shl edx,16
add edx,50*65536+3
add edx,tl_box_top
mov esi,tl_col_txt
or esi,0x40000000 ;закрашивать фон цветом edi
mov edi,tl_col_zag
int 0x40
pop esi edi edx ecx ebx eax
@@:
ret
;input:
;dword[ebp+ 8] - memory size
;dword[ebp+12] - pointer to memory
;dword[ebp+16] - options: 0 - first element, 1 - add next element
;dword[ebp+20] - pointer to 'TreeList' struct
;output:
;dword[ebp+ 8] - error code
align 4
tl_save_mem:
push ebp
mov ebp,esp
push eax ebx ecx edx edi esi
mov esi,dword[ebp+12]
mov edi,dword[ebp+20]
cmp dword[ebp+16],0 ;add mode
je @f
.beg_cycle:
cmp dword[esi],0x65657274 ;0x65657274 = 'tree'
jne @f
xor ebx,ebx
mov bx,word[esi+4]
imul ebx,dword[esi+6]
add ebx,tl_save_load_heder_size
add esi,ebx
jmp .beg_cycle
@@:
xor ebx,ebx
mov bx,tl_info_size
call tl_get_node_count_all ;eax = all node count
mov ecx,eax ;вычисляем сколько памяти должно быть заполнено
imul ecx,ebx ;умножаем на размер структуры узла
add ecx,tl_save_load_heder_size+1 ;element header +1 end element sumbol
add ecx,esi ;добавляем указатель на начало памяти (с учетом ранее записанных структур)
sub ecx,dword[ebp+12] ;отнимаем указатель на начало памяти (без ранее записанных структур)
cmp ecx,dword[ebp+8] ;ecx = element memory size
jg .err_mem_size
;save tree params
mov dword[esi],0x65657274 ;0x65657274 = 'tree'
mov word[esi+4],bx
mov dword[esi+6],eax ;element count
add esi,10
mov eax,tl_style
mov dword[esi],eax
add esi,4
mov eax,tl_cur_pos
mov dword[esi],eax
add esi,4
mov ax,tl_info_capt_offs
mov word[esi],ax
add esi,2
mov ax,tl_info_capt_len
mov word[esi],ax
add esi,2+4
;cycle to nodes
mov edx,tl_data_nodes
mov ecx,edx
add ecx,sizeof.TreeList
@@:
call tl_iterat_next_all
cmp edx,ecx
jle @f
;save node params
call tl_get_node_index ;eax = index of pointer [edx]
mov dword[esi],eax
add esi,4
mov eax,dword[edx] ;eax = (type; lev; clo)
mov dword[esi],eax
add esi,4
;push dword edi
;call tl_node_get_data
;pop eax
push dword edi
push dword edx
call tl_node_poi_get_data
pop dword eax
;call tl_node_copy_data
push ecx edi
mov edi,eax
mov ecx,ebx
xchg esi,edi
rep movsb
mov esi,edi
pop edi ecx
;add esi,ebx
jmp @b
@@:
mov byte[esi],0 ;end of 'treelist'
mov dword[ebp+20],0 ;return error code
jmp @f
.err_mem_size:
or dword[ebp+20],tl_err_save_memory_size
@@:
pop esi edi edx ecx ebx eax
pop ebp
ret 12
;input:
;dword[ebp+ 8] - memory size
;dword[ebp+12] - pointer to memory
;word[ebp+16] - options: element index
;word[ebp+18] - options: 2*(add mode)+(init mode)
;dword[ebp+20] - pointer to 'TreeList' struct
;output:
;dword[ebp+ 8] - error code
align 4
tl_load_mem:
push ebp
mov ebp,esp
push eax ebx ecx edx edi esi
mov esi,dword[ebp+12]
mov edi,dword[ebp+20]
mov dword[ebp+20],0 ;return error code
xor ecx,ecx
mov cx,word[ebp+16]
cmp cx,0 ;load in array mode
je @f
.beg_cycle:
cmp dword[esi],0x65657274 ;0x65657274 = 'tree'
jne .no_tree
xor ebx,ebx
mov bx,word[esi+4]
imul ebx,dword[esi+6]
add ebx,tl_save_load_heder_size
add esi,ebx
loop .beg_cycle
@@:
cmp dword[esi],0x65657274 ;0x65657274 = 'tree'
jne .no_tree
bt word[ebp+18],1 ;load in add mode
jc @f
push dword edi
call tl_info_clear
@@:
xor ebx,ebx
mov bx,word[esi+4] ;info_size
cmp bx,tl_info_size
je @f
or dword[ebp+20],tl_err_load_info_size
@@:
mov ecx,dword[esi+6] ;count nodes
cmp ecx,1
jl .end_f
add esi,tl_save_load_heder_size
@@:
;load node params
push dword edi
mov eax,dword[esi+4]
ror eax,16
push dword eax ;options (type; lev; clo)
add esi,8
push dword esi
call tl_node_add
push dword edi
call tl_cur_next
;...
add esi,ebx
loop @b
jmp .end_f
.no_tree:
mov dword[ebp+20],tl_err_load_caption
.end_f:
pop esi edi edx ecx ebx eax
pop ebp
ret 12
;ascii scan key
; 13 28 Enter
; 32 57 Space
; 178 72 Up
; 177 80 Down
; 176 75 Left
; 179 77 Right
; 182 83 Delete
; 184 73 Pg Up
; 183 81 Pg Dn
tl_key_ascii db 13,32,178,177,176,179,182,184,183
tl_key_scan db 28,57, 72, 80, 75, 77, 83, 73, 81
txt_capt_cur db '‘ва®Є ',0
txt_capt_otm db 'Ћв¬Ґ­л',0
}