2 * Copyright (C) 2012-2013 Andy Spencer <andy753421@gmail.com>
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 #define _XOPEN_SOURCE_EXTENDED
29 int get_col(event_t **list, int n, event_t *event, int *ncols);
30 void move_event(int events, int days, int *line);
39 void week_init(WINDOW *_win)
41 win = _win; // lines cols y x
42 times = derwin(win, LINES-2, 5, 0, 0);
43 body = derwin(win, LINES-2, COLS-5, 0, 5);
48 void week_size(int rows, int cols)
51 wmvresize(times, hdr, 0, rows-hdr, 5);
52 wmvresize(body, hdr, 5, rows-hdr, cols-5);
63 /* Get start of week */
64 year_t year = SEL.year;
65 month_t month = SEL.month;
67 wday_t wday = day_of_week(year, month, day);
68 add_days(&year, &month, &day, -wday);
71 cal_load(year, month, day, 7);
74 int wstart = WEEKENDS ? SUN : MON;
75 int wend = WEEKENDS ? SAT : FRI;
76 int wdays = wend - wstart + 1;
77 float hstep = (float)(COLS-x)/wdays;
78 add_days(&year, &month, &day, wstart);
81 int l = ROUND((wday-wstart+0)*hstep);
82 int r = ROUND((wday-wstart+1)*hstep);
85 int rev = COMPACT ? A_REVERSE | A_BOLD : 0;
87 mvwprintw(win, 0, 0, "%-*s", COLS, month_to_str(SEL.month));
88 mvwprintw(win, 1, 0, "%-0*d", COLS, SEL.year);
90 mvwhline(win, 0, x+l, ' ', r-l-1);
91 mvwhline(win, 1, x+l, ' ', r-l-1);
93 for (int i = 0; i < wdays; i++) {
94 const char *str = hstep >= 10 ? day_to_string(wstart+i)
95 : day_to_str(wstart+i);
96 if (wstart+i == wday) wattrset(win, A_BOLD);
97 mvwprintw(win, 0, x+ROUND(i*hstep), "%s", str);
98 mvwprintw(win, 1, x+ROUND(i*hstep), "%02d/%02d", month+1, day+1);
99 if (wstart+i == wday) wattrset(win, rev);
100 add_days(&year, &month, &day, 1);
104 /* Print all day events */
107 add_days(&year, &month, &day, -wdays);
108 for (int i = 0; i < wdays; i++) {
110 while (event && before(&event->start, year, month, day, 24, 0)) {
111 if (!before(&event->end, year, month, day, 0, 1) &&
112 get_mins(&event->start, &event->end) > 23*60) {
113 int s = ROUND(i*hstep);
114 int w = ROUND((i+1)*hstep) - 1 - s;
115 event_line(win, event, y+n++, x+s, w, SHOW_ACTIVE);
121 add_days(&year,&month,&day,1);
123 if (allday && !COMPACT)
127 wshrink(times, y+allday-!COMPACT);
128 wshrink(body, y+allday-!COMPACT);
131 mvwprintw(times, !COMPACT, 0, "%02d:%02d", ((line/4)-1)%12+1, (line*15)%60);
132 for (int h = 0; h < 24; h++)
133 mvwprintw(times, !COMPACT+h*4-line, 0, "%02d:%02d", (h-1)%12+1, 0);
137 EVENT = find_event(&SEL);
140 add_days(&year, &month, &day, -wdays);
141 event_t *active[5] = {};
143 for (int i = 0; i < wdays; i++, add_days(&year,&month,&day,1))
144 for (int h = 0; h < 24; h++)
145 for (int m = 0; m < 60; m+=15)
146 while (event && before(&event->start,
147 year, month, day, h+(m+15)/60, (m+15)%60)) {
148 if (!before(&event->start, year, month, day, h, m) &&
149 get_mins(&event->start, &event->end) <= 23*60) {
150 int col = get_col(active, N_ELEMENTS(active), event, &ncols);
151 int y = h*4 + m/15 - line + !COMPACT;
152 int x = ROUND(i*hstep) + 1 + (col*3);
153 int h = (get_mins(&event->start, &event->end)-1)/15+1;
154 int w = ROUND((i+1)*hstep) - x - ((ncols-1)-col)*3;
155 if (event == EVENT) {
156 ee = event; ex = x; ey = y; ew = w; eh = h;
158 event_box(body, event, y, x, h, w);
163 /* Draw current event on top of other events */
165 event_box(body, ee, ey, ex, eh, ew);
167 /* Print header lines */
169 mvwhline(win, y-1, 0, ACS_HLINE, COLS);
170 if (!COMPACT && allday)
171 mvwhline(win, y-1+allday, 0, ACS_HLINE, COLS);
173 /* Print day lines */
174 for (int i = 0; i < wdays; i++)
175 mvwvline(body, !COMPACT, ROUND(i*hstep),
176 ACS_VLINE, LINES-y-2+COMPACT-allday);
177 mvwvline_set(body, 0, l, WACS_T_VLINE, LINES-y-1+COMPACT);
178 mvwvline_set(body, 0, r, WACS_T_VLINE, LINES-y-1+COMPACT);
179 for (int h = (line+3)/4; h < 24; h++) {
180 mvwadd_wch(body, h*4-line+!COMPACT, l, WACS_T_LTEE);
181 mvwadd_wch(body, h*4-line+!COMPACT, r, WACS_T_RTEE);
184 mvwhline(body, 0, l, ACS_BLOCK, r-l+1);
188 int week_run(int key, mmask_t btn, int row, int col)
190 int days = 0, events = 0, lines = 0, toggle = 0;
192 case 'h': days = -1; break;
193 case 'l': days = 1; break;
194 case 'i': days = -7; break;
195 case 'o': days = 7; break;
196 case 'k': events = -1; break;
197 case 'j': events = 1; break;
198 case '\031': lines = -1; break; // ctrl-y
199 case '\005': lines = 1; break; // ctrl-e
200 case 'w': toggle = 1; break;
201 case 'e': view_edit(EDIT_EVENT); return 1;
202 case '\012': view_edit(EDIT_EVENT); return 1; // enter
203 default: return 0; // not found
206 wday_t wday = day_of_week(SEL.year, SEL.month, SEL.day);
207 if (!WEEKENDS && ((wday == MON && days == -1) ||
208 (wday == FRI && days == 1)))
212 WEEKENDS = !WEEKENDS;
213 if (wday == SUN) days = 1;
214 if (wday == SAT) days = -1;
215 set_bool("view", NULL, "weekends", WEEKENDS);
219 line = CLAMP(line+lines, 0, 24*4);
221 move_event(events, days, &line);