forked from KolibriOS/kolibrios
caf224ae96
1) 'tl_mouse' add mouse in child scroll bar 2) optimize some functions git-svn-id: svn://kolibrios.org@1309 a494cfbc-eb01-0410-851d-a64ba20cac60
2448 lines
56 KiB
Plaintext
2448 lines
56 KiB
Plaintext
; макрос для системной библиотеки box_lib.obj
|
||
; элемент TreeList для Kolibri OS
|
||
; файл последний раз изменялся 8.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_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,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
|
||
rb 4
|
||
.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 .test_scroll ;.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
|
||
;--- mouse event for children scrollbar ----------------------------------------
|
||
.test_scroll:
|
||
mov edx,tl_p_scrol
|
||
cmp edx,0
|
||
je .no_in_wnd ;пользователь не создал дочернего скроллинга
|
||
shr ebx,16
|
||
add bx,word[edx] ;+0 .size_x
|
||
shl ebx,16
|
||
cmp eax,ebx ;правая граница окна
|
||
jg .no_in_wnd
|
||
|
||
mov eax,dword[edx+16] ;+16 .max_area
|
||
cmp eax,dword[edx+20] ;+20 .cur_area
|
||
jbe .no_in_wnd ;все узлы попадают в окно скроллинга
|
||
push dword edx
|
||
call scroll_bar_vertical.mouse ;scrollbar_ver_mouse
|
||
|
||
cmp dword[edx+40],0 ;+40 .redraw
|
||
je @f
|
||
mov dword[edx+40],0 ;+40 .redraw
|
||
push dword edi
|
||
call tl_draw ;произошли изменения скроллинга
|
||
@@:
|
||
cmp dword[edx+46],0 ;+46 .delta2
|
||
jne .no_draw ;попали на скроллинг - не снимаем фокус с TreeList
|
||
;-------------------------------------------------------------------------------
|
||
.no_in_wnd: ;не попали в окно - потеря фокуса (при условии что фокус был на данном эелементе)
|
||
mov ebx,tl_el_focus
|
||
cmp dword[ebx],edi
|
||
jne .no_draw ;элемент не в фокусе
|
||
mov dword[ebx],0 ;reset focus
|
||
mov esi,tl_box_top
|
||
add esi,tl_box_height ;esi = coord bottom border
|
||
call tl_draw_cursor ;рисуем курсор с потеряным фокусом
|
||
.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 ebx,edi ;calculate cursor position
|
||
mov eax,tl_cur_pos
|
||
inc eax
|
||
lea edi,[txt_capt_cur]
|
||
add edi,7
|
||
call tl_convert_to_str
|
||
|
||
mov edi,ebx
|
||
mov eax,tl_tim_undo
|
||
lea edi,[txt_capt_otm]
|
||
add edi,7
|
||
call tl_convert_to_str
|
||
mov edi,ebx ;restore edi
|
||
|
||
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
|
||
@@:
|
||
|
||
;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 eax
|
||
|
||
; mov bl,byte[edx+2]
|
||
|
||
cmp tl_tim_undo,0
|
||
je .beg1
|
||
|
||
push eax
|
||
.beg0:
|
||
call tl_move_perv
|
||
cmp edx,ecx
|
||
jle @f
|
||
call tl_node_not_vis ;пропуск удаленных и отмененных
|
||
cmp al,1
|
||
je .beg0
|
||
|
||
.beg1:
|
||
call tl_move_perv
|
||
cmp edx,ecx
|
||
jle @f
|
||
cmp dword[edx+16],0 ;td = 'time delete' -> пропуск удаленных
|
||
jne .beg1
|
||
|
||
@@:
|
||
call tl_move_max_clo_par
|
||
pop eax
|
||
ret
|
||
|
||
|
||
;input:
|
||
; edx = pointer to some node struct
|
||
; edi = pointer to 'TreeList' struct
|
||
;output:
|
||
; edx = pointer closed parent node with maximum level
|
||
align 4
|
||
tl_move_max_clo_par: ;находит родительский закрытый узел максимального уровня
|
||
push eax ebx
|
||
mov eax,edx
|
||
xor ebx,ebx
|
||
.beg:
|
||
call tl_move_par
|
||
cmp byte[edx+3],1 ;родительский узел закрыт ?
|
||
jne @f
|
||
mov eax,edx
|
||
@@:
|
||
cmp ebx,edx
|
||
je .end_f
|
||
mov ebx,edx
|
||
jmp .beg
|
||
.end_f:
|
||
mov edx,eax
|
||
pop ebx eax
|
||
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:
|
||
; ecx =
|
||
; edx = pointer to some node struct
|
||
; edi = pointer to 'TreeList' struct
|
||
;output:
|
||
; edx = pointer to parent node struct
|
||
align 4
|
||
tl_move_par: ;передвигаемся на родительский узел, если такого нет, то оставляем старое значение указателя
|
||
cmp byte[edx+2],0
|
||
je .end_f ;узел 0-го уровня не может быть дочерним
|
||
push eax ebx esi
|
||
mov esi,edx ;copy node pointer (edx)
|
||
mov bl,byte[edx+2]
|
||
@@:
|
||
call tl_move_perv
|
||
cmp edx,ecx
|
||
jle @f ;все выше стоящие узлы не родительские
|
||
call tl_node_not_vis ;пропуск удаленных и отмененных
|
||
cmp al,1
|
||
je @b
|
||
cmp byte[edx+2],bl
|
||
jl .end_0 ;удачно нашли родительский узел
|
||
jmp @b
|
||
@@:
|
||
mov esi,ebx ;restore node pointer
|
||
.end_0:
|
||
pop esi ebx eax
|
||
.end_f:
|
||
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 edx,tl_box_left
|
||
shl edx,16
|
||
mov dx,ax
|
||
add edx,tl_box_top
|
||
add dx,tl_capt_cy
|
||
|
||
mov ecx,tl_el_focus ;проверяем в фокусе элемент или нет
|
||
cmp dword[ecx],edi
|
||
je .focus
|
||
xor eax,eax
|
||
xor ecx,ecx
|
||
mov cx,tl_img_cx
|
||
mov ax,tl_img_cy
|
||
imul eax,ecx
|
||
imul eax,4*3 ;4=icon index 3=rgb
|
||
add ebx,eax
|
||
.focus:
|
||
|
||
mov cx,tl_img_cx
|
||
shl ecx,16
|
||
mov cx,tl_img_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
|
||
call tl_draw_node_icon_par_lin_up
|
||
.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:
|
||
; al = уровень элемента
|
||
;...
|
||
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
|
||
|
||
|
||
|
||
;icon:
|
||
; al = уровень элемента
|
||
;...
|
||
align 4
|
||
tl_draw_node_icon_par_lin_up:
|
||
push eax ebx ecx edx esi
|
||
cmp tl_data_img_sys,0 ;if not image
|
||
je @f
|
||
cmp al,0
|
||
je @f
|
||
|
||
;---------
|
||
xor esi,esi ;в si будем насчитывать кол-во иконок, нужных для прорисовки линии
|
||
.cycle0:
|
||
call tl_iterat_perv ;get perv visible item
|
||
cmp edx,ecx
|
||
jle .cycle1 ;if begin of list
|
||
|
||
cmp byte[edx+2],al
|
||
jle .cycle1 ;уровень верхнего элемента не требует прорисовки
|
||
inc si
|
||
jmp .cycle0
|
||
.cycle1:
|
||
cmp si,0 ;si = кол-во иконок линии которые нужно нарисовать сверху
|
||
je @f
|
||
shl esi,16
|
||
|
||
pop ecx ;esi->ecx
|
||
push ecx ;save esi
|
||
|
||
ror ebx,16
|
||
sub bx,tl_img_cx
|
||
ror ebx,16
|
||
|
||
mov edx,ebx
|
||
ror ecx,16
|
||
mov dx,cx
|
||
mov cx,bx
|
||
ror ecx,16
|
||
mov cx,tl_img_cy ;restore size y (if crop)
|
||
mov ebx,3 ;rgb = 3 bytes
|
||
imul bx,tl_img_cx
|
||
imul bx,tl_img_cy
|
||
;imul ebx,1
|
||
add ebx,tl_data_img_sys
|
||
|
||
add esi,tl_box_top
|
||
add si,tl_capt_cy ;si = верхняя граница окна
|
||
mov eax,7
|
||
;---------
|
||
.cycle2:
|
||
sub dx,tl_img_cy ;поднимаем координату y вверх
|
||
cmp dx,si
|
||
jl @f
|
||
; int 0x40 ;draw line icon
|
||
cmp esi,0x10000
|
||
jl @f
|
||
int 0x40 ;draw line icon
|
||
sub esi,0x10000 ;уменьшаем счетчик иконок
|
||
jmp .cycle2
|
||
@@:
|
||
pop esi edx ecx ebx eax
|
||
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
|
||
call scroll_bar_vertical.draw
|
||
@@:
|
||
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]
|
||
call scroll_bar_vertical.draw
|
||
@@:
|
||
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
|
||
call scroll_bar_vertical.draw
|
||
|
||
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]
|
||
call scroll_bar_vertical.draw
|
||
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
|
||
call scroll_bar_vertical.draw
|
||
.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
|
||
call scroll_bar_vertical.draw
|
||
.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 ebx,edi ;calculate cursor position
|
||
mov eax,tl_cur_pos
|
||
inc eax
|
||
lea edi,[txt_capt_cur]
|
||
add edi,7
|
||
call tl_convert_to_str
|
||
mov edi,ebx
|
||
|
||
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,0xc0000000 ;0x40000000 закрашивать фон цветом edi
|
||
lea edx,[txt_capt_cur]
|
||
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 (in header)
|
||
mov dword[esi],0x65657274 ;0x65657274 = 'tree'
|
||
mov word[esi+4],bx
|
||
mov dword[esi+6],eax ;element count
|
||
|
||
mov eax,tl_style
|
||
mov dword[esi+10],eax
|
||
|
||
mov eax,tl_cur_pos
|
||
mov dword[esi+14],eax
|
||
|
||
mov ax,tl_info_capt_offs
|
||
mov word[esi+18],ax
|
||
|
||
mov ax,tl_info_capt_len
|
||
mov word[esi+20],ax
|
||
|
||
;copy scroll position
|
||
mov edx,tl_p_scrol
|
||
mov eax,dword[edx+24] ;+24 .position
|
||
mov dword[esi+22],eax
|
||
|
||
add esi,tl_save_load_heder_size ;add header size
|
||
|
||
;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
|
||
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
|
||
mov edx,esi ;save header pointer
|
||
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
|
||
|
||
bt word[ebp+18],1 ;load in add mode
|
||
jc .no_tree
|
||
mov eax,dword[edx+14] ;set cursor pos
|
||
mov tl_cur_pos,eax
|
||
mov eax,dword[edx+22] ;set scroll pos
|
||
mov ebx,tl_p_scrol
|
||
cmp ebx,0
|
||
je .end_f
|
||
mov dword[ebx+24],eax ;+24 .position
|
||
push dword ebx ;pointer to scroll struct
|
||
call scroll_bar_vertical.draw
|
||
|
||
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
|
||
|
||
;этот код не мой, он преобразует число в строку
|
||
;input:
|
||
; eax = value
|
||
; edi = string buffer
|
||
;output:
|
||
; edi =
|
||
align 4
|
||
tl_convert_to_str:
|
||
pushad
|
||
mov dword[edi+1],0x20202020
|
||
call .str
|
||
popad
|
||
ret
|
||
|
||
align 4
|
||
.str:
|
||
mov ecx,0x0a ;задается система счисления изменяются регистры ebx,eax,ecx,edx входные параметры eax - число
|
||
;преревод числа в ASCII строку взодные данные ecx=система счисленя edi адрес куда записывать, будем строку, причем конец переменной
|
||
cmp eax,ecx ;сравнить если в eax меньше чем в ecx то перейти на @@-1 т.е. на pop eax
|
||
jb @f
|
||
xor edx,edx ;очистить edx
|
||
div ecx ;разделить - остаток в edx
|
||
push edx ;положить в стек
|
||
;dec edi ;смещение необходимое для записи с конца строки
|
||
call .str;перейти на саму себя т.е. вызвать саму себя и так до того момента пока в eax не станет меньше чем в ecx
|
||
pop eax
|
||
@@: ;cmp al,10 ;проверить не меньше ли значение в al чем 10 (для системы счисленя 10 данная команда - лишная))
|
||
;sbb al,$69 ;- честно данная инструкция меня заставляет задуматься т.е. я не знаю как это работает
|
||
;das ;после данной команды как бы происходит уменьшение al на 66h (в книге написано другое)
|
||
or al,0x30 ;данная команда короче чем две выше
|
||
stosb ;записать элемент из регистра al в ячеку памяти es:edi
|
||
ret ;вернуться чень интересный ход т.к. пока в стеке храниться кол-во вызовов то столько раз мы и будем вызываться
|
||
}
|