From aa8a700dd924a83e1dcd8eb374df777fb0a83b66 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Thu, 30 Jul 2009 11:22:59 +0200 Subject: Bug #300567 - Calendar drawing optimizations --- calendar/gui/calendar-config-keys.h | 4 + calendar/gui/calendar-config.c | 21 ++ calendar/gui/calendar-config.h | 4 + calendar/gui/comp-util.c | 26 +- calendar/gui/comp-util.h | 2 +- calendar/gui/e-day-view-main-item.c | 448 ++++++++++++++-------------------- calendar/gui/e-day-view-top-item.c | 13 +- calendar/gui/e-day-view.c | 4 +- calendar/gui/e-week-view-event-item.c | 331 ++++++++++++------------- calendar/gui/e-week-view.c | 2 +- 10 files changed, 396 insertions(+), 459 deletions(-) (limited to 'calendar/gui') diff --git a/calendar/gui/calendar-config-keys.h b/calendar/gui/calendar-config-keys.h index 61044f577b..9afa8dc7e4 100644 --- a/calendar/gui/calendar-config-keys.h +++ b/calendar/gui/calendar-config-keys.h @@ -95,6 +95,10 @@ G_BEGIN_DECLS #define CALENDAR_CONFIG_DEF_RECUR_COUNT CALENDAR_CONFIG_PREFIX "/other/def_recur_count" +/* drawing of events */ +#define CALENDAR_CONFIG_DISPLAY_EVENTS_GRADIENT CALENDAR_CONFIG_PREFIX "/display/events_gradient" +#define CALENDAR_CONFIG_DISPLAY_EVENTS_ALPHA CALENDAR_CONFIG_PREFIX "/display/events_transparency" + G_END_DECLS #endif diff --git a/calendar/gui/calendar-config.c b/calendar/gui/calendar-config.c index 6b458adf58..4a727f486a 100644 --- a/calendar/gui/calendar-config.c +++ b/calendar/gui/calendar-config.c @@ -41,6 +41,8 @@ #include "calendar-config.h" static GConfClient *config = NULL; +static gboolean display_events_gradient = TRUE; +static gfloat display_events_alpha = 1.0; static void do_cleanup (void) @@ -59,6 +61,9 @@ calendar_config_init (void) g_atexit ((GVoidFunc) do_cleanup); gconf_client_add_dir (config, CALENDAR_CONFIG_PREFIX, GCONF_CLIENT_PRELOAD_RECURSIVE, NULL); + + display_events_gradient = gconf_client_get_bool (config, CALENDAR_CONFIG_DISPLAY_EVENTS_GRADIENT, NULL); + display_events_alpha = gconf_client_get_float (config, CALENDAR_CONFIG_DISPLAY_EVENTS_ALPHA, NULL); } void @@ -1017,3 +1022,19 @@ calendar_config_get_default_count (void) return res; } + +gboolean +calendar_config_get_display_events_gradient (void) +{ + calendar_config_init (); + + return display_events_gradient; +} + +gfloat +calendar_config_get_display_events_alpha (void) +{ + calendar_config_init (); + + return display_events_alpha; +} diff --git a/calendar/gui/calendar-config.h b/calendar/gui/calendar-config.h index 950cb50862..50df8a4875 100644 --- a/calendar/gui/calendar-config.h +++ b/calendar/gui/calendar-config.h @@ -184,4 +184,8 @@ guint calendar_config_add_notification_month_scroll_by_week (GConfClientNotifyFu /* default count for recurring events */ gint calendar_config_get_default_count (void); +/* event drawing customization, one-time read on start only */ +gboolean calendar_config_get_display_events_gradient (void); +gfloat calendar_config_get_display_events_alpha (void); + #endif /* _CALENDAR_CONFIG_H_ */ diff --git a/calendar/gui/comp-util.c b/calendar/gui/comp-util.c index 30af43fd6d..a745b61e12 100644 --- a/calendar/gui/comp-util.c +++ b/calendar/gui/comp-util.c @@ -428,13 +428,16 @@ cal_comp_memo_new_with_defaults (ECal *client) /** * cal_comp_util_get_n_icons: * @comp: A calendar component object. + * @pixbufs: List of pixbufs to use. Can be NULL. * * Get the number of icons owned by the component. + * Each member of pixmaps should be freed with g_object_unref + * and the list itself should be freed too. * * Returns: the number of icons owned by the component. **/ gint -cal_comp_util_get_n_icons (ECalComponent *comp) +cal_comp_util_get_n_icons (ECalComponent *comp, GSList **pixbufs) { GSList *categories_list, *elem; gint num_icons = 0; @@ -444,16 +447,21 @@ cal_comp_util_get_n_icons (ECalComponent *comp) e_cal_component_get_categories_list (comp, &categories_list); for (elem = categories_list; elem; elem = elem->next) { - gchar *category; - GdkPixmap *pixmap = NULL; - GdkBitmap *mask = NULL; + const gchar *category; + GdkPixbuf *pixbuf = NULL; + + category = elem->data; + if (e_categories_config_get_icon_for (category, &pixbuf)) { + if (!pixbuf) + continue; - category = (gchar *) elem->data; - if (e_categories_config_get_icon_for (category, &pixmap, &mask)) { num_icons++; - g_object_unref (pixmap); - if (mask) - g_object_unref (mask); + + if (pixbufs) { + *pixbufs = g_slist_append (*pixbufs, pixbuf); + } else { + g_object_unref (pixbuf); + } } } e_cal_component_free_categories_list (categories_list); diff --git a/calendar/gui/comp-util.h b/calendar/gui/comp-util.h index d46fcb79e2..2faea3e217 100644 --- a/calendar/gui/comp-util.h +++ b/calendar/gui/comp-util.h @@ -39,7 +39,7 @@ gboolean cal_comp_util_compare_event_timezones (ECalComponent *comp, icaltimezone *zone); /* Returns the number of icons owned by the ECalComponent */ -gint cal_comp_util_get_n_icons (ECalComponent *comp); +gint cal_comp_util_get_n_icons (ECalComponent *comp, GSList **pixbufs); gboolean cal_comp_is_on_server (ECalComponent *comp, ECal *client); diff --git a/calendar/gui/e-day-view-main-item.c b/calendar/gui/e-day-view-main-item.c index afa4e8b5c6..298831d60b 100644 --- a/calendar/gui/e-day-view-main-item.c +++ b/calendar/gui/e-day-view-main-item.c @@ -35,6 +35,7 @@ /*#include "a11y/ea-calendar.h"*/ /* KILL-BONOBO */ #include "e-calendar-view.h" #include "comp-util.h" +#include "calendar-config.h" #include #include @@ -61,22 +62,22 @@ static void e_day_view_main_item_draw_long_events_in_vbars (EDayViewMainItem *dv gint x, gint y, gint width, - gint height); + gint height, GdkRegion *draw_region); static void e_day_view_main_item_draw_events_in_vbars (EDayViewMainItem *dvmitem, GdkDrawable *drawable, gint x, gint y, gint width, gint height, - gint day); + gint day, GdkRegion *draw_region); static void e_day_view_main_item_draw_day_events (EDayViewMainItem *dvmitem, GdkDrawable *drawable, gint x, gint y, gint width, gint height, - gint day); + gint day, GdkRegion *draw_region); static void e_day_view_main_item_draw_day_event (EDayViewMainItem *dvmitem, GdkDrawable *drawable, gint x, gint y, gint width, gint height, - gint day, gint event_num); + gint day, gint event_num, GdkRegion *draw_region); /* The arguments we take */ enum { @@ -157,6 +158,36 @@ e_day_view_main_item_update (GnomeCanvasItem *item, item->y2 = INT_MAX; } +static gboolean +can_draw_in_region (GdkRegion *draw_region, gint x, gint y, gint width, gint height) +{ + GdkRectangle rect; + + g_return_val_if_fail (draw_region != NULL, FALSE); + + rect.x = x; + rect.y = y; + rect.width = width; + rect.height = height; + + return gdk_region_rect_in (draw_region, &rect) != GDK_OVERLAP_RECTANGLE_OUT; +} + +static gboolean +icalcomp_is_transparent (icalcomponent *icalcomp) +{ + icalproperty *transp_prop; + icalproperty_transp ical_transp = ICAL_TRANSP_NONE; + + g_return_val_if_fail (icalcomp != NULL, TRUE); + + transp_prop = icalcomponent_get_first_property (icalcomp, ICAL_TRANSP_PROPERTY); + if (transp_prop) + ical_transp = icalproperty_get_transp (transp_prop); + + return transp_prop && (ical_transp == ICAL_TRANSP_TRANSPARENT || ical_transp == ICAL_TRANSP_TRANSPARENTNOCONFLICT); +} + /* * DRAWING ROUTINES - functions to paint the canvas item. */ @@ -177,6 +208,8 @@ e_day_view_main_item_draw (GnomeCanvasItem *canvas_item, GdkDrawable *drawable, gint weekday; cairo_t *cr; gboolean today = FALSE; + GdkRegion *draw_region; + GdkRectangle rect; cr = gdk_cairo_create (drawable); @@ -190,6 +223,11 @@ e_day_view_main_item_draw (GnomeCanvasItem *canvas_item, GdkDrawable *drawable, g_return_if_fail (day_view != NULL); style = gtk_widget_get_style (GTK_WIDGET (day_view)); + rect.x = 0; + rect.y = 0; + rect.width = width; + rect.height = height; + draw_region = gdk_region_rectangle (&rect); /* Paint the background colors. */ work_day_start_y = e_day_view_convert_time_to_position (day_view, day_view->work_day_start_hour, day_view->work_day_start_minute) - y; @@ -210,13 +248,13 @@ e_day_view_main_item_draw (GnomeCanvasItem *canvas_item, GdkDrawable *drawable, day_w = day_view->day_widths[day]; if (work_day) { - cairo_save (cr); - gdk_cairo_set_source_color (cr, &day_view->colors[E_DAY_VIEW_COLOR_BG_NOT_WORKING]); - - cairo_rectangle (cr, day_x, 0 - y, day_w, - work_day_start_y - (0 - y)); - cairo_fill (cr); - cairo_restore (cr); + if (can_draw_in_region (draw_region, day_x, 0 - y, day_w, work_day_start_y - (0 - y))) { + cairo_save (cr); + gdk_cairo_set_source_color (cr, &day_view->colors[E_DAY_VIEW_COLOR_BG_NOT_WORKING]); + cairo_rectangle (cr, day_x, 0 - y, day_w, work_day_start_y - (0 - y)); + cairo_fill (cr); + cairo_restore (cr); + } if (day_view->days_shown > 1) { /* Check if we are drawing today */ @@ -227,25 +265,24 @@ e_day_view_main_item_draw (GnomeCanvasItem *canvas_item, GdkDrawable *drawable, today = FALSE; } - cairo_save (cr); - gdk_cairo_set_source_color (cr, &day_view->colors[today ? E_DAY_VIEW_COLOR_BG_MULTIDAY_TODAY : E_DAY_VIEW_COLOR_BG_WORKING]); - - cairo_rectangle (cr, day_x, work_day_start_y, day_w, - work_day_end_y - work_day_start_y); - cairo_fill (cr); - cairo_restore (cr); - - cairo_save (cr); - gdk_cairo_set_source_color (cr, &day_view->colors[E_DAY_VIEW_COLOR_BG_NOT_WORKING]); + if (can_draw_in_region (draw_region, day_x, work_day_start_y, day_w, work_day_end_y - work_day_start_y)) { + cairo_save (cr); + gdk_cairo_set_source_color (cr, &day_view->colors[today ? E_DAY_VIEW_COLOR_BG_MULTIDAY_TODAY : E_DAY_VIEW_COLOR_BG_WORKING]); + cairo_rectangle (cr, day_x, work_day_start_y, day_w, work_day_end_y - work_day_start_y); + cairo_fill (cr); + cairo_restore (cr); + } - cairo_rectangle (cr, day_x, work_day_end_y, day_w, - height - work_day_end_y); - cairo_fill (cr); - cairo_restore (cr); - } else { + if (can_draw_in_region (draw_region, day_x, work_day_end_y, day_w, height - work_day_end_y)) { + cairo_save (cr); + gdk_cairo_set_source_color (cr, &day_view->colors[E_DAY_VIEW_COLOR_BG_NOT_WORKING]); + cairo_rectangle (cr, day_x, work_day_end_y, day_w, height - work_day_end_y); + cairo_fill (cr); + cairo_restore (cr); + } + } else if (can_draw_in_region (draw_region, day_x, 0, day_w, height)) { cairo_save (cr); gdk_cairo_set_source_color (cr, &day_view->colors[E_DAY_VIEW_COLOR_BG_NOT_WORKING]); - cairo_rectangle (cr, day_x, 0, day_w, height); cairo_fill (cr); cairo_restore (cr); @@ -274,20 +311,10 @@ e_day_view_main_item_draw (GnomeCanvasItem *canvas_item, GdkDrawable *drawable, rect_y = start_row * day_view->row_height - y; rect_height = (end_row - start_row + 1) * day_view->row_height; - if (GTK_WIDGET_HAS_FOCUS(day_view)) { - cairo_save (cr); - gdk_cairo_set_source_color (cr, - &day_view->colors[E_DAY_VIEW_COLOR_BG_SELECTED]); - cairo_rectangle (cr, rect_x, rect_y, rect_width, - rect_height); - cairo_fill (cr); - cairo_restore (cr); - } else { + if (can_draw_in_region (draw_region, rect_x, rect_y, rect_width, rect_height)) { cairo_save (cr); - gdk_cairo_set_source_color (cr, - &day_view->colors[E_DAY_VIEW_COLOR_BG_SELECTED_UNFOCUSSED]); - cairo_rectangle (cr, rect_x, rect_y, rect_width, - rect_height); + gdk_cairo_set_source_color (cr, &day_view->colors[GTK_WIDGET_HAS_FOCUS(day_view) ? E_DAY_VIEW_COLOR_BG_SELECTED : E_DAY_VIEW_COLOR_BG_SELECTED_UNFOCUSSED]); + cairo_rectangle (cr, rect_x, rect_y, rect_width, rect_height); cairo_fill (cr); cairo_restore (cr); } @@ -351,20 +378,20 @@ e_day_view_main_item_draw (GnomeCanvasItem *canvas_item, GdkDrawable *drawable, e_day_view_main_item_draw_events_in_vbars (dvmitem, drawable, x, y, width, height, - day); + day, draw_region); } /* Fill in the vertical bars corresponding to the busy times from the long events. */ e_day_view_main_item_draw_long_events_in_vbars (dvmitem, drawable, - x, y, width, height); + x, y, width, height, draw_region); /* Draw the event borders and backgrounds, and the vertical bars down the left edges. */ for (day = 0; day < day_view->days_shown; day++) { e_day_view_main_item_draw_day_events (dvmitem, drawable, x, y, width, height, - day); + day, draw_region); } if (e_day_view_marcus_bains_get_show_line (day_view)) { @@ -406,6 +433,7 @@ e_day_view_main_item_draw (GnomeCanvasItem *canvas_item, GdkDrawable *drawable, cairo_restore (cr); } cairo_destroy (cr); + gdk_region_destroy (draw_region); } static void @@ -413,56 +441,24 @@ e_day_view_main_item_draw_events_in_vbars (EDayViewMainItem *dvmitem, GdkDrawable *drawable, gint x, gint y, gint width, gint height, - gint day) + gint day, GdkRegion *draw_region) { EDayView *day_view; EDayViewEvent *event; gint grid_x, event_num, bar_y, bar_h; - ECalComponentTransparency transparency; - cairo_t *cr; + cairo_t *cr = NULL; GdkColor bg_color; day_view = dvmitem->day_view; - cr = gdk_cairo_create (drawable); - cairo_save (cr); - - gdk_cairo_set_source_color (cr, - &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BACKGROUND]); - grid_x = day_view->day_offsets[day] + 1 - x; /* Draw the busy times corresponding to the events in the day. */ - for (event_num = 0; event_num < day_view->events[day]->len; - event_num++) { - ECalComponent *comp; - - event = &g_array_index (day_view->events[day], EDayViewEvent, - event_num); - if (gdk_color_parse (e_cal_model_get_color_for_component (e_calendar_view_get_model (E_CALENDAR_VIEW (day_view)), event->comp_data), - &bg_color)) { - GdkColormap *colormap; - - colormap = gtk_widget_get_colormap (GTK_WIDGET (day_view)); - if (gdk_colormap_alloc_color (colormap, &bg_color, TRUE, TRUE)) { - gdk_cairo_set_source_color (cr, - &bg_color); - } - } - - comp = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp)); - - /* If the event is TRANSPARENT, skip it. */ - e_cal_component_get_transparency (comp, &transparency); - if (transparency == E_CAL_COMPONENT_TRANSP_TRANSPARENT) { - g_object_unref (comp); - continue; - } + for (event_num = 0; event_num < day_view->events[day]->len; event_num++) { + event = &g_array_index (day_view->events[day], EDayViewEvent, event_num); /* We can skip the events in the first column since they will draw over this anyway. */ if (event->num_columns > 0 && event->start_row_or_col == 0) { - g_object_unref (comp); continue; } @@ -471,66 +467,62 @@ e_day_view_main_item_draw_events_in_vbars (EDayViewMainItem *dvmitem, bar_y -= y; /* Skip it if it isn't visible. */ - if (bar_y >= height || bar_y + bar_h <= 0) { - g_object_unref (comp); + if (bar_y >= height || bar_y + bar_h <= 0 || !can_draw_in_region (draw_region, grid_x, bar_y, E_DAY_VIEW_BAR_WIDTH - 2, bar_h)) { + continue; + } + + /* If the event is TRANSPARENT, skip it. */ + if (icalcomp_is_transparent (event->comp_data->icalcomp)) { continue; } - cairo_rectangle (cr, grid_x, bar_y, - E_DAY_VIEW_BAR_WIDTH - 2, bar_h); + if (!cr) { + cr = gdk_cairo_create (drawable); + cairo_save (cr); + + gdk_cairo_set_source_color (cr, &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BACKGROUND]); + } + + if (gdk_color_parse (e_cal_model_get_color_for_component (e_calendar_view_get_model (E_CALENDAR_VIEW (day_view)), event->comp_data), &bg_color)) { + GdkColormap *colormap; + + colormap = gtk_widget_get_colormap (GTK_WIDGET (day_view)); + if (gdk_colormap_alloc_color (colormap, &bg_color, TRUE, TRUE)) { + gdk_cairo_set_source_color (cr, &bg_color); + } + } + + cairo_rectangle (cr, grid_x, bar_y, E_DAY_VIEW_BAR_WIDTH - 2, bar_h); cairo_fill (cr); + } - g_object_unref (comp); + if (cr) { + cairo_restore (cr); + cairo_destroy (cr); } - cairo_restore (cr); - cairo_destroy (cr); } static void e_day_view_main_item_draw_long_events_in_vbars (EDayViewMainItem *dvmitem, GdkDrawable *drawable, gint x, gint y, - gint width, gint height) + gint width, gint height, GdkRegion *draw_region) { EDayView *day_view; EDayViewEvent *event; gint event_num, start_day, end_day, day, bar_y1, bar_y2, grid_x; - ECalComponentTransparency transparency; - cairo_t *cr; + cairo_t *cr = NULL; GdkColor bg_color; day_view = dvmitem->day_view; - cr = gdk_cairo_create (drawable); - cairo_save (cr); - - gdk_cairo_set_source_color (cr, - &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BACKGROUND]); - - for (event_num = 0; event_num < day_view->long_events->len; - event_num++) { - ECalComponent *comp; - - event = &g_array_index (day_view->long_events, EDayViewEvent, - event_num); - if (gdk_color_parse (e_cal_model_get_color_for_component (e_calendar_view_get_model (E_CALENDAR_VIEW (day_view)), event->comp_data), - &bg_color)) { - GdkColormap *colormap; - - colormap = gtk_widget_get_colormap (GTK_WIDGET (day_view)); - if (gdk_colormap_alloc_color (colormap, &bg_color, TRUE, TRUE)) { - gdk_cairo_set_source_color (cr, &bg_color); - } - } - - comp = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp)); + for (event_num = 0; event_num < day_view->long_events->len; event_num++) { + gboolean first = TRUE; + event = &g_array_index (day_view->long_events, EDayViewEvent, event_num); /* If the event is TRANSPARENT, skip it. */ - e_cal_component_get_transparency (comp, &transparency); - if (transparency == E_CAL_COMPONENT_TRANSP_TRANSPARENT) { - g_object_unref (comp); + if (icalcomp_is_transparent (event->comp_data->icalcomp)) { continue; } @@ -538,7 +530,6 @@ e_day_view_main_item_draw_long_events_in_vbars (EDayViewMainItem *dvmitem, day_view->days_shown, day_view->day_starts, &start_day, &end_day)) { - g_object_unref (comp); continue; } @@ -562,24 +553,43 @@ e_day_view_main_item_draw_long_events_in_vbars (EDayViewMainItem *dvmitem, bar_y2 = event->end_minute * day_view->row_height / day_view->mins_per_row - y; } - if (bar_y1 < height && bar_y2 > 0 && bar_y2 > bar_y1) { - cairo_rectangle (cr, grid_x, bar_y1, - E_DAY_VIEW_BAR_WIDTH - 2, bar_y2 - bar_y1); + if (bar_y1 < height && bar_y2 > 0 && bar_y2 > bar_y1 && can_draw_in_region (draw_region, grid_x, bar_y1, E_DAY_VIEW_BAR_WIDTH - 2, bar_y2 - bar_y1)) { + if (!cr) { + cr = gdk_cairo_create (drawable); + cairo_save (cr); + gdk_cairo_set_source_color (cr, &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BACKGROUND]); + } + if (first) { + first = FALSE; + + if (gdk_color_parse (e_cal_model_get_color_for_component (e_calendar_view_get_model (E_CALENDAR_VIEW (day_view)), event->comp_data), &bg_color)) { + GdkColormap *colormap; + + colormap = gtk_widget_get_colormap (GTK_WIDGET (day_view)); + if (gdk_colormap_alloc_color (colormap, &bg_color, TRUE, TRUE)) { + gdk_cairo_set_source_color (cr, &bg_color); + } + } + } + + cairo_rectangle (cr, grid_x, bar_y1, E_DAY_VIEW_BAR_WIDTH - 2, bar_y2 - bar_y1); cairo_fill (cr); } } - g_object_unref (comp); } - cairo_restore (cr); - cairo_destroy (cr); + + if (cr) { + cairo_restore (cr); + cairo_destroy (cr); + } } static void e_day_view_main_item_draw_day_events (EDayViewMainItem *dvmitem, GdkDrawable *drawable, gint x, gint y, gint width, gint height, - gint day) + gint day, GdkRegion *draw_region) { EDayView *day_view; gint event_num; @@ -590,7 +600,7 @@ e_day_view_main_item_draw_day_events (EDayViewMainItem *dvmitem, event_num++) { e_day_view_main_item_draw_day_event (dvmitem, drawable, x, y, width, height, - day, event_num); + day, event_num, draw_region); } } @@ -598,7 +608,7 @@ static void e_day_view_main_item_draw_day_event (EDayViewMainItem *dvmitem, GdkDrawable *drawable, gint x, gint y, gint width, gint height, - gint day, gint event_num) + gint day, gint event_num, GdkRegion *draw_region) { EDayView *day_view; EDayViewEvent *event; @@ -611,7 +621,6 @@ e_day_view_main_item_draw_day_event (EDayViewMainItem *dvmitem, gint max_icon_w, max_icon_h; gboolean draw_reminder_icon, draw_recurrence_icon, draw_timezone_icon, draw_meeting_icon; gboolean draw_attach_icon; - GSList *categories_list, *elem; ECalComponentTransparency transparency; cairo_t *cr; cairo_pattern_t *pat; @@ -635,35 +644,13 @@ e_day_view_main_item_draw_day_event (EDayViewMainItem *dvmitem, gchar *text = NULL; gint scroll_flag = 0; gint row_y; - GConfClient *gconf; day_view = dvmitem->day_view; model = e_calendar_view_get_model (E_CALENDAR_VIEW (day_view)); - cr = gdk_cairo_create (drawable); - gdk_cairo_set_source_color (cr, - &day_view->colors[E_DAY_VIEW_COLOR_EVENT_VBAR]); - - gc = day_view->main_gc; - - gconf = gconf_client_get_default (); - - alpha = gconf_client_get_float (gconf, - "/apps/evolution/calendar/display/events_transparency", - NULL); - - gradient = gconf_client_get_bool (gconf, - "/apps/evolution/calendar/display/events_gradient", - NULL); - - g_object_unref (gconf); - - font_options = get_font_options (); - /* If the event is currently being dragged, don't draw it. It will be drawn in the special drag items. */ - if (day_view->drag_event_day == day - && day_view->drag_event_num == event_num) + if (day_view->drag_event_day == day && day_view->drag_event_num == event_num) return; /* Get the position of the event. If it is not shown skip it.*/ @@ -675,6 +662,20 @@ e_day_view_main_item_draw_day_event (EDayViewMainItem *dvmitem, item_x -= x; item_y -= y; + if (!can_draw_in_region (draw_region, item_x, item_y, item_w, item_h)) + return; + + cr = gdk_cairo_create (drawable); + gdk_cairo_set_source_color (cr, + &day_view->colors[E_DAY_VIEW_COLOR_EVENT_VBAR]); + + gc = day_view->main_gc; + + gradient = calendar_config_get_display_events_gradient (); + alpha = calendar_config_get_display_events_alpha (); + + font_options = get_font_options (); + event = &g_array_index (day_view->events[day], EDayViewEvent, event_num); @@ -1042,6 +1043,8 @@ e_day_view_main_item_draw_day_event (EDayViewMainItem *dvmitem, /* Draw the reminder & recurrence icons, if needed. */ if (!resize_flag && (!is_editing || text_x_offset > E_DAY_VIEW_ICON_X_PAD)) { + GSList *categories_pixbufs = NULL, *pixbufs; + num_icons = 0; draw_reminder_icon = FALSE; draw_recurrence_icon = FALSE; @@ -1077,8 +1080,7 @@ e_day_view_main_item_draw_day_event (EDayViewMainItem *dvmitem, num_icons++; } - num_icons += cal_comp_util_get_n_icons (comp); - e_cal_component_get_categories_list (comp, &categories_list); + num_icons += cal_comp_util_get_n_icons (comp, &categories_pixbufs); if (num_icons != 0) { if (item_h >= (E_DAY_VIEW_ICON_HEIGHT + E_DAY_VIEW_ICON_Y_PAD) * num_icons) { @@ -1091,137 +1093,61 @@ e_day_view_main_item_draw_day_event (EDayViewMainItem *dvmitem, icon_y_inc = 0; } - #define fit_in_event() icon_x + icon_x_inc < item_x + item_w && icon_y + icon_y_inc < item_y + item_h + #define fit_in_event() (icon_x + icon_x_inc < item_x + item_w && icon_y + icon_y_inc < item_y + item_h) + #define draw_pixbuf(pf) \ + max_icon_w = item_x + item_w - icon_x - E_DAY_VIEW_EVENT_BORDER_WIDTH; \ + max_icon_h = item_y + item_h - icon_y - E_DAY_VIEW_EVENT_BORDER_HEIGHT; \ + \ + if (can_draw_in_region (draw_region, icon_x, icon_y, max_icon_w, max_icon_h)) { \ + cairo_save (cr); \ + cairo_rectangle (cr, icon_x, icon_y, max_icon_w, max_icon_h); \ + cairo_clip (cr); \ + cairo_new_path (cr); \ + gdk_cairo_set_source_pixbuf (cr, pf, icon_x, icon_y); \ + cairo_paint (cr); \ + cairo_close_path (cr); \ + cairo_restore (cr); \ + } \ + \ + icon_x += icon_x_inc; \ + icon_y += icon_y_inc; if (draw_reminder_icon && fit_in_event ()) { - max_icon_w = item_x + item_w - icon_x - - E_DAY_VIEW_EVENT_BORDER_WIDTH; - max_icon_h = item_y + item_h - icon_y - - E_DAY_VIEW_EVENT_BORDER_HEIGHT; - - cairo_save (cr); - cairo_rectangle (cr, icon_x, icon_y, max_icon_w, max_icon_h); - cairo_clip (cr); - cairo_new_path (cr); - gdk_cairo_set_source_pixbuf (cr, day_view->reminder_icon, icon_x, icon_y); - cairo_paint (cr); - cairo_close_path (cr); - cairo_restore (cr); - - icon_x += icon_x_inc; - icon_y += icon_y_inc; + draw_pixbuf (day_view->reminder_icon); } if (draw_recurrence_icon && fit_in_event ()) { - max_icon_w = item_x + item_w - icon_x - - E_DAY_VIEW_EVENT_BORDER_WIDTH; - max_icon_h = item_y + item_h - icon_y - - E_DAY_VIEW_EVENT_BORDER_HEIGHT; - - cairo_save (cr); - cairo_rectangle (cr, icon_x, icon_y, max_icon_w, max_icon_h); - cairo_clip (cr); - cairo_new_path (cr); - gdk_cairo_set_source_pixbuf (cr, day_view->recurrence_icon, icon_x, icon_y); - cairo_paint (cr); - cairo_close_path (cr); - cairo_restore (cr); - - icon_x += icon_x_inc; - icon_y += icon_y_inc; + draw_pixbuf (day_view->recurrence_icon); } if (draw_attach_icon && fit_in_event ()) { - max_icon_w = item_x + item_w - icon_x - - E_DAY_VIEW_EVENT_BORDER_WIDTH; - max_icon_h = item_y + item_h - icon_y - - E_DAY_VIEW_EVENT_BORDER_HEIGHT; - - cairo_save (cr); - cairo_rectangle (cr, icon_x, icon_y, max_icon_w, max_icon_h); - cairo_clip (cr); - cairo_new_path (cr); - gdk_cairo_set_source_pixbuf (cr, day_view->attach_icon, icon_x, icon_y); - cairo_paint (cr); - cairo_close_path (cr); - cairo_restore (cr); - icon_x += icon_x_inc; - icon_y += icon_y_inc; + draw_pixbuf (day_view->attach_icon); } if (draw_timezone_icon && fit_in_event ()) { - max_icon_w = item_x + item_w - icon_x - - E_DAY_VIEW_EVENT_BORDER_WIDTH; - max_icon_h = item_y + item_h - icon_y - - E_DAY_VIEW_EVENT_BORDER_HEIGHT; - - cairo_save (cr); - cairo_rectangle (cr, icon_x, icon_y, max_icon_w, max_icon_h); - cairo_clip (cr); - cairo_new_path (cr); - gdk_cairo_set_source_pixbuf (cr, day_view->timezone_icon, icon_x, icon_y); - cairo_paint (cr); - cairo_close_path (cr); - cairo_restore (cr); - - icon_x += icon_x_inc; - icon_y += icon_y_inc; + draw_pixbuf (day_view->timezone_icon); } if (draw_meeting_icon && fit_in_event ()) { - max_icon_w = item_x + item_w - icon_x - - E_DAY_VIEW_EVENT_BORDER_WIDTH; - max_icon_h = item_y + item_h - icon_y - - E_DAY_VIEW_EVENT_BORDER_HEIGHT; - - cairo_save (cr); - gdk_cairo_set_source_pixbuf (cr, day_view->meeting_icon, icon_x, icon_y); - cairo_paint (cr); - cairo_restore (cr); - - icon_x += icon_x_inc; - icon_y += icon_y_inc; + draw_pixbuf (day_view->meeting_icon); } /* draw categories icons */ - for (elem = categories_list; elem && fit_in_event (); elem = elem->next) { - gchar *category; - GdkPixmap *pixmap = NULL; - GdkBitmap *mask = NULL; - - category = (gchar *) elem->data; - if (!e_categories_config_get_icon_for (category, &pixmap, &mask)) - continue; - - max_icon_w = item_x + item_w - icon_x - - E_DAY_VIEW_EVENT_BORDER_WIDTH; - max_icon_h = item_y + item_h - icon_y - - E_DAY_VIEW_EVENT_BORDER_HEIGHT; - - gdk_gc_set_clip_origin (gc, icon_x, icon_y); - if (mask != NULL) - gdk_gc_set_clip_mask (gc, mask); - gdk_draw_drawable (drawable, gc, - pixmap, - 0, 0, icon_x, icon_y, - MIN (E_DAY_VIEW_ICON_WIDTH, - max_icon_w), - MIN (E_DAY_VIEW_ICON_HEIGHT, - max_icon_h)); - - g_object_unref (pixmap); - if (mask != NULL) - g_object_unref (mask); - - icon_x += icon_x_inc; - icon_y += icon_y_inc; + for (pixbufs = categories_pixbufs; + pixbufs && fit_in_event (); + pixbufs = pixbufs->next) { + GdkPixbuf *pixbuf = pixbufs->data; + + draw_pixbuf (pixbuf); } - #undef fit_in_event + #undef draw_pixbuf + #undef fit_in_event gdk_gc_set_clip_mask (gc, NULL); } /* free memory */ - e_cal_component_free_categories_list (categories_list); + g_slist_foreach (categories_pixbufs, (GFunc)g_object_unref, NULL); + g_slist_free (categories_pixbufs); } if (!short_event) diff --git a/calendar/gui/e-day-view-top-item.c b/calendar/gui/e-day-view-top-item.c index dd497e0f7b..51af20bbea 100644 --- a/calendar/gui/e-day-view-top-item.c +++ b/calendar/gui/e-day-view-top-item.c @@ -34,6 +34,7 @@ #include #include #include +#include "calendar-config.h" #include "e-calendar-view.h" #include "e-day-view-top-item.h" @@ -363,7 +364,6 @@ e_day_view_top_item_draw_long_event (EDayViewTopItem *dvtitem, { EDayView *day_view; EDayViewEvent *event; - GConfClient *gconf_client; GtkStyle *style; GdkGC *gc, *fg_gc; gint start_day, end_day; @@ -394,15 +394,8 @@ e_day_view_top_item_draw_long_event (EDayViewTopItem *dvtitem, cr = gdk_cairo_create (drawable); - gconf_client = gconf_client_get_default (); - alpha = gconf_client_get_float (gconf_client, - "/apps/evolution/calendar/display/events_transparency", - NULL); - - gradient = gconf_client_get_bool (gconf_client, - "/apps/evolution/calendar/display/events_gradient", - NULL); - g_object_unref (gconf_client); + gradient = calendar_config_get_display_events_gradient (); + alpha = calendar_config_get_display_events_alpha (); /* If the event is currently being dragged, don't draw it. It will be drawn in the special drag items. */ diff --git a/calendar/gui/e-day-view.c b/calendar/gui/e-day-view.c index 03b1b9cb51..ea77600889 100644 --- a/calendar/gui/e-day-view.c +++ b/calendar/gui/e-day-view.c @@ -4849,7 +4849,7 @@ e_day_view_reshape_long_event (EDayView *day_view, num_icons++; if (e_cal_component_has_attachments (comp)) num_icons++; - num_icons += cal_comp_util_get_n_icons (comp); + num_icons += cal_comp_util_get_n_icons (comp, NULL); } if (!event->canvas_item) { @@ -5019,7 +5019,7 @@ e_day_view_reshape_day_event (EDayView *day_view, if (e_cal_component_has_organizer (comp)) num_icons++; - num_icons += cal_comp_util_get_n_icons (comp); + num_icons += cal_comp_util_get_n_icons (comp, NULL); g_object_unref(comp); } diff --git a/calendar/gui/e-week-view-event-item.c b/calendar/gui/e-week-view-event-item.c index db67562c7c..0f79faa9e7 100644 --- a/calendar/gui/e-week-view-event-item.c +++ b/calendar/gui/e-week-view-event-item.c @@ -35,6 +35,7 @@ #include #include "e-calendar-view.h" +#include "calendar-config.h" #include "comp-util.h" #include @@ -64,13 +65,16 @@ static void e_week_view_event_item_draw_icons (EWeekViewEventItem *wveitem, gint icon_x, gint icon_y, gint x2, - gboolean right_align); + gboolean right_align, + GdkRegion *draw_region); static void e_week_view_event_item_draw_triangle (EWeekViewEventItem *wveitem, GdkDrawable *drawable, + GdkColor bg_color, gint x, gint y, gint w, - gint h); + gint h, + GdkRegion *draw_region); static double e_week_view_event_item_point (GnomeCanvasItem *item, double x, double y, @@ -216,6 +220,21 @@ e_week_view_event_item_update (GnomeCanvasItem *item, } } +static gboolean +can_draw_in_region (GdkRegion *draw_region, gint x, gint y, gint width, gint height) +{ + GdkRectangle rect; + + g_return_val_if_fail (draw_region != NULL, FALSE); + + rect.x = x; + rect.y = y; + rect.width = width; + rect.height = height; + + return gdk_region_rect_in (draw_region, &rect) != GDK_OVERLAP_RECTANGLE_OUT; +} + /* * DRAWING ROUTINES - functions to paint the canvas item. */ @@ -231,7 +250,6 @@ e_week_view_event_item_draw (GnomeCanvasItem *canvas_item, EWeekView *week_view; EWeekViewEvent *event; EWeekViewEventSpan *span; - GConfClient *gconf_client; GdkGC *gc; gint x1, y1, x2, y2, time_x, time_y; gint icon_x, icon_y, time_width, min_end_time_x, max_icon_x; @@ -248,6 +266,8 @@ e_week_view_event_item_draw (GnomeCanvasItem *canvas_item, gdouble radius, cx0, cy0, rect_height, rect_width; gboolean gradient; gdouble cc = 65535.0; + GdkRegion *draw_region; + GdkRectangle rect; #if 0 g_print ("In e_week_view_event_item_draw %i,%i %ix%i\n", @@ -258,23 +278,15 @@ e_week_view_event_item_draw (GnomeCanvasItem *canvas_item, week_view = E_WEEK_VIEW (GTK_WIDGET (canvas_item->canvas)->parent); g_return_if_fail (E_IS_WEEK_VIEW (week_view)); - cr = gdk_cairo_create (drawable); - if (wveitem->event_num == -1 || wveitem->span_num == -1) return; - g_return_if_fail(wveitem->event_num < week_view->events->len); - - gconf_client = gconf_client_get_default (); - gradient = gconf_client_get_bool (gconf_client, - "/apps/evolution/calendar/display/events_gradient", - NULL); - g_object_unref (gconf_client); + g_return_if_fail (wveitem->event_num < week_view->events->len); event = &g_array_index (week_view->events, EWeekViewEvent, wveitem->event_num); - g_return_if_fail(event->spans_index + wveitem->span_num < week_view->spans->len); + g_return_if_fail (event->spans_index + wveitem->span_num < week_view->spans->len); span = &g_array_index (week_view->spans, EWeekViewEventSpan, event->spans_index + wveitem->span_num); @@ -289,6 +301,20 @@ e_week_view_event_item_draw (GnomeCanvasItem *canvas_item, if (x1 == x2 || y1 == y2) return; + rect.x = 0; + rect.y = 0; + rect.width = width; + rect.height = height; + draw_region = gdk_region_rectangle (&rect); + + if (!can_draw_in_region (draw_region, x1, y1, x2 - x1, y2 - y1)) { + gdk_region_destroy (draw_region); + return; + } + + cr = gdk_cairo_create (drawable); + gradient = calendar_config_get_display_events_gradient (); + icon_x = 0; icon_y = y1 + E_WEEK_VIEW_EVENT_BORDER_HEIGHT + E_WEEK_VIEW_ICON_Y_PAD; @@ -305,37 +331,28 @@ e_week_view_event_item_draw (GnomeCanvasItem *canvas_item, time_width = e_week_view_get_time_string_width (week_view); - one_day_event = e_week_view_is_one_day_event (week_view, - wveitem->event_num); + one_day_event = e_week_view_is_one_day_event (week_view, wveitem->event_num); + + bg_color = week_view->colors[E_WEEK_VIEW_COLOR_EVENT_BACKGROUND]; + if (gdk_color_parse (e_cal_model_get_color_for_component (e_calendar_view_get_model (E_CALENDAR_VIEW (week_view)), event->comp_data), &bg_color)) { + GdkColormap *colormap; + + colormap = gtk_widget_get_colormap (GTK_WIDGET (week_view)); + if (!gdk_colormap_alloc_color (colormap, &bg_color, TRUE, TRUE)) { + bg_color = week_view->colors[E_WEEK_VIEW_COLOR_EVENT_BACKGROUND]; + } + } + + red = bg_color.red; + green = bg_color.green; + blue = bg_color.blue; + if (one_day_event) { time_x = x1 + E_WEEK_VIEW_EVENT_L_PAD + 1; rect_x = x1 + E_WEEK_VIEW_EVENT_L_PAD; rect_w = x2 - x1 - E_WEEK_VIEW_EVENT_L_PAD - E_WEEK_VIEW_EVENT_R_PAD + 1; - if (gdk_color_parse (e_cal_model_get_color_for_component (e_calendar_view_get_model (E_CALENDAR_VIEW (week_view)), - event->comp_data), - &bg_color)) { - GdkColormap *colormap; - - colormap = gtk_widget_get_colormap (GTK_WIDGET (week_view)); - if (gdk_colormap_alloc_color (colormap, &bg_color, TRUE, TRUE)) { - red = bg_color.red; - green = bg_color.green; - blue = bg_color.blue; - } else { - red = week_view->colors[E_WEEK_VIEW_COLOR_EVENT_BACKGROUND].red; - green = week_view->colors[E_WEEK_VIEW_COLOR_EVENT_BACKGROUND].green; - blue = week_view->colors[E_WEEK_VIEW_COLOR_EVENT_BACKGROUND].blue; - } - } else { - red = week_view->colors[E_WEEK_VIEW_COLOR_EVENT_BACKGROUND].green; - green = week_view->colors[E_WEEK_VIEW_COLOR_EVENT_BACKGROUND].green; - blue = week_view->colors[E_WEEK_VIEW_COLOR_EVENT_BACKGROUND].green; - } - /* Here we draw the border around the event*/ - cairo_save (cr); - cx0 = rect_x; cy0 = y1 + 1; rect_width = rect_w; @@ -343,17 +360,17 @@ e_week_view_event_item_draw (GnomeCanvasItem *canvas_item, radius = 12; - draw_curved_rectangle (cr, cx0, cy0, rect_width, rect_height, radius); - - cairo_set_line_width (cr, 2.0); - cairo_set_source_rgb (cr, red/cc, green/cc, blue/cc); - cairo_stroke (cr); - cairo_restore (cr); + if (can_draw_in_region (draw_region, cx0, cy0, rect_width, rect_height)) { + cairo_save (cr); + draw_curved_rectangle (cr, cx0, cy0, rect_width, rect_height, radius); + cairo_set_line_width (cr, 2.0); + cairo_set_source_rgb (cr, red/cc, green/cc, blue/cc); + cairo_stroke (cr); + cairo_restore (cr); + } /* Fill it in the Event */ - cairo_save (cr); - cx0 = rect_x + 1.5; cy0 = y1 + 2.75; rect_width = rect_w - 3.; @@ -361,24 +378,26 @@ e_week_view_event_item_draw (GnomeCanvasItem *canvas_item, radius = 8; - draw_curved_rectangle (cr, cx0, cy0, rect_width, rect_height, radius); - - if (gradient) { - pat = cairo_pattern_create_linear (rect_x + 2, y1 + 1, - rect_x + 2, y2 - 7.25); - cairo_pattern_add_color_stop_rgba (pat, 1, red/cc, green/cc, blue/cc, 0.8); - cairo_pattern_add_color_stop_rgba (pat, 0, red/cc, green/cc, blue/cc, 0.4); - cairo_set_source (cr, pat); - cairo_fill_preserve (cr); - cairo_pattern_destroy (pat); - } else { - cairo_set_source_rgba (cr, red/cc, green/cc, blue/cc, 0.8); - cairo_fill_preserve (cr); + if (can_draw_in_region (draw_region, cx0, cy0, rect_width, rect_height)) { + cairo_save (cr); + draw_curved_rectangle (cr, cx0, cy0, rect_width, rect_height, radius); + + if (gradient) { + pat = cairo_pattern_create_linear (rect_x + 2, y1 + 1, rect_x + 2, y2 - 7.25); + cairo_pattern_add_color_stop_rgba (pat, 1, red/cc, green/cc, blue/cc, 0.8); + cairo_pattern_add_color_stop_rgba (pat, 0, red/cc, green/cc, blue/cc, 0.4); + cairo_set_source (cr, pat); + cairo_fill_preserve (cr); + cairo_pattern_destroy (pat); + } else { + cairo_set_source_rgba (cr, red/cc, green/cc, blue/cc, 0.8); + cairo_fill_preserve (cr); + } + cairo_set_source_rgba (cr, red/cc, green/cc, blue/cc, 0.2); + cairo_set_line_width (cr, 0.5); + cairo_stroke (cr); + cairo_restore (cr); } - cairo_set_source_rgba (cr, red/cc, green/cc, blue/cc, 0.2); - cairo_set_line_width (cr, 0.5); - cairo_stroke (cr); - cairo_restore (cr); /* Draw the start and end times, as required. */ switch (week_view->time_format) { @@ -427,7 +446,7 @@ e_week_view_event_item_draw (GnomeCanvasItem *canvas_item, /* Draw the icons. */ e_week_view_event_item_draw_icons (wveitem, drawable, icon_x, icon_y, - x2, FALSE); + x2, FALSE, draw_region); } else { rect_x = x1 + E_WEEK_VIEW_EVENT_L_PAD; @@ -450,28 +469,7 @@ e_week_view_event_item_draw (GnomeCanvasItem *canvas_item, rect_w -= 2; } - cairo_save (cr); - if (gdk_color_parse (e_cal_model_get_color_for_component (e_calendar_view_get_model (E_CALENDAR_VIEW (week_view)), - event->comp_data), - &bg_color)) { - GdkColormap *colormap; - - colormap = gtk_widget_get_colormap (GTK_WIDGET (week_view)); - if (gdk_colormap_alloc_color (colormap, &bg_color, TRUE, TRUE)) { - red = bg_color.red; - green = bg_color.green; - blue = bg_color.blue; - } else { - red = week_view->colors[E_WEEK_VIEW_COLOR_EVENT_BACKGROUND].red; - green = week_view->colors[E_WEEK_VIEW_COLOR_EVENT_BACKGROUND].green; - blue = week_view->colors[E_WEEK_VIEW_COLOR_EVENT_BACKGROUND].blue; - } - } else { - red = week_view->colors[E_WEEK_VIEW_COLOR_EVENT_BACKGROUND].green; - green = week_view->colors[E_WEEK_VIEW_COLOR_EVENT_BACKGROUND].green; - blue = week_view->colors[E_WEEK_VIEW_COLOR_EVENT_BACKGROUND].green; - } - + /* Here we draw the border around the event */ cx0 = rect_x; @@ -481,17 +479,17 @@ e_week_view_event_item_draw (GnomeCanvasItem *canvas_item, radius = 12; - draw_curved_rectangle (cr, cx0, cy0, rect_width, rect_height, radius); - - cairo_set_line_width (cr, 2.0); - cairo_set_source_rgb (cr, red/cc, green/cc, blue/cc); - cairo_stroke (cr); - cairo_restore (cr); + if (can_draw_in_region (draw_region, cx0, cy0, rect_width, rect_height)) { + cairo_save (cr); + draw_curved_rectangle (cr, cx0, cy0, rect_width, rect_height, radius); + cairo_set_line_width (cr, 2.0); + cairo_set_source_rgb (cr, red/cc, green/cc, blue/cc); + cairo_stroke (cr); + cairo_restore (cr); + } /* Here we fill it in the event*/ - cairo_save (cr); - cx0 = rect_x + 1.5; cy0 = y1 + 2.75; rect_width = rect_w - 3.; @@ -499,28 +497,30 @@ e_week_view_event_item_draw (GnomeCanvasItem *canvas_item, radius = 8; - draw_curved_rectangle (cr, cx0, cy0, rect_width, rect_height, radius); - - if (gradient) { - pat = cairo_pattern_create_linear (rect_x + 2, y1 + 1, - rect_x + 2, y2 - 7.25); - cairo_pattern_add_color_stop_rgba (pat, 1, red/cc, green/cc, blue/cc, 0.8); - cairo_pattern_add_color_stop_rgba (pat, 0, red/cc, green/cc, blue/cc, 0.4); - cairo_set_source (cr, pat); - cairo_fill_preserve (cr); - cairo_pattern_destroy (pat); - } else { - cairo_set_source_rgba (cr, red/cc, green/cc, blue/cc, 0.8); - cairo_fill_preserve (cr); + if (can_draw_in_region (draw_region, cx0, cy0, rect_width, rect_height)) { + cairo_save (cr); + draw_curved_rectangle (cr, cx0, cy0, rect_width, rect_height, radius); + + if (gradient){ + pat = cairo_pattern_create_linear (rect_x + 2, y1 + 1, rect_x + 2, y2 - 7.25); + cairo_pattern_add_color_stop_rgba (pat, 1, red/cc, green/cc, blue/cc, 0.8); + cairo_pattern_add_color_stop_rgba (pat, 0, red/cc, green/cc, blue/cc, 0.4); + cairo_set_source (cr, pat); + cairo_fill_preserve (cr); + cairo_pattern_destroy (pat); + } else { + cairo_set_source_rgba (cr, red/cc, green/cc, blue/cc, 0.8); + cairo_fill_preserve (cr); + } + cairo_set_source_rgba (cr, red/cc, green/cc, blue/cc, 0.2); + cairo_set_line_width (cr, 0.5); + cairo_stroke (cr); + cairo_restore (cr); } - cairo_set_source_rgba (cr, red/cc, green/cc, blue/cc, 0.2); - cairo_set_line_width (cr, 0.5); - cairo_stroke (cr); - cairo_restore (cr); if (draw_start_triangle) { - e_week_view_event_item_draw_triangle (wveitem, drawable, x1 + E_WEEK_VIEW_EVENT_L_PAD + 2, y1, -3, y2 - y1 + 1); - } else { + e_week_view_event_item_draw_triangle (wveitem, drawable, bg_color, x1 + E_WEEK_VIEW_EVENT_L_PAD + 2, y1, -3, y2 - y1 + 1, draw_region); + } else if (can_draw_in_region (draw_region, rect_x, y1, 1, y2 - y1)) { cairo_save (cr); gdk_cairo_set_source_color (cr, &week_view->colors[E_WEEK_VIEW_COLOR_EVENT_BORDER]); cairo_set_line_width (cr, 0.7); @@ -531,8 +531,8 @@ e_week_view_event_item_draw (GnomeCanvasItem *canvas_item, } if (draw_end_triangle) { - e_week_view_event_item_draw_triangle (wveitem, drawable, x2 - E_WEEK_VIEW_EVENT_R_PAD - 2, y1, 3, y2 - y1 + 1); - } else { + e_week_view_event_item_draw_triangle (wveitem, drawable, bg_color, x2 - E_WEEK_VIEW_EVENT_R_PAD - 2, y1, 3, y2 - y1 + 1, draw_region); + } else if (can_draw_in_region (draw_region, rect_x2, y2, 1, 1)) { cairo_save (cr); gdk_cairo_set_source_color (cr, &week_view->colors[E_WEEK_VIEW_COLOR_EVENT_BORDER]); cairo_set_line_width (cr, 0.7); @@ -614,10 +614,12 @@ e_week_view_event_item_draw (GnomeCanvasItem *canvas_item, icon_x = span->text_item->x1 - E_WEEK_VIEW_ICON_R_PAD - x; e_week_view_event_item_draw_icons (wveitem, drawable, icon_x, icon_y, - max_icon_x, TRUE); + max_icon_x, TRUE, draw_region); } } cairo_destroy (cr); + + gdk_region_destroy (draw_region); } static void @@ -725,7 +727,8 @@ e_week_view_event_item_draw_icons (EWeekViewEventItem *wveitem, gint icon_x, gint icon_y, gint x2, - gboolean right_align) + gboolean right_align, + GdkRegion *draw_region) { EWeekView *week_view; EWeekViewEvent *event; @@ -735,7 +738,7 @@ e_week_view_event_item_draw_icons (EWeekViewEventItem *wveitem, gboolean draw_reminder_icon = FALSE, draw_recurrence_icon = FALSE; gboolean draw_timezone_icon = FALSE, draw_attach_icon = FALSE; gboolean draw_meeting_icon = FALSE; - GSList *categories_list, *elem; + GSList *categories_pixbufs = NULL, *pixbufs; cairo_t *cr; week_view = E_WEEK_VIEW (GTK_WIDGET (GNOME_CANVAS_ITEM (wveitem)->canvas)->parent); @@ -773,87 +776,61 @@ e_week_view_event_item_draw_icons (EWeekViewEventItem *wveitem, num_icons++; } - num_icons += cal_comp_util_get_n_icons (comp); - - e_cal_component_get_categories_list (comp, &categories_list); + num_icons += cal_comp_util_get_n_icons (comp, &categories_pixbufs); icon_x_inc = E_WEEK_VIEW_ICON_WIDTH + E_WEEK_VIEW_ICON_X_PAD; if (right_align) icon_x -= icon_x_inc * num_icons; - if (draw_reminder_icon && icon_x + E_WEEK_VIEW_ICON_WIDTH <= x2) { - cairo_save (cr); - gdk_cairo_set_source_pixbuf (cr, week_view->reminder_icon, icon_x, icon_y); - cairo_paint (cr); - cairo_restore (cr); - + #define draw_pixbuf(pf) \ + if (can_draw_in_region (draw_region, icon_x, icon_y, \ + E_WEEK_VIEW_ICON_WIDTH, E_WEEK_VIEW_ICON_HEIGHT)) { \ + cairo_save (cr); \ + gdk_cairo_set_source_pixbuf (cr, pf, icon_x, icon_y); \ + cairo_paint (cr); \ + cairo_restore (cr); \ + } \ + \ icon_x += icon_x_inc; + + + if (draw_reminder_icon && icon_x + E_WEEK_VIEW_ICON_WIDTH <= x2) { + draw_pixbuf (week_view->reminder_icon); } if (draw_attach_icon && icon_x + E_WEEK_VIEW_ICON_WIDTH <= x2) { - cairo_save (cr); - gdk_cairo_set_source_pixbuf (cr, week_view->attach_icon, icon_x, icon_y); - cairo_paint (cr); - cairo_restore (cr); - - icon_x += icon_x_inc; + draw_pixbuf (week_view->attach_icon); } if (draw_recurrence_icon && icon_x + E_WEEK_VIEW_ICON_WIDTH <= x2) { - cairo_save (cr); - gdk_cairo_set_source_pixbuf (cr, week_view->recurrence_icon, icon_x, icon_y); - cairo_paint (cr); - cairo_restore (cr); - icon_x += icon_x_inc; + draw_pixbuf (week_view->recurrence_icon); } if (draw_timezone_icon && icon_x + E_WEEK_VIEW_ICON_WIDTH <= x2) { - cairo_save (cr); - gdk_cairo_set_source_pixbuf (cr, week_view->timezone_icon, icon_x, icon_y); - cairo_paint (cr); - cairo_restore (cr); - icon_x += icon_x_inc; + draw_pixbuf (week_view->timezone_icon); } if (draw_meeting_icon && icon_x + E_WEEK_VIEW_ICON_WIDTH <= x2) { - cairo_save (cr); - gdk_cairo_set_source_pixbuf (cr, week_view->meeting_icon, icon_x, icon_y); - cairo_paint (cr); - cairo_restore (cr); - icon_x += icon_x_inc; + draw_pixbuf (week_view->meeting_icon); } /* draw categories icons */ - for (elem = categories_list; elem; elem = elem->next) { - gchar *category; - GdkPixmap *pixmap = NULL; - GdkBitmap *mask = NULL; - - category = (gchar *) elem->data; - if (!e_categories_config_get_icon_for (category, &pixmap, &mask)) - continue; - - if (icon_x + E_WEEK_VIEW_ICON_WIDTH <= x2) { - gdk_gc_set_clip_origin (gc, icon_x, icon_y); - if (mask != NULL) - gdk_gc_set_clip_mask (gc, mask); - gdk_draw_drawable (drawable, gc, - pixmap, - 0, 0, icon_x, icon_y, - E_WEEK_VIEW_ICON_WIDTH, - E_WEEK_VIEW_ICON_HEIGHT); - icon_x += icon_x_inc; - } - g_object_unref (pixmap); - if (mask != NULL) - g_object_unref (mask); + for (pixbufs = categories_pixbufs; + pixbufs; + pixbufs = pixbufs->next) { + GdkPixbuf *pixbuf = pixbufs->data; + + draw_pixbuf (pixbuf); } + #undef draw_pixbuf + + g_slist_foreach (categories_pixbufs, (GFunc)g_object_unref, NULL); + g_slist_free (categories_pixbufs); + cairo_destroy (cr); - e_cal_component_free_categories_list (categories_list); g_object_unref(comp); - gdk_gc_set_clip_mask (gc, NULL); } @@ -862,19 +839,23 @@ e_week_view_event_item_draw_icons (EWeekViewEventItem *wveitem, static void e_week_view_event_item_draw_triangle (EWeekViewEventItem *wveitem, GdkDrawable *drawable, + GdkColor bg_color, gint x, gint y, gint w, - gint h) + gint h, + GdkRegion *draw_region) { EWeekView *week_view; EWeekViewEvent *event; GdkGC *gc; - GdkColor bg_color; GdkPoint points[3]; gint c1, c2; cairo_t *cr; + if (!can_draw_in_region (draw_region, x, y, w, h)) + return; + week_view = E_WEEK_VIEW (GTK_WIDGET (GNOME_CANVAS_ITEM (wveitem)->canvas)->parent); event = &g_array_index (week_view->events, EWeekViewEvent, diff --git a/calendar/gui/e-week-view.c b/calendar/gui/e-week-view.c index 97034f8e01..6012901fcf 100644 --- a/calendar/gui/e-week-view.c +++ b/calendar/gui/e-week-view.c @@ -3028,7 +3028,7 @@ e_week_view_reshape_event_span (EWeekView *week_view, num_icons++; if (event->different_timezone) num_icons++; - num_icons += cal_comp_util_get_n_icons (comp); + num_icons += cal_comp_util_get_n_icons (comp, NULL); } /* Create the background canvas item if necessary. */ -- cgit v1.2.3