; Calendar for KolibriOS ; ; v1.5 - time redesign by Heavyiron ; v1.2 - v1.55 - new design 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-3 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 ; right border-outer mov edx,color2 add ebx,1 shl 16 sub ecx,1 shl 16 add cx,1 mcall ; right border-outer 2 mov edx,color1 add ebx,1 shl 16 sub ecx,1 shl 16 add cx,2 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 ; bottom border-outer 2 mov edx,color1 add ecx,1 shl 16 mcall add ebx,1 shl 16 sub ecx,1 shl 16 ; 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 get_current_date: mcall 29 mov [datestr],eax mov esi,datestr call str2int add eax,1900 mov [curYear],eax call str2int dec eax mov [curMonth],eax call str2int mov [curDay],eax test byte[esi],0 jnz .no2000 add [curYear],100 .no2000: ret check_midnight: mov ebx,[datestr] mcall 29 cmp eax,ebx je end_check_midnight call get_current_date call draw_days end_check_midnight: ret ;=============================================================== START: call get_current_date m2m [Year], [curYear] m2m [Month], [curMonth] m2m [day_sel], [curDay] call calculate 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 check_midnight 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 jg still cmp ah,179 jl 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+298,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 ; GetClientTop, fix for case when @patel in the top shr ebx, 16 mov ecx,ebx shl ecx,16 cmp ecx,0 jne panel_top ; panel bottom mcall 48,5 ;get screen size mov ecx, ebx sub ecx, WIN_H shl ecx, 16 panel_top: add ecx, WIN_H ; [y start] *65536 + [y size] 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_clock call draw_week mcall 8,193*65536+8,285*65536+10,72,COL_TOOLBAR_BG mov ebx,202*65536+8 inc edx ;73 mcall mov ebx,193*65536+8 mov ecx,315*65536+10 inc edx ;74 mcall mov ebx,202*65536+8 inc edx ;75 mcall mov ebx,215*65536+8 mov ecx,285*65536+10 inc edx ;76 mcall mov ebx,224*65536+8 inc edx ;77 mcall mov ebx,215*65536+8 mov ecx,315*65536+10 inc edx ;78 mcall mov ebx,224*65536+8 inc edx ;79 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,55 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+287, ,plus mcall ,185*65536+317, ,minus mcall , 35*65536+300,0x00CCCCCC,set_date_t,15 ;set date text 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,8 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 mov [dropped],0 ret draw_year: 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] mov eax,4 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] push ecx .dayloop: 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 sub edx,8 shl 16 + 8 mov ebx,edx mov bx,DATE_BUTTON_WIDTH-1 shrd ecx,edx,16 mov cx,DATE_BUTTON_HEIGHT-1 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 DrawRect COL_DATE_1,COL_DATE_2,COL_DATE_3,COL_DATE_4 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-1 mov cx,3 sub ebx,2 shl 16 sub ecx,1 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 ; second number mov ecx,remainder add edx,8 shl 16 mcall add edx,1 shl 16 mcall sub edx,10 shl 16 inc edi cmp edi,7 jne .nowrap xor edi,edi add dx,B_DAYS_SHIFT .nowrap: dec dword [esp] jnz .dayloop pop ecx 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 add eax,2 xchg eax,ebx mov ecx,100 xor edx,edx div cx sub ebx,eax shr eax,2 add ebx,eax 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: