]> Pileus Git - lackey/commitdiff
Add utils, tests, and month view
authorAndy Spencer <andy753421@gmail.com>
Thu, 4 Oct 2012 08:01:00 +0000 (08:01 +0000)
committerAndy Spencer <andy753421@gmail.com>
Thu, 4 Oct 2012 08:51:47 +0000 (08:51 +0000)
.gitignore
screen.txt
src/main.c
src/makefile
src/screen.c
src/screen.h
src/test.c [new file with mode: 0644]
src/util.c [new file with mode: 0644]
src/util.h [new file with mode: 0644]
src/view/month.c

index a88d9f9aa5efac4d4a7ff5c7f91bdf84923ca545..a85852fab334e26e21da73d6dac1e4966757b4af 100644 (file)
@@ -4,4 +4,5 @@
 *~
 .vimrc
 acal
+test
 tags
index a5107735d04d46aa7e53130f67a543917ae4c90f..293f2d00fdf85a7c30abe712415519cd3a87280a 100644 (file)
@@ -68,25 +68,25 @@ Month view
    │ Day  Week  Month  Year │ Todo  Notes │ Settings  Help               │
    │ ─────────────────────────────────────────────────────────────────── │
    │                          September  2012                            │
-   │ Mon      Tue       Wed       Thu       Fri       Sat       Sun      │
+   │ Sun      Mon       Tue       Wed       Thu       Fri       Sat      │
    │ ─────────────────────────────────────────────────────────────────── │
-   │                                                           │ 1       │
+   │                                                           │       │
    │                                                           │         │
    │                                                           │         │
    │ ────────┬─────────┬─────────┬─────────┬─────────┬─────────┼──────── │
-   │ 2       │ 3       │ 4       │ 5       │ 6       │ 7       │ 8       │
+   │ 2       │3        │4        │5        │6        │7        │8        │
    │         │         │         │         │         │         │         │
    │         │         │         │         │         │         │         │
    │ ────────┼─────────┼─────────┼─────────┼─────────┼─────────┼──────── │
-   │ 9       │ 10      │ 11      │ 12      │ 13      │ 14      │ 15      │
+   │ 9       │10       │11       │12       │13       │14       │15       │
    │         │         │         │         │         │         │         │
    │         │         │         │         │         │         │         │
    │ ────────┼─────────┼─────────┼─────────┼─────────┼─────────┼──────── │
-   │ 16      │ 17      │ 18      │ 19      │ 20      │ 21      │ 22      │
+   │ 16      │17       │18       │19       │20       │21       │22       │
    │         │         │         │         │         │         │         │
    │         │         │         │         │         │         │         │
    │ ────────┼─────────┼─────────┼─────────┼─────────┼─────────┼──────── │
-   │ 23      │ 24      │ 25      │ 26      │ 27      │ 28      │ 29      │
+   │ 23      │24       │25       │26       │27       │28       │29       │
    │         │         │         │         │         │         │         │
    │         │         │         │         │         │         │         │
    │ ────────┼─────────┴─────────┴─────────┴─────────┴─────────┴──────── │
index a5d89c9bc44a5864d20d620ba21594fd4468ef02..4161b031deb31d77ed554a8d64f9bdb1e959a654 100644 (file)
@@ -22,6 +22,7 @@ static void on_sigwinch(int signum)
 {
        endwin();
        refresh();
+       screen_resize();
        screen_draw();
 }
 
index 20ac4a8b09046f74c81140ac68d33be3e02c6e2a..afa11157ac7f83ea327ec01277ffa7576a0cbbf9 100644 (file)
@@ -1,29 +1,37 @@
 # Settings
 CC       = gcc
 CFLAGS   = -Wall --std=c99
-CPPFLAGS =
+CPPFLAGS = -I.
 LDFLAGS  = -lncursesw
 PROG     = acal
+TEST     = test
 
 # Views
-SOURCES  = main screen
+SOURCES  = main screen util
+TESTS    = test util
 VIEWS    = day week month year todo notes settings help
 
-default: test
+default: run-$(PROG)
 
 # Targets
-all: $(PROG)
+all: $(PROG) $(TEST)
 
-test: $(PROG)
+run-$(PROG): $(PROG)
        @urxvt -e ./$<
        @cat acal.log
 
+run-$(TEST): $(TEST)
+       ./$<
+
 clean:
