ESC 27
# define CALENDAR_WIDTH 31
# define CALENDAR_HEIGHT 17
# define RED 1
# define GREEN 2
# define BLUE 3
# define YELLOW 4
# define WHITE 5
# define RED_COLOR (COLOR PAIR(RED) | A BOLD)
# define GREEN_COLOR (COLOR PAIR(GREEN) | A BOLD)
# define BLUE_COLOR (COLOR PAIR(BLUE) | A BOLD)
# define YELLOW_COLOR (COLOR PAIR(YELLOW) | A BOLD)
# define WHITE_COLOR (COLOR PAIR(WHITE) | A BOLD)
# define GRAY_COLOR (COLOR PAIR(WHITE) | A NORMAL)
typedef struct _date
{
int day;
int month;
int year;
}date;
void show_window(WINDOW* win);/*显示主界面*/
void show_calendar(WINDOW* calr);/*显示日历*/
void input_custom(WINDOW* win);/*用户输入年月*/
int is_leap(int year);/*判断闰年*/
int get_weekday(date d);/*取得日期的星期*/
date get_date before(date d, int n);/*取得日期d的前n天*/
date get_date after(date d, int n);/*取得日期d的后n天*/
int get_days(int year, int month);/*取得某年某月的天数*/
int day table[2][12] ={{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};
char* WEEK[] ={" Sun", " Mon", " Tue", " Wen", " Thu", " Fri", " Sat"};
char* MONTH[] ={" January", " February", " March", " April", " May", " June", " July","ugust", " September", " October", " Nevember", " December"};
char* help[] =
{
" Press Up Down key to change year. ",
" Press Left Right key to change month. ",
" Press f key to show a custom calendar. ",
" Press SPACE key to back to today. ",
" Press ESC key to exit. ",
0
};
struct tm* today;
date current;
int main()
{WINDOW* win = NULL;
WINDOW* calr = NULL;
int ch = ' ';long now;
/*取得当前日期*/
time(& now);
today = localtime(& now);
initscr();/*初始化curses库*/
start color();/*允许使用颜色*/
cbreak();/*禁止行模式*/
noecho();/*禁止显示用户输入的字符*/
/*初始化颜色*/
init pair(RED, COLOR RED, COLOR BLACK);
init pair(GREEN, COLOR GREEN, COLOR BLACK);
init pair(BLUE, COLOR BLUE, COLOR BLACK);
init pair(YELLOW, COLOR YELLOW, COLOR BLACK);
init pair(WHITE, COLOR WHITE, COLOR BLACK);
/*创建主窗口*/
win = newwin(LINES, COLS, 0, 0);
/*创建一个自窗口显示日历*/
calr = derwin(win, CALENDAR HEIGHT, CALENDAR WIDTH,2,2);
keypad(win, TRUE);/*允许使用控制键*/
while(ch != KEY ESC)
{
switch(ch)
{case ' ':/*输入空格*/
current. day =1;
current. month = today-> tm mon;
current. year =1900+ today-> tm year;
break;
case 'f':/*输入“f”*/
input custom(win);
break;
case KEY UP:/*输入向上键*/
current. year--;
break;
case KEY DOWN:/*输入向下键*/
current. year++;
break;
case KEY LEFT:/*输入向左键*/
current. month--;
if(current. month <0)
{
current. month =11;
current. year--;
}
break;
case KEY RIGHT:/*输入向右键*/
current. month++;
if(current. month >11)
{
current. month =0;
current. year++;
}
break;
}show window(win);/*显示主窗口*/
show calendar(calr);/*显示日历窗口*/
wrefresh(win);
ch = wgetch(win);
}
delwin(calr);/*释放日历窗口*/
delwin(win);/*释放主窗口*/
endwin();/*结束使用curses库*/
return 0;
}
void show window(WINDOW* win)
{
int row =1;
int i =0;
/*显示标题*/
wattron(win, BLUE COLOR I A UNDERLINE);
mvwprintw(win, row++, CALENDAR WIDTH +3, "MY CALENDAR");
wattroff(win, BLUE COLOR | A UNDERLINE);
/*显示帮助信息*/
row =4;
for(i =0; help[i]; i++)
{
mvwprintw(win, row++, CALENDAR WIDTH +3, help[i]);
row++;
}
/*显示今天的日期*/
wattron(win, GREEN COLOR | A UNDERLINE);
mvwprintw(win, LINES -4, 2, " Today is %d-%d-%d\n",1900+ today-> tm year, today-> tm mon +1, today-> tm mday);
wattroff(win, GREEN COLOR | A UNDERLINE);
whline(win, '-', COLS);
/*显示提示信息*/
wattron(win, BLUE COLOR);
mvwprintw(win, LINES -2, 1, "> Press function key:");
wattroff(win, BLUE COLOR);
/*设置边框*/
wborder(win, ' l ', ' l ', '=', '=', '+', '+', '+', '+') ;
}
void show calendar(WINDOW* calr)
{
int i =0;
int x =1;
int y =1;
int wbegin = 0;
date d;
/*显示年、月信息*/
wattron(calr, YELLOW COLOR);
mvwprintw(calr, 1, 2, "%s %d\n ", MONTH[current. month],urrent. year);
wattroff(calr, YELLOW COLOR);
whline(calr, '-', CALENDAR WIDTH);
/*显示星期*/
y = 3;
x = 1;
for(i = 0; i < 7; ++i)
{
if(i == 0 || i == 6)
{
wattron(calr, RED COLOR);
mvwprintw(calr, y, x, "%4s", WEEK[i]);
wattroff(calr, RED COLOR);
}
else
{
wattron(calr, BLUE COLOR);
mvwprintw(calr, y, x, "%4s", WEEK[i]);
wattroff(calr, BLUE COLOR);
}
x += 4;
}
/*显示日历*/
wbegin = get weekday(current);
d = get date before(current, wbegin);
for(i = 0; i < 42; ++i)
{
y = 5+2* ((int)(i /7));
x = 1 + (i %7) *4;
if (d. day == today-> tm mday
&& d. month == today-> tm mon
&& d. year == (1900 + today-> tm year))
{
wateron(calr, GREEN COLOR);
mvwprintw(calr, y, x, "%4d", d. day);
wattroff(calr, GREEN COLOR);
}
else
if
(d. month != current. month)
{
wattron(calr, GRAY COLOR);
mvwprintw(calr, y, x, "%4d", d. day);
wattroff(calr, GRAY COLOR);
}
else
if
((i %7) ==0 11(i %7) ==6)
{
wattron(calr, RED COLOR);
mvwprintw(calr, y, x, "%4d", d. day);
wattroff(calr, RED COLOR);
}
else
{
wattron(calr, WHITE COLOR);
mvwprintw(calr, y, x, "%4d", d. day);
wattroff(calr, WHITE COLOR);
}
d = get date after(d, 1);
}
/*设置边框*/
wborder(calr, ' l', ' l ', '-', '-', '+', '+', '+', '+');
}
void input custom(WINDOW* win)
{
int year =0;
int month =0;
wattron(win, GREEN COLOR);
mvwprintw(win, LINES - 2, 1, "> Input year/ month(example:2000/1):");
wattroff(win, GREEN COLOR);
nocbreak();
echo();
if
(wscanw(win, "%d/%d", & year, & month) ==2&& month >0 && month<13)
{
current. year = year;
current. month = month -1;
}
else
{
wattron(win, RED COLOR);
mvwprintw(win, LINES - 2, 1, "> Input error:");
wrefresh(win);
sleep(2);
wattroff(win,·RED COLOR);
}
mvwprintw(win, LINES -2, 1, "");
whline(win, ' ', COLS-2);
cbreak();
noecho();
}
int is leap(int year)
{
if (((year%4==0) && (year%100 !=0)) || (year%400==0))
{
return 1;
}
return 0;
}
int get weekday(date d)
{
int w=0;
int y = d. year %100;
int c = d. year / 100;
int m = d. month >1? (d. month +1) : (d. month +13);
w = y + y /4+ c /4-2* c +26* (m +1) /10+ d. day -1;
while (w <0)
{
w +=70;
}
return (w % 7);
}
date get date before(date d, int n)
{
date bd = d;
while(n > 0)
{
n--;
bd. day--;
if(bd. day <1)
{
bd. month--;
if(bd. month < 0)
{
bd. year--;
bd. month =11;
}
bd. day = get days(bd. year, bd. month);
}
}
return bd;
}
date get date after(date d, int n)
{
date ad = d;
int max = get_days(ad.year, ad.month);
while(n >0)
{
n--;
ad. day++;
if (ad.day > max)
ad. month++;
if (ad. month >11)
{
ad. year++;
ad. month =0;
}
ad. day =1;
max = get dayslad. year, ad. month);
return ad;
}
int get_days(int year, int month)
{
return day_table[is_leap(year)][month];
}