; 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 draw_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+287,0x50000000,COL_WINDOW_BG shr ecx,8 add edx,22*65536 mcall shr ecx,8 add edx,22*65536 mcall ret draw_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 63,1,'Y' GetSkinHeight mov ecx, eax shl ecx, 16 add ecx, 43 mcall 13,B_WBAR_X, ,COL_TOOLBAR_BG ; draw toolbar background call draw_week mcall 8,193*65536+8,272*65536+10,72,COL_DATE_BUTTONS mov ebx,202*65536+8 inc edx ;73 mcall mov ebx,193*65536+8 mov ecx,298*65536+10 inc edx ;74 mcall mov ebx,202*65536+8 inc edx ;75 mcall mov ebx,215*65536+8 mov ecx,272*65536+10 inc edx ;76 mcall mov ebx,224*65536+8 inc edx ;77 mcall mov ebx,215*65536+8 mov ecx,298*65536+10 inc edx ;78 mcall mov ebx,224*65536+8 inc edx ;79 mcall mov ebx,237*65536+21 mov ecx,273*65536+35 inc edx ;80 or edx,0x40000000 mcall mov ebx,25*65536+110 mov ecx,285*65536+22 mov esi,COL_DATE_BUTTONS 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+287,0x80000000,sys_text mcall ,211*65536+287,,separator mcall ,233*65536+287 mcall ,185*65536+274, ,plus mcall ,185*65536+300, ,minus mcall , 35*65536+292,0x00000000,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 mcall 12,2 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: