kolibrios/programs/system/open/open.asm

944 lines
20 KiB
NASM
Raw Normal View History

DEBUG equ 0
LIST_WIDTH equ 256
WIN_WIDTH equ (LIST_WIDTH + 16 + 12)
LIST_SIZE equ 12
LINE_SIZE equ 40
LIST_HEIGHT equ (LIST_SIZE * LINE_SIZE / 2)
WIN_HEIGHT equ (LIST_HEIGHT + 80)
use32
org 0
db 'MENUET01'
dd 1, main, dataend, memory, memory, params, 0
include "../../proc32.inc"
include "../../macros.inc"
include "../../dll.inc"
include "../../cmp.inc"
include "../../string.inc"
include "../../develop/libraries/box_lib/trunk/box_lib.mac"
include "lang.inc"
if DEBUG eq 1
include "../../debug.inc"
end if
;===============================
if lang eq ru
title db "<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", 0
browse_txt db "<22><><EFBFBD><EFBFBD><EFBFBD>...", 0
notify_txt db "'Incorrect ", '"', "/sys/settings/assoc.ini", '"', " file' -tE", 0
checkbox_txt db "<22><EFBFBD><EFBFBD><ECA7AE><EFBFBD><EFBFBD> <20><EFBFBD><E1A5A3>", 0
else if lang eq et
title db "Open with", 0
browse_txt db "Browse...", 0
notify_txt db "'Incorrect ", '"', "/sys/settings/assoc.ini", '"', " file' -tE", 0
checkbox_txt db "Always use selected program", 0
else if lang eq it
title db "Open with", 0
browse_txt db "Browse...", 0
notify_txt db "'Incorrect ", '"', "/sys/settings/assoc.ini", '"', " file' -tE", 0
checkbox_txt db "Always use selected program", 0
else
title db "Open with", 0
browse_txt db "Browse...", 0
notify_txt db "'Incorrect ", '"', "/sys/settings/assoc.ini", '"', " file' -tE", 0
checkbox_txt db "Always use selected program", 0
end if
sys_dir db "/sys", 0
slash db "/", 0
open_dialog_path db "/sys/file managers/opendial", 0
app_link db "$", 0
icons db "/sys/icons32.png", 0
communication_area_name db "FFFFFF_open_dialog", 0
assoc_ini db "/sys/settings/assoc.ini", 0
.sec db "Assoc", 0
.exec db "exec", 0
.icon db "icon", 0
sb_apps scrollbar \
13, WIN_WIDTH - 25, LIST_HEIGHT, 10 + 12, \ ;; w, x, h, y
0, 0, LIST_SIZE / 2, 0, \ ;; b.h, max, area, pos
0, 0, 0, 2
cb_always check_box2 \
5 shl 16 + 16, (LIST_HEIGHT + 33) shl 16 + 16, 6, 0, 0, 0, checkbox_txt, ch_flag_middle
opendialog:
.type dd 0
.procinfo dd buffer3
.com_area_name dd communication_area_name
.com_area dd 0
.opendir_path dd buffer4
.dir_default_path dd sys_dir
.start_path dd open_dialog_path
.draw_window dd draw_window
.status dd 0
.openfile_pach dd buffer
.filename_area dd buffer5
.filter_area dd .filter
.x:
.x_size dw 420
.x_start dw 200
.y:
.y_size dw 320
.y_start dw 120
.filter dd 0
ps_addres:
dd 0 ;; type
dw 7 ;; y
dw 4 ;; x
dw 6 ;; font.w
dw LIST_WIDTH ;; w
dd 0 ;; mono
dd 0 ;; without bg
.color dd 0 ;; text color
dd 0 ;; bg color
.txt dd 0 ;; text
dd buffer2
dd 0
is_execute:
dd 7, 0, 0, 0, 0
db 0
dd buffer
is_openas:
dd 7, 0, 0, 0, 0
db 0
dd buffer
is_open:
dd 7, 0, 0, 0, 0
db 0
dd buffer
is_undefined:
dd 7, 0, notify_txt, 0, 0
db "/sys/@notify", 0
is_openimg_info:
dd 5, 0, 0, 0, img.buf
db 0
dd icons
is_openimg:
dd 0, 0, 0, 0, 0
db 0
dd icons
is_file_exists:
dd 0, 0, 0, 0, buffer6
db 0
dd buffer
last_x dd -1
last_y dd -1
if DEBUG eq 1
std_param db "~/sys/example.asm", 0
end if
imports:
library libini, "libini.obj"
import libini, libini.get_str, "ini_get_str", \
libini.set_str, "ini_set_str", \
libini.get_num, "ini_get_int", \
libini.for_each_section, "ini_enum_sections"
imports_add:
library libimg, "libimg.obj", \
boxlib, "box_lib.obj", \
prclib, "proc_lib.obj"
import libimg, libimg.init, "lib_init", \
libimg.toRGB, "img_to_rgb2", \
libimg.decode, "img_decode", \
libimg.destroy, "img_destroy"
import boxlib, scrollbar.draw, "scrollbar_v_draw", \
scrollbar.mouse, "scrollbar_v_mouse", \
pathshow.init, "PathShow_prepare", \
pathshow.draw, "PathShow_draw", \
checkbox.init, "init_checkbox2", \
checkbox.draw, "check_box_draw2", \
checkbox.mouse, "check_box_mouse2"
import prclib, opendialog.lib_init, "lib_init", \
opendialog.init, "OpenDialog_init", \
opendialog.start, "OpenDialog_start"
;===============================
main:
mcall 68, 11
stdcall dll.Load, imports
if DEBUG eq 1
stdcall string.copy, std_param, params
end if
;; trim params
stdcall string.to_lower_case, params
stdcall string.trim_last, params
stdcall string.trim_first, params
mov [param_s], eax
;; if empty - exit
cmpe [eax], byte 0, exit
;; if folder
stdcall string.length, [param_s]
add eax, [param_s]
cmpe [eax - 1], byte '/', open
;; if dialog
mov eax, [param_s]
mov [is_openas + 8], eax
cmpne [eax], byte '~', @f
inc [param_s]
mov eax, [param_s]
mov [is_openas + 8], eax
jmp start_dialog
@@:
;; if without '.' - execute
stdcall string.last_index_of, [param_s], '.', 1
cmpe eax, -1, execute
;; if '.' is part of path - execute
mov esi, eax
stdcall string.last_index_of, [param_s], '/', 1
cmpg eax, esi, execute
;; if ext == "kex" - execute
add esi, [param_s]
mov [param_e], esi
cmpe [esi], dword "kex", execute
open_as:
invoke libini.get_str, assoc_ini, assoc_ini.sec, esi, buffer, 2048, undefined
cmpe [buffer], byte 0, start_dialog_pre
cmpne [buffer], byte "$", @f
invoke libini.get_str, assoc_ini, buffer + 1, assoc_ini.exec, buffer, 2048, undefined
cmpe [buffer], byte 0, ini_error
@@:
mcall 70, is_openas
jmp exit
execute:
mov eax, [param_s]
mov [is_execute + 21], eax
mcall 70, is_execute
jmp exit
open:
invoke libini.get_str, assoc_ini, assoc_ini.sec, slash, buffer, 2048, undefined
cmpne [buffer], byte "$", @f
invoke libini.get_str, assoc_ini, buffer + 1, assoc_ini.exec, buffer, 2048, undefined
cmpe [buffer], byte 0, ini_error
@@:
mov eax, [param_s]
mov [is_open + 8], eax
mcall 70, is_open
jmp exit
ini_error:
mcall 70, is_undefined
jmp exit
;----------------------
start_dialog_pre:
or [cb_always.flags], ch_flag_en
start_dialog:
stdcall dll.Load, imports_add
invoke opendialog.lib_init
mcall 40, 100111b
;; get title
stdcall string.copy, title, win.title
;; get positions
mcall 14
movzx ebx, ax
shr ebx, 1
shr eax, 16 + 1
sub eax, WIN_WIDTH / 2 - 1
sub ebx, WIN_HEIGHT / 2 - 1
mov [win.x], eax
mov [win.y], ebx
;; get colors
mcall 48, 3, skin, sizeof.system_colors
;; get opendialog
invoke opendialog.init, opendialog
;; get pathshow
mov eax, [param_s]
mov ebx, [skin.work_text]
mov [ps_addres.txt], eax
mov [ps_addres], ebx
invoke pathshow.init, ps_addres
;; get checkbox
mov eax, 0xFFFfff
mov ebx, [skin.work_graph]
mov ecx, [skin.work_text]
mov [cb_always.color], eax
mov [cb_always.border_color], ebx
mov [cb_always.text_color], ecx
invoke checkbox.init, cb_always
;; get list
invoke libini.for_each_section, assoc_ini, section_cb
mov eax, [sb_apps.max_area]
and eax, 1b
shr [sb_apps.max_area], 1
add [sb_apps.max_area], eax
mov eax, 0xFFFfff
mov ebx, 0xCCCccc ;[skin.3d]
mov [sb_apps.bg_color], eax
mov [sb_apps.front_color], ebx
mov [sb_apps.line_color], ebx
;; get icons
mcall 70, is_openimg_info
mov edx, dword [img.buf + 32]
shl edx, 4
stdcall mem.Alloc, edx
mov [img.rgb], eax
mov [is_openimg + 12], edx
m2m dword[is_openimg + 16], dword[img.rgb]
mcall 70, is_openimg
invoke libimg.decode, dword[img.rgb], ebx, 0
mov [img], eax
;; alpha
mov edi, [eax + 8]
shl edi, 7
sub edi, 4
mov eax, [eax + 24]
.setalpha:
mov ebx, [eax + edi]
shr ebx, 24
cmpne ebx, 0, @f
mov ecx, 0xFFFfff
mov [eax + edi], ecx
@@:
cmpe edi, 0, @f
sub edi, 4
jmp .setalpha
@@:
invoke libimg.toRGB, [img], [img.rgb]
invoke libimg.destroy, [img]
;----------------------
update:
mcall 10
cmpe eax, EV_REDRAW, event_redraw
cmpe eax, EV_KEY, event_key
cmpe eax, EV_BUTTON, event_button
cmpe eax, EV_MOUSE, event_mouse
jmp update
;----------------------
event_redraw:
call draw_window
jmp update
;----------------------
event_key:
mcall 2
cmpe ah, 27, exit
cmpe ah, 13, list_item_activate
cmpe ah, 9, event_button.opendialog
cmpe ah, 32, .toggle_cb
cmpe ah, 179, .go_right
cmpe ah, 176, .go_left
cmpe ah, 178, .go_up
cmpe ah, 177, .go_down
cmpl ah, "a", @f
cmpg ah, "z", @f
jmp .letter
@@:
cmpl ah, "<22>", @f
cmpg ah, "<22>", @f
jmp .letter
@@:
cmpl ah, "A", @f
cmpg ah, "Z", @f
jmp .letter_big
@@:
cmpl ah, "<22>", @f
cmpg ah, "<22>", @f
jmp .letter_big
@@:
cmpl ah, "0", @f
cmpg ah, "9", @f
jmp .letter
@@:
jmp update
.letter_big:
movzx ebx, ah
stdcall downcase_char, ebx
mov ah, al
.letter:
push eax
stdcall get_index
inc eax
mov ecx, eax
imul ebx, eax, 32
add ebx, list
pop eax
@@:
cmpe byte [ebx], 0, @f
movzx edx, byte [ebx]
stdcall downcase_char, edx
cmpne ah, al, .next
stdcall set_index, ecx
stdcall draw_list
jmp update
.next:
inc ecx
add ebx, 32
jmp @b
@@:
jmp update
.toggle_cb:
mov eax, [cb_always.flags]
mov ebx, eax
and ebx, ch_flag_en
cmpe ebx, 0, @f
sub eax, ch_flag_en
jmp .toggle_cb.redraw
@@:
add eax, ch_flag_en
.toggle_cb.redraw:
mov [cb_always.flags], eax
invoke checkbox.draw, cb_always
jmp update
.go_right:
mov esi, 1
jmp .go_anyway
.go_left:
mov esi, -1
jmp .go_anyway
.go_up:
mov esi, -2
jmp .go_anyway
.go_down:
mov esi, 2
.go_anyway:
;; HIDE OLD SELECTION
stdcall draw_item, [last_x], [last_y], 0
;; [X, Y] -> INDEX
stdcall get_index
;; CHANGE INDEX
add eax, esi
cmpl eax, [list.size], @f
mov eax, [list.size]
dec eax
@@:
cmpge eax, 0, @f
mov eax, 0
@@:
;; INDEX -> [X, Y]
stdcall set_index, eax
cmpe eax, 1, @f
;; PARTLY REDRAW
stdcall draw_item, [last_x], [last_y], 1
jmp update
;; FULL REDRAW
@@:
stdcall draw_list
jmp update
;----------------------
event_button:
mcall 17
cmpe ah, 1, exit
cmpe ah, 2, .opendialog
jmp list_item_activate
.opendialog:
invoke opendialog.start, opendialog
cmpne [opendialog.status], 1, update
mcall 70, is_openas
mov edi, 0
jmp save_assoc
;----------------------
list_item_activate:
stdcall get_index
shl eax, 5
add eax, list
cmpe byte [eax], 0, update
mov [param_a], eax
invoke libini.get_str, assoc_ini, eax, assoc_ini.exec, buffer, 256, undefined
cmpe byte [buffer], 0, ini_error
mcall 70, is_openas
mov edi, 1
jmp save_assoc
;----------------------
save_assoc:
mov eax, [cb_always.flags]
and eax, ch_flag_en
cmpe eax, 0, exit
cmpe edi, 0, @f
stdcall string.copy, app_link, buffer
stdcall string.concatenate, [param_a], buffer
@@:
invoke libini.set_str, assoc_ini, assoc_ini.sec, [param_e], buffer, 33
jmp exit
;----------------------
event_mouse:
invoke checkbox.mouse, cb_always
mov edi, [sb_apps.position]
invoke scrollbar.mouse, sb_apps
sub edi, [sb_apps.position]
jz @f
call draw_list
@@:
mcall 37, 1
movzx edi, ax
shr eax, 16
mov esi, eax
sub esi, 4
sub edi, 10 + 12
cmpl esi, 0, .out
cmpge esi, LIST_WIDTH, .out
cmpl edi, 0, .out
cmpge edi, LIST_HEIGHT, .out
mcall 37, 7
and eax, 0xFFFF
cmpe eax, 65535, .scroll_up
cmpe eax, 0, @f
.scroll_down:
mov eax, [sb_apps.position]
add eax, LIST_SIZE / 2
shl eax, 1
cmpge eax, [list.size], @f
inc [sb_apps.position]
stdcall draw_list
jmp update
.scroll_up:
cmpe [sb_apps.position], 0, @f
dec [sb_apps.position]
stdcall draw_list
jmp update
@@:
mov eax, esi
mov ebx, LIST_WIDTH / 2
mov edx, 0
div ebx
mov esi, eax
mov eax, edi
mov ebx, LINE_SIZE
mov edx, 0
div ebx
mov edi, eax
cmpne esi, [last_x], .redraw
cmpne edi, [last_y], .redraw
jmp @f
.redraw:
stdcall draw_item, [last_x], [last_y], 0
mov [last_x], esi
mov [last_y], edi
stdcall draw_item, esi, edi, 1
jmp @f
.out:
cmpe [last_x], -1, @f
stdcall draw_item, [last_x], [last_y], 0
mov [last_x], -1
mov [last_y], -1
@@:
jmp update
;----------------------
exit:
mcall -1
;----------------------
proc draw_window
mcall 12, 1
mov edx, [skin.work]
or edx, 0x34 shl 24
mcall 0, <[win.x], WIN_WIDTH>, <[win.y], WIN_HEIGHT>, , , win.title
stdcall draw_list
invoke pathshow.draw, ps_addres
invoke checkbox.draw, cb_always
mcall 13, <207, 66>, <LIST_HEIGHT + 29, 22>, [skin.work_graph]
mcall 8, <208, 63>, <LIST_HEIGHT + 30, 19>, 2, [skin.work_button]
;
mov ecx, [skin.work_button_text]
add ecx, 0x80 shl 24
mcall 4, <214, LIST_HEIGHT + 37>, , browse_txt
;; buttons
mov eax, 8
mov ebx, 4 shl 16 + LIST_WIDTH / 2
mov ecx, (10 + 12) shl 16 + LINE_SIZE - 1
mov edx, 0x60 shl 24 + 10
mov edi, LIST_SIZE
mov esi, 0
@@:
cmpe edi, 0, @f
mcall
cmpe esi, 0, .doA
.doB:
sub ebx, LIST_WIDTH shl 16
add ecx, LINE_SIZE shl 16
.doA:
add ebx, (LIST_WIDTH / 2) shl 16
sub ecx, LINE_SIZE shl 16
not esi
add ecx, LINE_SIZE shl 16
inc edx
dec edi
jmp @b
@@:
mcall 12, 2
ret
endp
;----------------------
proc draw_list
mcall 13, <3, LIST_WIDTH + 2 + 12>, <9 + 12, 1>, [skin.work_graph]
mcall , , <LIST_HEIGHT + 9 + 1 + 12, 1>
mcall , <3, 1>, <9 + 12, LIST_HEIGHT + 1>
mcall , <3 + LIST_WIDTH + 12 + 1, 1>
mcall , <4, LIST_WIDTH>, <10 + 12, LIST_HEIGHT>, 0xFFFfff
mov esi, 1
mov edi, LIST_SIZE / 2 - 1
.draw_loop:
mov edx, 0
cmpne [last_x], esi, @f
cmpne [last_y], edi, @f
mov edx, 1
@@:
stdcall draw_item, esi, edi, edx
dec esi
cmpne esi, -1, @f
mov esi, 1
dec edi
@@:
cmpne edi, -1, .draw_loop
invoke scrollbar.draw, sb_apps
ret
endp
;----------------------
proc draw_item uses edx edi esi, _x, _y, _sel
;; get index
stdcall get_index_cur, [_x], [_y]
mov edi, eax
cmpge edi, [list.size], .break
;; background
mov ebx, [_x]
shl ebx, 7 + 16
add ebx, 4 shl 16 + LIST_WIDTH / 2
imul ecx, [_y], LINE_SIZE
shl ecx, 16
add ecx, (10 + 12) shl 16 + LINE_SIZE
mov edx, 0xFFFfff
cmpe [_sel], 0, @f
mov edx, 0x94AECE
@@:
mcall 13
;; shadows
push ecx
cmpe [_sel], 1, .after_shadows
mov edx, 0xCCCccc ;[skin.3d]
cmpne [_x], 0, @f
imul ecx, [_y], LINE_SIZE
shl ecx, 16
add ecx, (10 + 12) shl 16 + LINE_SIZE
mcall , <4, 1>
@@:
cmpne [_y], 0, @f
imul ebx, [_x], LIST_WIDTH / 2
shl ebx, 16
add ebx, 4 shl 16 + LIST_WIDTH / 2
mcall , , <10 + 12, 1>
@@:
.after_shadows:
pop ecx
;; icon
and ebx, 0xFFFF shl 16
shr ecx, 16
add ecx, ebx
mov edx, ecx
add edx, 6 shl 16 + (LINE_SIZE - 32) / 2
mov ebx, edi
shl ebx, 2
mov ebx, [ebx + list.icon]
imul ebx, 32 * 32 * 3
add ebx, [img.rgb]
cmpe [_sel], 0, .draw_icon
.selected:
mov eax, img.sel
mov ecx, 32 * 32
push edx
@@:
mov edx, [ebx]
and edx, 0xFFFFFF
cmpne edx, 0xFFFFFF, .not
mov edx, 0x94AECE
.not:
mov [eax], edx
add eax, 3
add ebx, 3
dec ecx
jnz @b
pop edx
mov ebx, img.sel
.draw_icon:
mcall 7, , <32, 32>
;; text
mov ebx, edx
add ebx, (32 + 6) shl 16 + 32 / 2 - 9 / 2
mov ecx, 0x000000 ; inactive item text
cmpe [_sel], 0, @f
mov ecx, 0x000000 ; active item text
@@:
add ecx, 0x80 shl 24
mov edx, edi
shl edx, 5
add edx, list
mcall 4
.break:
ret
endp
;----------------------
proc downcase_char uses ebx, _ch
mov ebx, [_ch]
cmpl bl, "A", @f
cmpg bl, "Z", @f
sub bl, "A" - "a"
jmp .ret
@@:
cmpl bl, "<22>", @f
cmpg bl, "<22>", @f
sub bl, "<22>" - "<22>"
@@:
.ret:
mov al, bl
ret
endp
;----------------------
proc get_index_cur uses ebx, _x, _y
mov eax, [_y]
shl eax, 1
add eax, [_x]
mov ebx, [sb_apps.position]
shl ebx, 1
add eax, ebx
ret
endp
;----------------------
proc get_index
stdcall get_index_cur, [last_x], [last_y]
ret
endp
;----------------------
proc set_index uses ebx,_index
mov eax, [_index]
mov ebx, [sb_apps.position]
shl ebx, 1
sub eax, ebx
mov ebx, eax
and ebx, 1b
mov [last_x], ebx
shr eax, 1
mov [last_y], eax
mov eax, 0
cmpl [last_y], 0xFFFF, @f
mov [last_y], 0
dec [sb_apps.position]
mov eax, 1
jmp .exit
@@:
cmpl [last_y], LIST_SIZE / 2, @f
mov ebx, [last_y]
sub ebx, LIST_SIZE / 2 - 1
mov [last_y], LIST_SIZE / 2 - 1
add [sb_apps.position], ebx
mov eax, 1
jmp .exit
@@:
.exit:
cmpge [sb_apps.position], 0, @f
mov [sb_apps.position], 0
@@:
ret
endp
;----------------------
proc section_cb, _file, _sec
;; CHECK IF EXISTS
invoke libini.get_str, assoc_ini, [_sec], assoc_ini.exec, buffer, 2048, undefined
mcall 70, is_file_exists
cmpe ebx, -1, .exit
mov ebx, [list.size]
shl ebx, 5
add ebx, list
stdcall string.compare, [_sec], assoc_ini.sec
cmpe eax, 1, @f
stdcall string.copy, [_sec], ebx
invoke libini.get_num, [_file], [_sec], assoc_ini.icon, 0
mov ecx, [list.size]
shl ecx, 2
mov [ecx + list.icon], eax
inc [list.size]
inc [sb_apps.max_area]
@@:
mov eax, 1
.exit:
ret
endp
;----------------------
dataend:
;===============================
skin system_colors
list rb 32 * 256
.icon rd 256
.size rd 1
img rd 1
.rgb rd 1
.size rd 1
.buf rb 40
.sel rb 32 * 32 * 3
win:
.x rd 1
.y rd 1
win.title rb 256
param_s rd 1
param_e rd 1
param_a rd 1
undefined rb 1
buffer rb 2048
buffer2 rb 2048
buffer3 rb 2048
buffer4 rb 4096
buffer5 rb 4096
buffer6 rb 2048
params rb 2048
_stack rb 2048
memory: