kolibrios-fun/programs/system/calendar/trunk/calendar.asm
Kirill Lipatov (Leency) 337c9c65c2 Calendar: small redraw optimization
git-svn-id: svn://kolibrios.org@4735 a494cfbc-eb01-0410-851d-a64ba20cac60
2014-04-02 22:26:56 +00:00

864 lines
14 KiB
NASM

; Calendar for KolibriOS
;
; v1.5 - time redesign by Heavyiron
; v1.2 - v1.55 - new desighn and functionality by Leency
; v1.1 - add change time support by DedOK
; v1.0 - written in pure assembler by Ivushkin Andrey aka Willow
; also - diamond, spraid, fedesco
;
; Created: November 1, 2004
use32
org 0x0
db 'MENUET01'
dd 0x01
dd START
dd I_END
dd 0x1000
dd 0x1000
dd 0x0
dd 0x0
include '..\..\..\macros.inc'
include 'lang.inc'
include 'data.inc'
macro ShowFocus field,reg
{
local .nofocus, .exit
cmp [focus],field
jne .nofocus
if reg eq
mov ecx,COL_ACTIVE_TEXT
else
mov reg,COL_ACTIVE_TEXT
end if
jmp .exit
.nofocus:
if reg eq
mov ecx,COL_DROPDOWN_T
else
mov reg,COL_DROPDOWN_T
end if
.exit:
}
macro GetSkinHeight
{
mov eax,48
mov ebx,4
int 0x40
}
macro DrawRect color1,color2,color3,color4 ; pizdec... but optimized well
{
; top border-outer
push ebx
push ecx
mov eax,13
mov bx,DATE_BUTTON_WIDTH
mov edx,color1
mov cx,1
mcall
; left border-outer
mov bx,1
mov cx,DATE_BUTTON_HEIGHT
mcall
; top border-inner
mov edx,color2
add ebx,1 shl 16
add ecx,1 shl 16
mov bx,DATE_BUTTON_WIDTH-1
mov cx,1
; left border-inner
mcall
mov bx,1
mov cx,DATE_BUTTON_HEIGHT-2
mcall
; inner
mov edx,color3
add ebx,1 shl 16
add ecx,1 shl 16
mov bx,DATE_BUTTON_WIDTH-4
mov cx,DATE_BUTTON_HEIGHT-4
mcall
; bottom border-inner
mov edx,color4
add ebx,DATE_BUTTON_WIDTH shl 16
sub ebx,4 shl 16
mov bx,1
mov cx,DATE_BUTTON_HEIGHT-3
mcall
; rgiht border-outer
mov edx,color2
add ebx,1 shl 16
sub ecx,1 shl 16
add cx,1
mcall
; bottom border-outer
mov edx,color2
pop ecx
pop ebx
add ecx,DATE_BUTTON_HEIGHT shl 16
sub ecx,1 shl 16
add ebx,1 shl 16
mov cx,1
mcall
; left border-outer
mov edx,color4
add ebx,1 shl 16
sub ecx,1 shl 16
sub bx,2
mcall
}
str2int:
xor eax,eax
lodsb
mov ebx,eax
shr ebx,4
and eax,0xf
imul ebx,10
add al,bl
ret
START:
mcall 29
mov [datestr],eax
mov esi,datestr
call str2int
add eax,1900
mov [Year],eax
call str2int
dec eax
mov [Month],eax
call str2int
mov [day_sel],eax
test byte[esi],0
jnz .no2000
add [Year],100
mov eax,[Year]
mov [curYear], eax
mov eax,[Month]
mov [curMonth], eax
mov eax,[day_sel]
mov [curDay], eax
.no2000:
jmp upd
red:
call define_window
still:
mcall 23,50 ; wait here for event
.evt:
mov ebp,[focus]
cmp eax,1
je red
cmp eax,2
je key
cmp eax,3
je button
call draw_clock
jmp still
key:
mcall 2 ; get pressed key
cmp ah,9
jne no_tab
.tab:
cmp ebp,FOCUSABLE
JAE foc_cycle
inc [focus]
upd:
call calculate
jmp red
foc_cycle:
mov [focus],2
jmp upd
no_tab:
push eax
shr eax,8
mov ecx,12
mov edi,Fkeys
repne scasb
pop eax
jnz .noFkey
sub edi,Fkeys+1
mov [Month],edi
jmp upd
.noFkey:
cmp ebp,2
jne .nomonth
cmp ah,177
je noclose.drop
jmp still
.nomonth:
cmp ebp,3
je noy_up.year_evt
cmp ebp,4
jne still
mov ebx,[day_sel]
cmp ah,176 ; left arrow
jb still
cmp ah,179
ja still
shr eax,8
sub eax,176
movsx ecx,byte[day_bounds+eax*2]
movzx eax,byte[day_bounds+eax*2+1]
add ecx,ebx
test eax,eax
jz .chk0
cmp ecx,eax
ja still
.ok:
mov [day_sel],ecx
call draw_days
jmp still
.chk0:
cmp ecx,eax
jle still
jmp .ok
day_bounds db -1,0,7,0,-7,0,1,0 ; left,down,up,right
button:
mcall 17
movzx ebx,ah
cmp ah,200
jbe nodayselect
sub ah,200
mov byte[day_sel],ah
cmp ebp,5
jne .redraw
call draw_days
jmp still
.redraw:
mov [focus],4
jmp red
nodayselect:
cmp ah,100
jb no_list
sub ah,100
mov byte[Month],ah
mov [focus],2
jmp upd
no_list:
cmp ah,1
jne noclose
close:
mcall -1 ; clore programm
noclose:
cmp ah,72
je plus_he
cmp ah,73
je plus_hd
cmp ah,74
je minus_he
cmp ah,75
je minus_hd
cmp ah,76
je plus_me
cmp ah,77
je plus_md
cmp ah,78
je minus_me
cmp ah,79
je minus_md
cmp ah,80
je reset
cmp ah,81
je set_date
cmp ah,2 ; drop down list
jne no_dropdn
.drop:
mov [focus],2
cmp [dropped],al ; ==0
jne red
call draw_window
mov edx,1 shl 31+231
mov ecx,31
mov eax,8
.bremove:
mcall
dec edx
loop .bremove
call draw_dropdown
jmp still
no_dropdn:
cmp ah,3 ; year -1
jne noy_dn
year_dec:
dec [Year]
mov [focus],3
jmp upd
noy_dn:
cmp ah,4 ; year+1
jne noy_up
year_inc:
inc [Year]
mov [focus],3
jmp upd
noy_up:
cmp ah,5
jne noy_click
mov [focus],3
call draw_window
.still:
mcall 10
cmp eax,2
jne still.evt
mcall 2
.year_evt:
cmp ah,176
je year_dec
cmp ah,179
je year_inc
mov ebx,10
cmp ah,9
je key.tab
cmp ah,8 ; backspace
jne .nobsp
mov eax,[Year]
xor edx,edx
div ebx
.ch_year:
mov [Year],eax
call draw_year
jmp .still
.nobsp:
cmp ah,13 ; enter
je upd
cmp ah,182
jne .noclear ; del
xor eax,eax
jmp .ch_year
.noclear:
cmp ah,48
jb .still
cmp ah,57
ja .still
cmp [Year],1000
jae .still
shr eax,8
lea ecx,[eax-48]
mov eax,[Year]
imul eax,ebx
add eax,ecx
jmp .ch_year
noy_click:
cmp ah,10
jne START
xor [new_style],1
jmp upd
reset:
mcall 3
mov ecx,eax
shl ecx,16
shr ecx,16
mcall 22,0x00000000
jmp still
plus_hd:
mcall 3
mov ecx,eax
add ecx,1
mcall 22,0x00000000
jmp still
plus_he:
mcall 3
mov ecx,eax
add ecx,16
mcall 22,0x00000000
jmp still
minus_hd:
mcall 3
mov ecx,eax
sub ecx,1
mcall 22,0x00000000
jmp still
minus_he:
mcall 3
mov ecx,eax
sub ecx,16
mcall 22,0x00000000
jmp still
plus_md:
mcall 3
mov ecx,eax
add ecx,256
mcall 22,0x00000000
jmp still
plus_me:
mcall 3
mov ecx,eax
add ecx,4096
mcall 22,0x00000000
jmp still
minus_md:
mcall 3
mov ecx,eax
sub ecx,256
mcall 22,0x00000000
jmp still
minus_me:
mcall 3
mov ecx,eax
sub ecx,4096
mcall 22,0x00000000
jmp still
set_date:
mov eax,0x00000000
mov ebx,[day_sel]
call additem
shl eax,8
mov ebx,[Month]
add ebx,1
call additem
shl eax,8
mov ebx,[Year]
call additem
mov ecx,eax
mcall 22,1
jmp START
additem:
add eax,1
daa
sub ebx,1
cmp ebx,0
jne additem
ret
; *********************************************
; ******* DRAW WINDOW *******
; *********************************************
draw_clock:
mcall 3
mov ecx,eax
mcall 47,0x00020100, ,195*65536+301,0x50CCCCCC,COL_TOOLBAR_BG
shr ecx,8
add edx,22*65536
mcall
shr ecx,8
add edx,22*65536
mcall
ret
define_window:
mcall 12,1
mcall 48,5 ;get screen size
mov ecx, ebx
sub ecx, WIN_H
shl ecx, 16
add ecx, WIN_H
mov ebx, eax
sub eax, WIN_W
shl ebx, 16
add ebx, WIN_W
mcall 0,,,COL_WINDOW_BG, ,title ; define window
mcall 12,2
GetSkinHeight
mov ecx, eax
shl ecx, 16
add ecx, 43
mcall 13,B_WBAR_X, ,COL_TOOLBAR_BG ; draw toolbar background
mcall 13,B_WBAR_X,BT_WBAR_Y,COL_TOOLBAR_BG ; draw toolbar background
mcall 13,0*65536+B_WBAR_X,84*65536+199,0xE7E7E7
draw_window:
call draw_week
mcall 8,193*65536+8,287*65536+10,72,COL_TOOLBAR_BG
mov ebx,202*65536+8
inc edx ;73
mcall
mov ebx,193*65536+8
mov ecx,311*65536+10
inc edx ;74
mcall
mov ebx,202*65536+8
inc edx ;75
mcall
mov ebx,215*65536+8
mov ecx,287*65536+10
inc edx ;76
mcall
mov ebx,224*65536+8
inc edx ;77
mcall
mov ebx,215*65536+8
mov ecx,311*65536+10
inc edx ;78
mcall
mov ebx,224*65536+8
inc edx ;79
mcall
;mov ebx,237*65536+21
;mov ecx,281*65536+35
;inc edx ;80
;or edx,0x40CCFF44
;mcall
mov ebx,25*65536+110
mov ecx,293*65536+22
mov esi,COL_TOOLBAR_BG
mov edx,81
mcall
mov esi,COL_MONTH_YEAR_B ; new style
mov edx,10
or edx,1 shl 29+1 shl 30
mov ebx,B_NS_X
mov ecx,B_NS_Y
mcall
add edx,1-1 shl 29
mov ebx,B_TODAY_X+8*(today_end-today_msg)
mov ecx,B_TODAY_Y
mcall
mov ecx,B_Y
mov ebx,B_MONTH_X
mov edx,2
mcall
mov ebx,B_SPIN_X ; <
inc edx
mcall
add ebx,61 shl 16 ; >
inc edx
mcall
call draw_days
; draw text in window
mcall 4,157*65536+301,0x80CCCCCC,sys_text
mcall ,211*65536+301,,separator
mcall ,233*65536+301
mcall ,185*65536+289, ,plus
mcall ,185*65536+313, ,minus
mcall , 35*65536+300,0x00CCCCCC,set_date_t,15 ;set date text
mov ecx,0x10ddeeff
mov edx,n_style
mov esi,ns_end-n_style
mov ebx,B_NS
cmp [new_style],1
je .high
mov ecx,0xa0a0a0
jmp .int
.high:
mov ecx,COL_NEW_STYLE_T
.int:
mcall
mov ecx,COL_GO_TODAY_T
mov edx,today_msg
mov ebx,B_TODAY
mov esi,today_end-today_msg
mcall
mov ebx,B_SPIN
mov edx,spinner
mov esi,12
mov ecx,COL_DROPDOWN_T
mcall
mov edx,[Month]
movzx esi,byte[month_name]
imul edx,esi
add edx,month_name+1
mov ebx,B_MONTH
ShowFocus 2
mcall
call draw_year
call draw_clock
mov [dropped],0
ret
draw_year:
mcall 8,B_YEAR_X,B_Y,5,COL_MONTH_YEAR_B
ShowFocus 3,esi
mcall 47,0x40001,Year,B_YEAR
ret
draw_dropdown:
mov [dropped],1
push [Month]
pop [focus]
add [focus],100
mov ecx,12
mov edx,100
push dword month_name+1
push dword B_DROP
push dword B_Y+16 shl 16
.ddd_loop:
mov edi,edx
push ecx
mov esi,COL_DROPDOWN_BG
mcall 8,B_MONTH_X,[esp+4]
shr eax,1
mov ebx,[esp+8]
xchg edx,[esp+12]
movzx esi,byte[month_name]
ShowFocus edi
mcall
add edx,esi
xchg edx,[esp+12]
add dword[esp+8],16
add dword[esp+4],16 shl 16
inc edx
pop ecx
loop .ddd_loop
add esp,12
ret
draw_week:
mov eax,13
mov ebx,B_WBAR_X
mov ecx,B_WBAR_Y
mov edx,COL_WEEKDAY_BG
mcall
movzx esi,byte[week_days]
movzx edi,byte[week_days+1]
mov ebx,B_WEEK
mov ecx,7
mov edx,week_days+2
mov eax,4
.week:
push ecx
cmp ecx,edi
je .holiday
mov ecx,0x10000000
jmp .noholiday
.holiday:
mov ecx,0x10cc1010
.noholiday:
mcall
add edx,esi
add ebx,B_WX_SHIFT
pop ecx
loop .week
ret
draw_days:
call count_days
cmp ecx,[day_sel]
jae .ok
mov [day_sel],ecx
.ok:
mov [number],0
mov eax,47
mov edx,B_DAYS_Y
mov ebx,0x10001
mov edi,[firstday]
.dayloop:
push ecx
movzx edx,dx
mov esi,edi
shl esi,21
lea edx,[edx+esi+34 shl 16]
mov ecx,edi
add cl,[week_days+1]
cmp ecx,7
je .holiday
mov esi,0x10313138 ; COL_DATE_TEXT
jmp .noholiday
.holiday:
mov esi,0x10cc1010
.noholiday:
mov ecx,number
inc dword[ecx]
pusha
mov ebx,edx
mov bx,DATE_BUTTON_WIDTH-1
sub ebx,8 shl 16
shrd ecx,edx,16
mov cx,DATE_BUTTON_HEIGHT-1
sub ecx,12 shl 16
mov edx,[number]
cmp edx,[day_sel]
je .draw_sel
mov esi,COL_DATE_BUTTONS
jmp .draw_but
.draw_sel: ;draw selected button
add edx,1 shl 30
add edx,200+1 shl 29
mcall 8
cmp [focus],4
jne .not_active
DrawRect COL_DATE_ACTIVE_1,COL_DATE_ACTIVE_2,COL_DATE_ACTIVE_3,COL_DATE_ACTIVE_4
jmp .out
.not_active:
DrawRect COL_DATE_INACTIVE_1,COL_DATE_INACTIVE_2,COL_DATE_INACTIVE_3,COL_DATE_INACTIVE_4
jmp .out
.draw_but: ;draw non selected button
add edx,200+1 shl 29
mcall 8
mov eax,[Year]
cmp [curYear],eax
jne .out
mov eax,[Month]
cmp [curMonth],eax
jne .out
mov eax,[number]
cmp [curDay],eax
jne .out
mov edx,0xff0000
mov bx,DATE_BUTTON_WIDTH-2
mov cx,2
add ebx,1 shl 16
add ecx,27 shl 16
mcall 13
.out:
mov eax, [number]
xor edx, edx
mov ecx, 10
div ecx
mov [remainder], edx
mov [quotient], eax
popa
;first number
mov ecx,quotient
mcall
add edx,1 shl 16
mcall
sub edx,1 shl 16
;second number
mov ecx,remainder
add edx,9 shl 16
mcall
add edx,1 shl 16
mcall
sub edx,10 shl 16
pop ecx
inc edi
cmp edi,7
jne .nowrap
xor edi,edi
add dx,B_DAYS_SHIFT
.nowrap:
loop .eloop
jmp .ex
.eloop:
jmp .dayloop
.ex:
ret
count_days: ; ecx -days in month
call is_leap_year
mov ecx,[Month]
mov eax,1
movzx ecx,byte[day_count+ecx]
add ecx,28
cmp eax,[leap_year]
jne .noleap
cmp eax,[Month]
jne .noleap
inc ecx
.noleap:
mov [day_bounds+3],cl
mov [day_bounds+7],cl
ret
is_leap_year:
mov [leap_year],0
mov eax,[Year]
mov bl,100
div bl ; ah=Year mod 100, al=Year%100
test ah,ah
jz .century
shr ax,8 ; ax - last 2 digits
.century:
test al,11b
jnz .noleap
inc [leap_year]
.noleap:
ret
calculate:
mov ebx,[Year]
mov eax,[Month]
sub eax,2
jge .nojf
dec ebx
add eax,12
.nojf:
add eax,4
xor edx,edx
mov ecx,153
imul cx
mov ecx,5
div cx
inc eax
mov ecx,365
imul ecx,ebx
add eax,ecx
mov ecx,ebx
shr ecx,2
add eax,ecx
dec eax
cmp [new_style],0
je .nonew
add eax,2
xchg eax,ebx
mov ecx,100
xor edx,edx
div cx
sub ebx,eax
shr eax,2
add ebx,eax
.nonew:
add ebx,5
mov eax,ebx
xor edx,edx
movzx ebx,byte[week_days+1]
sub eax,ebx
inc eax
mov ebx,7
div bx
mov [firstday],edx
ret
I_END: