return (get_time(end)-get_time(start))/60;
}
-int before(date_t *start, int year, int month, int day, int hour, int min)
+int compare(date_t *a, date_t *b)
{
- int rval = start->year < year ? 1 : start->year > year ? 0 :
- start->month < month ? 1 : start->month > month? 0 :
- start->day < day ? 1 : start->day > day ? 0 :
- start->hour < hour ? 1 : start->hour > hour ? 0 :
- start->min < min ? 1 : start->min > min ? 0 : 0;
+ int rval = a->year < b->year ? -1 : a->year > b->year ? 1 :
+ a->month < b->month ? -1 : a->month > b->month ? 1 :
+ a->day < b->day ? -1 : a->day > b->day ? 1 :
+ a->hour < b->hour ? -1 : a->hour > b->hour ? 1 :
+ a->min < b->min ? -1 : a->min > b->min ? 1 : 0;
return rval;
}
+int before(date_t *start, int year, int month, int day, int hour, int min)
+{
+ return compare(start, &(date_t){year, month, day, hour, min}) < 0;
+}
+
/* Debug functions */
const char *month_to_str(month_t month)
{
if (color) wattroff(win, COLOR_PAIR(color));
- if (l<h && event->name) mvwprintw(win, y+l++, x+1, "%.*s", w-2, event->name);
- if (l<h && event->loc) mvwprintw(win, y+l++, x+1, "@ %-*.*s", w-4, w-4, event->loc);
- if (l<h && event->desc) mvwprintw(win, y+l++, x+1, "%-*.*s", w-2, w-2, event->desc);
+ if (l<h && event->name) mvwprintw(win, y+l++, x+1, "%.*s", w-2, event->name);
+ if (l<h && event->loc) mvwprintw(win, y+l++, x+1, "@ %.*s", w-4, event->loc);
+ if (l<h && event->desc) mvwprintw(win, y+l++, x+1, "%.*s", w-2, event->desc);
}
void event_line(WINDOW *win, event_t *event, int y, int x, int w)
static WINDOW *times;
static WINDOW *body;
+/* Box packing helpers */
+static void clear_old(event_t **list, int n, event_t *cur)
+{
+ for (int i = 0; i < n; i++)
+ if (list[i] && compare(&list[i]->end, &cur->start) < 0)
+ list[i] = NULL;
+}
+
+static int next_free(event_t **list, int n)
+{
+ for (int i = 0; i < n; i++)
+ if (!list[i])
+ return i;
+ return n-1;
+}
+
+static int count_busy(event_t **list, int n)
+{
+ int sum = 0;
+ for (int i = 0; i < n; i++)
+ if (list[i])
+ sum++;
+ return sum;
+}
+
+static int get_ncols(event_t *event, int n)
+{
+ int ncols = 0;
+ event_t *preview[n];
+ memset(preview, 0, sizeof(preview));
+ for (event_t *cur = event; cur; cur = cur->next) {
+ int col = next_free(preview, n);
+ preview[col] = cur;
+ ncols = MAX(ncols, col+1);
+ if (cur->next)
+ clear_old(preview, n, cur->next);
+ if (count_busy(preview, n) == 0)
+ break;
+ }
+ return ncols;
+}
+
+static int get_col(event_t **list, int n, event_t *event, int *ncols)
+{
+ clear_old(list, n, event);
+
+ /* If there are current events, then recalculate
+ * ncols for the next series of events */
+ if (count_busy(list, n) == 0)
+ *ncols = get_ncols(event, n);
+
+ /* Find next open slot */
+ int col = next_free(list, n);
+ list[col] = event;
+ return col;
+}
+
/* Day init */
void day_init(WINDOW *_win)
{
/* Print events */
event_t *event = EVENTS;
+ event_t *active[10] = {};
+ int ncols = 0;
for (int h = 0; h < 24; h++)
for (int m = 0; m < 60; m+=15)
while (event && before(&event->start,
YEAR, MONTH, DAY, h+(m+15)/60, (m+15)%60)) {
if (!before(&event->start, YEAR, MONTH, DAY, h, m)) {
- int y = h*4 + m/15 - line;
- int x = 0;
- int h = (get_mins(&event->start, &event->end)-1)/15+1;
- int w = COLS-6;
- event_box(body, event, y, x, h, w);
+ int col = get_col(active, N_ELEMENTS(active), event, &ncols);
+ int left = ROUND((col+0.0)*(COLS-6)/ncols);
+ int right = ROUND((col+1.0)*(COLS-6)/ncols);
+ int row = h*4 + m/15 - line;
+ int height = (get_mins(&event->start, &event->end)-1)/15+1;
+ event_box(body, event, row, left, height, right-left);
}
event = event->next;
}