commit 2f8431ccf186589e55afbe8847b2788f895ec829
parent f8c699210c8b66a0ac1e335a40391b57d20cb8d6
Author: William Casarin <jb55@jb55.com>
Date: Mon, 1 Oct 2018 12:59:49 -0700
timeblock selection hilightning
Diffstat:
M | viscal.c | | | 99 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------ |
1 file changed, 77 insertions(+), 22 deletions(-)
diff --git a/viscal.c b/viscal.c
@@ -80,18 +80,20 @@ struct cal {
int nevents;
char chord;
int repeat;
+
int selected_event_ind;
enum cal_flags flags;
// TODO: make multiple target selection
struct event *target;
- int minute_round;
+ int timeblock_size;
int refresh_events;
int x, y, mx, my;
int gutter_height;
double zoom, zoom_at;
icaltimezone *tz;
+ time_t current; // current highlighted position
time_t today, start_at, scroll;
int height, width;
@@ -130,11 +132,12 @@ calendar_create(struct cal *cal) {
cal->selected_event_ind = 0;
cal->chord = 0;
cal->gutter_height = 40;
- cal->minute_round = 30;
+ cal->timeblock_size = 30;
cal->ncalendars = 0;
cal->nevents = 0;
cal->start_at = nowh - today - 4*60*60;
cal->scroll = 0;
+ cal->current = nowh;
cal->repeat = 1;
cal->today = today;
cal->x = g_lmargin;
@@ -358,7 +361,7 @@ calendar_load_ical(struct cal *cal, char *path) {
/* event_set_start(struct event *ev, time_t time, const icaltimezone *zone) { */
/* if (zone == NULL) */
/* zone = g_timezone; */
-/* icaltimetype ictime = icaltime_from_timet_with_zone(time, 1, zone); */
+/* icaltimetype ictime = icaltime_from_timet_with_zone_with_zone(time, 1, zone); */
/* icalcomponent_set_dtstart(ev->vevent, ictime); */
/* } */
@@ -366,7 +369,7 @@ calendar_load_ical(struct cal *cal, char *path) {
/* event_set_end(struct event *ev, time_t time, const icaltimezone *zone) { */
/* if (zone == NULL) */
/* zone = g_timezone; */
-/* icaltimetype ictime = icaltime_from_timet_with_zone(time, 1, zone); */
+/* icaltimetype ictime = icaltime_from_timet_with_zone_with_zone(time, 1, zone); */
/* icalcomponent_set_dtend(ev->vevent, ictime); */
/* } */
@@ -389,12 +392,12 @@ calendar_drop(struct cal *cal, double mx, double my) {
// TODO: convert timezone on drag?
icaltimetype startt =
- icaltime_from_timet(ev->drag_time, 0);
+ icaltime_from_timet_with_zone(ev->drag_time, 0, NULL);
icalcomponent_set_dtstart(ev->vevent, startt);
icaltimetype endt =
- icaltime_from_timet(ev->drag_time + len, 0);
+ icaltime_from_timet_with_zone(ev->drag_time + len, 0, NULL);
icalcomponent_set_dtend(ev->vevent, endt);
}
@@ -463,8 +466,8 @@ static char *format_locale_timet(char *buffer, int bsize, time_t time) {
static icalcomponent *
create_event(struct cal *cal, time_t start, time_t end, icalcomponent *ical) {
icalcomponent *vevent;
- icaltimetype dtstart = icaltime_from_timet(start, 0);
- icaltimetype dtend = icaltime_from_timet(end, 0);
+ icaltimetype dtstart = icaltime_from_timet_with_zone(start, 0, NULL);
+ icaltimetype dtend = icaltime_from_timet_with_zone(end, 0, NULL);
vevent = icalcomponent_new(ICAL_VEVENT_COMPONENT);
@@ -486,17 +489,20 @@ calendar_def_cal(struct cal *cal) {
return NULL;
}
-static time_t
-closest_timeblock(struct cal *cal, int y) {
- time_t st;
+static time_t closest_timeblock_for_timet(time_t st, int timeblock_size) {
struct tm lt;
- st = calendar_loc_to_time(cal, y);
lt = *localtime(&st);
- lt.tm_min = round(lt.tm_min / cal->minute_round) * cal->minute_round;
+ lt.tm_min = round(lt.tm_min / timeblock_size) * timeblock_size;
lt.tm_sec = 0; // removes jitter
return mktime(<);
}
+static time_t
+closest_timeblock(struct cal *cal, int y) {
+ time_t st = calendar_loc_to_time(cal, y);
+ return closest_timeblock_for_timet(st, cal->timeblock_size);
+}
+
static void
@@ -510,7 +516,7 @@ calendar_view_clicked(struct cal *cal, int mx, int my) {
format_locale_timet(buf, length(buf), closest);
printf("(%d,%d) clicked @%s\n", mx, my, buf);
- create_event(cal, closest, closest + cal->minute_round * 60,
+ create_event(cal, closest, closest + cal->timeblock_size * 60,
calendar_def_cal(cal));
// TODO: configurable default duration
/* icalcomponent_set_duration(vevent, duration); */
@@ -577,6 +583,16 @@ static void select_up(struct cal *cal, int repeat)
cal->selected_event_ind = relative_selection(cal, -repeat);
}
+static void move_up(struct cal *cal, int repeat)
+{
+ cal->current -= cal->timeblock_size * 60;
+}
+
+static void move_down(struct cal *cal, int repeat)
+{
+ cal->current += cal->timeblock_size * 60;
+}
+
static int query_span(struct cal *cal, int index_hint, time_t start, time_t end,
time_t min_start, time_t max_end)
{
@@ -619,8 +635,8 @@ static void push_down(struct cal *cal, int from, int ind, time_t push_to)
new_et = et + (push_to - st);
- dtstart = icaltime_from_timet(push_to, 0);
- dtend = icaltime_from_timet(new_et, 0);
+ dtstart = icaltime_from_timet_with_zone(push_to, 0, NULL);
+ dtend = icaltime_from_timet_with_zone(new_et, 0, NULL);
// TODO: undo
icalcomponent_set_dtstart(ev->vevent, dtstart);
@@ -647,7 +663,7 @@ static void open_below(struct cal *cal)
vevent_span_timet(ev->vevent, &st, &et);
- push_to = et + cal->minute_round * 60;
+ push_to = et + cal->timeblock_size * 60;
// push down all nearby events
// TODO: filter on visible calendars
@@ -699,13 +715,30 @@ static gboolean on_keypress (GtkWidget *widget, GdkEvent *event, gpointer user_
cal->repeat = 1;
break;
+ case 'g':
+ if (cal->chord == 0)
+ cal->chord = 'g';
+ break;
+
case 'j':
- select_down(cal, cal->repeat);
+ if (cal->chord == 0) {
+ move_down(cal, cal->repeat);
+ }
+ else if (cal->chord == 'g') {
+ select_down(cal, cal->repeat);
+ cal->chord = 0;
+ }
cal->repeat = 1;
break;
case 'k':
- select_up(cal, cal->repeat);
+ if (cal->chord == 0) {
+ move_up(cal, cal->repeat);
+ }
+ else if (cal->chord == 'g') {
+ select_up(cal, cal->repeat);
+ cal->chord = 0;
+ }
cal->repeat = 1;
break;
@@ -926,6 +959,12 @@ calendar_time_to_loc(struct cal *cal, time_t time) {
+static double calendar_time_to_loc_absolute(struct cal *cal, time_t time) {
+ return calendar_time_to_loc(cal, time) * cal->height + cal->y;
+}
+
+
+
static void
event_update (struct event *ev, struct cal *cal)
{
@@ -1132,7 +1171,7 @@ draw_event (cairo_t *cr, struct cal *cal, struct event *ev) {
/* x += ev->dragx; */
y += ev->dragy;
st = closest_timeblock(cal, y);
- y = cal->y + calendar_time_to_loc(cal, st) * cal->height;
+ y = calendar_time_to_loc_absolute(cal, st);
cal->target->drag_time = st;
}
@@ -1216,8 +1255,7 @@ draw_line (cairo_t *cr, double x, double y, double w) {
static void
draw_time_line(cairo_t *cr, struct cal *cal, time_t time) {
- double loc = calendar_time_to_loc(cal, time);
- double y = (loc * cal->height) + cal->y;
+ double y = calendar_time_to_loc_absolute(cal, time);
int w = cal->width;
cairo_set_line_width(cr, 1.0);
@@ -1235,6 +1273,21 @@ draw_time_line(cairo_t *cr, struct cal *cal, time_t time) {
/* cairo_stroke(cr); */
}
+static void
+draw_selection (cairo_t *cr, struct cal *cal)
+{
+ double sx = cal->x;
+ double sy = calendar_time_to_loc_absolute(cal, cal->current);
+ time_t et = cal->current + cal->timeblock_size * 60;
+ double height = calendar_time_to_loc_absolute(cal, et) - sy;
+
+ cairo_move_to(cr, sx, sy);
+
+ cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.2);
+ draw_rectangle(cr, cal->width, height);
+ cairo_fill(cr);
+}
+
static int
draw_calendar (cairo_t *cr, struct cal *cal) {
int i, width, height;
@@ -1252,6 +1305,8 @@ draw_calendar (cairo_t *cr, struct cal *cal) {
draw_event(cr, cal, ev);
}
+ draw_selection(cr, cal);
+
draw_time_line(cr, cal, time(&now));
return 1;