-       rm -f *.o view/*.o $(PROG)
+       rm -f *.o view/*.o $(PROG) $(TEST)
 
 # Rules
 $(PROG): $(SOURCES:%=%.o) $(VIEWS:%=view/%.o)
        $(CC) $(CLFAGS) -o $@ $+ $(LDFLAGS)
 
+$(TEST): $(TESTS:%=%.o) $(VIEWS:%=view/%.o)
+       $(CC) $(CLFAGS) -o $@ $+ $(LDFLAGS)
+
 %.o: %.c $(SOURCES:%=%.h) makefile
        $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
index f31a738b08c44a6b40e3c72ff0fe76949605060d..b02d068ab71c28ce1356c3c0d41cf184b18fd469 100644 (file)
@@ -27,7 +27,7 @@ view_t views[] = {
        { "Help",     help_init,     help_draw,     help_run,     {KEY_F(8), '8', 'h', '?'} },
 };
 
-int active = 0;
+int active = 2;
 
 /* Local functions */
 void draw_header(void)
@@ -37,7 +37,7 @@ void draw_header(void)
        for (int i = 0; i < N_ELEMENTS(views); i++) {
                if (i == active)
                        attron(A_BOLD);
-               printw(" %s", views[i].name);
+               printw("%s ", views[i].name);
                if (i == active)
                        attroff(A_BOLD);
        }
@@ -57,11 +57,21 @@ void screen_init(void)
        }
 }
 
+/* Screen draw */
+void screen_resize(void)
+{
+       for (int i = 0; i < N_ELEMENTS(views); i++)
+               if (views[i].init)
+                       wresize(views[i].win, LINES-2, COLS);
+}
+
 /* Screen draw */
 void screen_draw(void)
 {
        draw_header();
+       werase(views[active].win);
        views[active].draw();
+       wrefresh(views[active].win);
 }
 
 /* Screen set */
index 7f6aa9d5b57db2990cb202451afbd4dd579083ea..116840a41d6a419e920f092dfb3b3c1dc01c86c1 100644 (file)
@@ -1,5 +1,6 @@
 /* Screen functions */
 void screen_init(void);
+void screen_resize(void);
 void screen_draw(void);
 int  screen_run(int key, mmask_t btn, int row, int col);
 
