diff --git a/data/theme/gtk-styles.css b/data/theme/gtk-styles.css index c33ed852..98be14e1 100644 --- a/data/theme/gtk-styles.css +++ b/data/theme/gtk-styles.css @@ -422,6 +422,11 @@ weekgrid.now-strip { min-height: 2px; } -weekgrid:selected { +weekgrid:selected, +.week-header:selected { background-color: alpha(@theme_selected_bg_color, 0.4); } + +.week-header:selected { + border: solid 1px alpha(@theme_selected_bg_color, 0.8); +} diff --git a/data/ui/week-header.ui b/data/ui/week-header.ui index 28524cc1..ac6a5a17 100644 --- a/data/ui/week-header.ui +++ b/data/ui/week-header.ui @@ -80,101 +80,109 @@ - + True - never - never - True - 2 + + + - + True - none + never + never + True + 2 - + True - True - True - 6 - 2 - 6 - 6 + none - + True + True + True + 6 + 2 + 6 + 6 + + + True + + + 0 + 0 + 1 + 1 + + + + + True + + + 1 + 0 + 1 + 1 + + + + + True + + + 2 + 0 + 1 + 1 + + + + + True + + + 3 + 0 + 1 + 1 + + + + + True + + + 4 + 0 + 1 + 1 + + + + + True + + + 5 + 0 + 1 + 1 + + + + + True + + + 6 + 0 + 1 + 1 + + - - 0 - 0 - 1 - 1 - - - - - True - - - 1 - 0 - 1 - 1 - - - - - True - - - 2 - 0 - 1 - 1 - - - - - True - - - 3 - 0 - 1 - 1 - - - - - True - - - 4 - 0 - 1 - 1 - - - - - True - - - 5 - 0 - 1 - 1 - - - - - True - - - 6 - 0 - 1 - 1 - diff --git a/src/views/gcal-week-header.c b/src/views/gcal-week-header.c index 22962ba1..26724d06 100644 --- a/src/views/gcal-week-header.c +++ b/src/views/gcal-week-header.c @@ -69,6 +69,9 @@ struct _GcalWeekHeader icaltimetype *active_date; icaltimetype *current_date; + gint selection_start; + gint selection_end; + GtkSizeGroup *sizegroup; }; @@ -141,6 +144,118 @@ destroy_event_widget (GcalWeekHeader *self, } /* Auxiliary methods */ +static gboolean +on_button_pressed (GcalWeekHeader *self, + GdkEventButton *event, + GtkWidget *widget) +{ + gboolean ltr; + gdouble column_width; + gint column; + gint width; + + ltr = gtk_widget_get_direction (widget) != GTK_TEXT_DIR_RTL; + width = gtk_widget_get_allocated_width (widget); + column_width = width / 7.0; + column = ltr ? (event->x / column_width) : (7 - event->x / column_width); + + self->selection_start = column; + self->selection_end = column; + + gtk_widget_queue_draw (GTK_WIDGET (self)); + + return GDK_EVENT_STOP; +} + +static gboolean +on_motion_notify (GcalWeekHeader *self, + GdkEventMotion *event, + GtkWidget *widget) +{ + gboolean ltr; + gdouble column_width; + gint column; + gint width; + + if (!(event->state & GDK_BUTTON_PRESS_MASK)) + return GDK_EVENT_PROPAGATE; + + ltr = gtk_widget_get_direction (widget) != GTK_TEXT_DIR_RTL; + width = gtk_widget_get_allocated_width (widget); + column_width = width / 7.0; + column = ltr ? (event->x / column_width) : (7 - event->x / column_width); + + self->selection_end = column; + + gtk_widget_queue_draw (GTK_WIDGET (self)); + + return GDK_EVENT_STOP; +} + +static gboolean +on_button_released (GcalWeekHeader *self, + GdkEventButton *event, + GtkWidget *widget) +{ + g_autoptr (GDateTime) week_start, selection_start, selection_end; + GtkWidget *weekview; + gboolean ltr; + gdouble column_width; + gint out_x, out_y; + gint column; + gint width; + gint start; + gint end; + + ltr = gtk_widget_get_direction (widget) != GTK_TEXT_DIR_RTL; + width = gtk_widget_get_allocated_width (widget); + column_width = width / 7.0; + column = ltr ? (event->x / column_width) : (7 - event->x / column_width); + + self->selection_end = column; + + gtk_widget_queue_draw (GTK_WIDGET (self)); + + /* Fake the week view's event so we can control the X and Y values */ + weekview = gtk_widget_get_ancestor (widget, GCAL_TYPE_WEEK_VIEW); + + start = self->selection_start; + end = self->selection_end; + + if (start > end) + { + start = start + end; + end = start - end; + start = start - end; + } + + week_start = get_start_of_week (self->active_date); + selection_start = g_date_time_add_days (week_start, start); + selection_end = g_date_time_add_days (week_start, end + 1); + + out_x = ltr ? (column_width * (column + 0.5)) : (width - column_width * (column + 0.5)); + + /* Translate X... */ + gtk_widget_translate_coordinates (widget, weekview, out_x, 0, &out_x, NULL); + + /* And Y */ + gtk_widget_translate_coordinates (GTK_WIDGET (self), + weekview, + 0, + gtk_widget_get_allocated_height (GTK_WIDGET (self)), + NULL, + &out_y); + + g_signal_emit_by_name (weekview, + "create-event", + selection_start, + selection_end, + (gdouble) out_x, + (gdouble) out_y); + + return GDK_EVENT_STOP; +} + static GcalEvent* get_event_by_uuid (GcalWeekHeader *self, const gchar *uuid) @@ -1035,7 +1150,7 @@ gcal_week_header_draw (GtkWidget *widget, /* Fonts and colour selection */ self = GCAL_WEEK_HEADER (widget); context = gtk_widget_get_style_context (widget); - state = gtk_widget_get_state_flags (widget); + state = gtk_style_context_get_state (context); ltr = gtk_widget_get_direction (widget) != GTK_TEXT_DIR_RTL; start_x = ltr ? gtk_widget_get_allocated_width (self->expand_button_box) : 0; @@ -1071,6 +1186,38 @@ gcal_week_header_draw (GtkWidget *widget, alloc.width, alloc.height); + /* Draw the selection background */ + if (self->selection_start != -1 && self->selection_end != -1) + { + gint selection_width; + gint selection_x; + gint start, end; + + start = self->selection_start; + end = self->selection_end; + + if (start > end) + { + start = start + end; + end = start - end; + start = start - end; + } + + gtk_style_context_save (context); + gtk_style_context_set_state (context, state | GTK_STATE_FLAG_SELECTED); + + selection_width = (end - start + 1) * cell_width; + selection_x = ltr ? (start * cell_width) : (alloc.width - (start * cell_width + selection_width)); + + gtk_render_background (context, cr, + ALIGNED (start_x + selection_x), + start_y, + selection_width, + alloc.height - start_y); + + gtk_style_context_restore (context); + } + pango_layout_get_pixel_size (layout, NULL, &font_height); for (i = 0; i < 7; i++) @@ -1228,7 +1375,10 @@ gcal_week_header_class_init (GcalWeekHeaderClass *kclass) gtk_widget_class_bind_template_child (widget_class, GcalWeekHeader, week_label); gtk_widget_class_bind_template_child (widget_class, GcalWeekHeader, year_label); + gtk_widget_class_bind_template_callback (widget_class, on_button_pressed); + gtk_widget_class_bind_template_callback (widget_class, on_button_released); gtk_widget_class_bind_template_callback (widget_class, on_expand_action_activated); + gtk_widget_class_bind_template_callback (widget_class, on_motion_notify); gtk_widget_class_set_css_name (widget_class, "calendar-view"); } @@ -1237,6 +1387,8 @@ static void gcal_week_header_init (GcalWeekHeader *self) { self->expanded = FALSE; + self->selection_start = -1; + self->selection_end = -1; gtk_widget_init_template (GTK_WIDGET (self)); } @@ -1431,3 +1583,14 @@ gcal_week_header_get_sidebar_size_group (GcalWeekHeader *self) return self->sizegroup; } + +void +gcal_week_header_clear_marks (GcalWeekHeader *self) +{ + g_return_if_fail (GCAL_IS_WEEK_HEADER (self)); + + self->selection_start = -1; + self->selection_end = -1; + + gtk_widget_queue_draw (GTK_WIDGET (self)); +} diff --git a/src/views/gcal-week-header.h b/src/views/gcal-week-header.h index f11d3c01..f916c4e5 100644 --- a/src/views/gcal-week-header.h +++ b/src/views/gcal-week-header.h @@ -54,6 +54,8 @@ GList* gcal_week_header_get_children_by_uuid (GcalWeekHeader GtkSizeGroup* gcal_week_header_get_sidebar_size_group (GcalWeekHeader *self); +void gcal_week_header_clear_marks (GcalWeekHeader *self); + G_END_DECLS #endif /* GCAL_WEEK_HEADER_H */ diff --git a/src/views/gcal-week-view.c b/src/views/gcal-week-view.c index 0263a070..92a34b9a 100644 --- a/src/views/gcal-week-view.c +++ b/src/views/gcal-week-view.c @@ -264,6 +264,7 @@ gcal_week_view_clear_marks (GcalView *view) { GcalWeekView *self = GCAL_WEEK_VIEW (view); + gcal_week_header_clear_marks (GCAL_WEEK_HEADER (self->header)); gcal_week_grid_clear_marks (GCAL_WEEK_GRID (self->week_grid)); }