diff --git a/src/test.c b/src/test.c
new file mode 100644 (file)
index 0000000..0619226
--- /dev/null
@@ -0,0 +1,7 @@
+#include "util.h"
+
+int main(int argc, char **argv)
+{
+       test_time();
+       return 0;
+}
diff --git a/src/util.c b/src/util.c
new file mode 100644 (file)
index 0000000..55cd265
--- /dev/null
@@ -0,0 +1,105 @@
+/* Time Keeping Bugs Abound! */
+
+#include <stdio.h>
+
+#include "util.h"
+
+/* Helper functions */
+static int is_leap_year(year_t year)
+{
+       return (year % 400 == 0) ? 1 :
+              (year % 100 == 0) ? 0 :
+              (year % 4   == 0) ? 1 : 0;
+}
+
+static wday_t day_of_week(year_t year, month_t month, day_t day)
+{
+       static int tmp[] = {0, 3, 2, 5, 0, 3,
+                           5, 1, 4, 6, 2, 4};
+       if (month < 3)
+               year--;
+       int start = year + year / 4
+                        - year / 100
+                        + year / 400
+                        + tmp[month];
+       return (start + day) % 7;
+}
+
+/* Time functions */
+int days_in_year(year_t year)
+{
+       return 365 + is_leap_year(year);
+}
+
+int days_in_month(year_t year, month_t month)
+{
+       static int mdays[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+       int days = mdays[month];
+       if (month == FEB)
+               days += is_leap_year(year);
+       return days;
+}
+
+int weeks_in_month(year_t year, month_t month)
+{
+       int start = start_of_month(year, month);
+       int days  = days_in_month(year, month);
+       return ((start + days)-1) / 7 + 1;
+}
+
+wday_t start_of_month(year_t year, month_t month)
+{
+       return day_of_week(year, month, 1);
+}
+
+/* Debug functions */
+const char *month_to_str(month_t month)
+{
+       static const char *map[] =
+               { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+                 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", };
+       return map[month];
+}
+const char *month_to_string(month_t month)
+{
+       static const char *map[] =
+               { "January",   "February", "March",    "April",
+                 "May",       "June",     "July",     "August",
+                 "September", "October",  "November", "December" };
+       return map[month];
+}
+
+const char *day_to_st(wday_t day)
+{
+       static const char *map[] =
+               { "Su","Mo", "Tu", "We", "Th", "Fr", "Sa" };
+       return map[day];
+}
+const char *day_to_str(wday_t day)
+{
+       static const char *map[] =
+               { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
+       return map[day];
+}
+const char *day_to_string(wday_t day)
+{
+       static const char *map[] =
+               { "Sunday",   "Monday", "Tuesday", "Wednesday",
+                 "Thursday", "Friday", "Saturday" };
+       return map[day];
+}
+
+/* Test functions */
+void test_time(void)
+{
+       printf("Year Month     Start Weeks Days\n");
+       for (int y = 2012; y <= 2012; y++)
+       for (int m = JAN;  m <= DEC;  m++) {
+               printf("%-5d",  y);
+               printf("%-10s", month_to_string(m));
+               printf("%-6s",  day_to_str(start_of_month(y,m)));
+               printf("%-6d",  weeks_in_month(y,m));
+               printf("%-2d",  days_in_month(y,m));
+               printf("\n");
+       }
+}
diff --git a/src/util.h b/src/util.h
new file mode 100644 (file)
index 0000000..57e7afc
--- /dev/null
@@ -0,0 +1,44 @@
+/* Types */
+typedef int year_t;
+typedef int day_t;
+
+typedef enum {
+       JAN =  0,
+       FEB =  1,
+       MAR =  2,
+       APR =  3,
+       MAY =  4,
+       JUN =  5,
+       JUL =  6,
+       AUG =  7,
+       SEP =  8,
+       OCT =  9,
+       NOV = 10,
+       DEC = 11,
+} month_t;
+
+typedef enum {
+       SUN = 0,
+       MON = 1,
+       TUE = 2,
+       WED = 3,
+       THU = 4,
+       FRI = 5,
+       SAT = 6,
+} wday_t;
+
+/* Time functions */
+int days_in_year(year_t year);
+int days_in_month(year_t year, month_t month);
+int weeks_in_month(year_t year, month_t month);
+wday_t start_of_month(year_t year, month_t month);
+
+/* String functions */
+const char *month_to_str(month_t month);
+const char *month_to_string(month_t month);
+const char *day_to_st(wday_t day);
+const char *day_to_str(wday_t day);
+const char *day_to_string(wday_t day);
+
+/* Tests */
+void test_time(void);
index 85ef13e2c67962133cb49502bf052ce863f89abd..d5bb538bf95e0607e8927cf7521e27895fbb90dc 100644 (file)
@@ -1,8 +1,19 @@
+#include <string.h>
 #include <ncurses.h>
 
+#include "util.h"
+
+/* Macros */
+#define ROUND(x) ((int)((x)+0.5))
+
 /* Static data */
 static WINDOW *win;
 
+/* Test data */
+const static int YEAR  = 2012;
+const static int MONTH = SEP;
+const static int DAY   = 29;
+
 /* Month init */
 void month_init(WINDOW *_win)
 {
@@ -12,8 +23,41 @@ void month_init(WINDOW *_win)
 /* Month draw */
 void month_draw(void)
 {
-       mvwprintw(win, 0, 1, "%s\n", "month");
-       wrefresh(win);
+       const char *name  = month_to_string(MONTH);
+       const int   start = start_of_month(YEAR, MONTH);
+       const int   days  = days_in_month(YEAR, MONTH);
+       const int   weeks = weeks_in_month(YEAR, MONTH);
+       const float midpt = (float)COLS/2.0 - (strlen(name) + 1 + 4)/2.0;
+       const float hstep = (float)COLS/7.0;
+       const float vstep = (float)(LINES-4)/weeks;
+
+       /* Print Header */
+       mvwprintw(win, 0, midpt, "%s %d", name, YEAR);
+       for (int d = 0; d < 7; d++)
+               mvwprintw(win, 1, ROUND(d*hstep), "%s", day_to_str(d+SUN));
+       mvwhline(win, 2, 0, ACS_HLINE, COLS);
+
+       /* Print days */
+       for (int d = 0; d < days; d++) {
+               int row = (start + d) / 7;
+               int col = (start + d) % 7;
+               mvwprintw(win, ROUND(3+row*vstep), ROUND(col*hstep), "%d", d+1);
+       }
+
+       /* Print lines */
+       for (int w = 1; w < weeks; w++)
+               mvwhline(win, ROUND(2+w*vstep), 0, ACS_HLINE, COLS);
+       for (int d = 1; d < 7; d++) {
+               int top = d >=  start         ? 0     : 1;
+               int bot = d <= (start+days)%7 ? weeks : weeks-1;
+               mvwvline(win, ROUND(3+top*vstep), ROUND(d*hstep-1),
+                               ACS_VLINE, (bot-top)*vstep);
+               for (int w = 1; w < weeks; w++) {
+                       int chr = w == top ? ACS_TTEE :
+                                 w == bot ? ACS_BTEE : ACS_PLUS;
+                       mvwaddch(win, ROUND(2+w*vstep), ROUND(d*hstep-1), chr);
+               }
+       }
 }
 
 /* Month run */