diff options
author | Milan Crha <mcrha@redhat.com> | 2009-07-30 17:22:59 +0800 |
---|---|---|
committer | Milan Crha <mcrha@redhat.com> | 2009-07-30 17:22:59 +0800 |
commit | f093350819edeba7728af7f216d1429f8bcd5926 (patch) | |
tree | 0324e8ef276ec4d3875b29d174edaa7f39bfaf97 | |
parent | c485a5b5f41802bddb5cd17302b388ab5115aa22 (diff) | |
download | gsoc2013-evolution-f093350819edeba7728af7f216d1429f8bcd5926.tar gsoc2013-evolution-f093350819edeba7728af7f216d1429f8bcd5926.tar.gz gsoc2013-evolution-f093350819edeba7728af7f216d1429f8bcd5926.tar.bz2 gsoc2013-evolution-f093350819edeba7728af7f216d1429f8bcd5926.tar.lz gsoc2013-evolution-f093350819edeba7728af7f216d1429f8bcd5926.tar.xz gsoc2013-evolution-f093350819edeba7728af7f216d1429f8bcd5926.tar.zst gsoc2013-evolution-f093350819edeba7728af7f216d1429f8bcd5926.zip |
Bug #300567 - Calendar drawing optimizations
-rw-r--r-- | calendar/gui/calendar-config-keys.h | 4 | ||||
-rw-r--r-- | calendar/gui/calendar-config.c | 21 | ||||
-rw-r--r-- | calendar/gui/calendar-config.h | 4 | ||||
-rw-r--r-- | calendar/gui/comp-util.c | 26 | ||||
-rw-r--r-- | calendar/gui/comp-util.h | 2 | ||||
-rw-r--r-- | calendar/gui/e-day-view-main-item.c | 448 | ||||
-rw-r--r-- | calendar/gui/e-day-view-top-item.c | 13 | ||||
-rw-r--r-- | calendar/gui/e-day-view.c | 4 | ||||
-rw-r--r-- | calendar/gui/e-week-view-event-item.c | 331 | ||||
-rw-r--r-- | calendar/gui/e-week-view.c | 2 | ||||
-rw-r--r-- | e-util/e-categories-config.c | 72 | ||||
-rw-r--r-- | e-util/e-categories-config.h | 4 |
12 files changed, 441 insertions, 490 deletions
diff --git a/calendar/gui/calendar-config-keys.h b/calendar/gui/calendar-config-keys.h index deac5d595c..7210e83834 100644 --- a/calendar/gui/calendar-config-keys.h +++ b/calendar/gui/calendar-config-keys.h @@ -103,6 +103,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 86c771ff3e..2bc7357038 100644 --- a/calendar/gui/calendar-config.c +++ b/calendar/gui/calendar-config.c @@ -40,6 +40,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) @@ -58,6 +60,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 @@ -1736,3 +1741,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 bbee7e6da1..53d636faf5 100644 --- a/calendar/gui/calendar-config.h +++ b/calendar/gui/calendar-config.h @@ -280,4 +280,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 28091409ce..3e198518ea 100644 --- a/calendar/gui/e-day-view-main-item.c +++ b/calendar/gui/e-day-view-main-item.c @@ -35,6 +35,7 @@ #include "ea-calendar.h" #include "e-calendar-view.h" #include "comp-util.h" +#include "calendar-config.h" #include <libecal/e-cal-time-util.h> #include <e-calendar-view.h> @@ -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 { @@ -155,6 +156,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. */ @@ -175,6 +206,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); @@ -188,6 +221,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; @@ -208,13 +246,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 */ @@ -225,25 +263,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); @@ -272,20 +309,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); } @@ -349,20 +376,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_get_show_marcus_bains (day_view)) { @@ -404,6 +431,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 @@ -411,56 +439,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; } @@ -469,66 +465,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; } @@ -536,7 +528,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; } @@ -560,24 +551,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; @@ -588,7 +598,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); } } @@ -596,7 +606,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; @@ -608,7 +618,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; @@ -632,34 +641,12 @@ 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; - 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.*/ @@ -671,6 +658,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); @@ -1038,6 +1039,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; @@ -1073,8 +1076,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) { @@ -1087,137 +1089,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 09ed59e6e4..67f6d009e7 100644 --- a/calendar/gui/e-day-view-top-item.c +++ b/calendar/gui/e-day-view-top-item.c @@ -34,6 +34,7 @@ #include <libecal/e-cal-time-util.h> #include <libedataserver/e-data-server-util.h> #include <libedataserver/e-categories.h> +#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; @@ -391,15 +391,8 @@ e_day_view_top_item_draw_long_event (EDayViewTopItem *dvtitem, day_view = dvtitem->day_view; 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 209196ce81..1ed1a492bd 100644 --- a/calendar/gui/e-day-view.c +++ b/calendar/gui/e-day-view.c @@ -4457,7 +4457,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) { @@ -4627,7 +4627,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 66c1bed136..98963823b6 100644 --- a/calendar/gui/e-week-view-event-item.c +++ b/calendar/gui/e-week-view-event-item.c @@ -35,6 +35,7 @@ #include <gtk/gtk.h> #include "e-calendar-view.h" +#include "calendar-config.h" #include "comp-util.h" #include <text/e-text.h> @@ -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 @@ -722,7 +724,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; @@ -732,7 +735,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); @@ -770,87 +773,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); } @@ -859,19 +836,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 abf18ccd1d..f3c3100763 100644 --- a/calendar/gui/e-week-view.c +++ b/calendar/gui/e-week-view.c @@ -2817,7 +2817,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. */ diff --git a/e-util/e-categories-config.c b/e-util/e-categories-config.c index 14c8eae189..3dc35588b0 100644 --- a/e-util/e-categories-config.c +++ b/e-util/e-categories-config.c @@ -27,48 +27,64 @@ #include <libedataserverui/e-categories-dialog.h> #include "e-categories-config.h" +static GHashTable *pixbufs_cache = NULL; + +static void +categories_changed_cb (gpointer object, gpointer user_data) +{ + if (pixbufs_cache) + g_hash_table_remove_all (pixbufs_cache); +} + +static void +free_pixbuf_cb (gpointer ptr) +{ + GdkPixbuf *pixbuf = ptr; + + if (pixbuf) + g_object_unref (pixbuf); +} + /** * e_categories_config_get_icon_for: * @category: Category for which to get the icon. - * @icon: A pointer to where the pixmap will be returned. - * @mask: A pointer to where the mask will be returned. + * @pixbuf: A pointer to where the pixbuf will be returned. * - * Returns the icon (and associated mask) configured for the - * given category. + * Returns the icon configured for the given category. */ gboolean -e_categories_config_get_icon_for (const gchar *category, GdkPixmap **pixmap, GdkBitmap **mask) +e_categories_config_get_icon_for (const gchar *category, GdkPixbuf **pixbuf) { - gchar *icon_file; - GdkPixbuf *pixbuf; - GdkBitmap *tmp_mask; + const gchar *icon_file; - g_return_val_if_fail (pixmap != NULL, FALSE); + g_return_val_if_fail (pixbuf != NULL, FALSE); + g_return_val_if_fail (category != NULL, FALSE); - icon_file = (gchar *) e_categories_get_icon_file_for (category); - if (!icon_file) { - *pixmap = NULL; - if (mask != NULL) - *mask = NULL; - return FALSE; + if (!pixbufs_cache) { + pixbufs_cache = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, free_pixbuf_cb); + e_categories_register_change_listener (G_CALLBACK (categories_changed_cb), NULL); + } else { + gpointer key = NULL, value = NULL; + + if (g_hash_table_lookup_extended (pixbufs_cache, category, &key, &value)) { + *pixbuf = value; + if (*pixbuf) + g_object_ref (*pixbuf); + return *pixbuf != NULL; + } } - /* load the icon in our list */ - pixbuf = gdk_pixbuf_new_from_file (icon_file, NULL); - if (!pixbuf) { - *pixmap = NULL; - if (mask != NULL) - *mask = NULL; - return FALSE; + icon_file = e_categories_get_icon_file_for (category); + if (!icon_file) { + *pixbuf = NULL; + } else { + /* load the icon in our list */ + *pixbuf = gdk_pixbuf_new_from_file (icon_file, NULL); } - /* render the pixbuf to the pixmap and mask passed */ - gdk_pixbuf_render_pixmap_and_mask (pixbuf, pixmap, &tmp_mask, 1); - if (mask != NULL) - *mask = tmp_mask; + g_hash_table_insert (pixbufs_cache, g_strdup (category), *pixbuf == NULL ? NULL : g_object_ref (*pixbuf)); - g_object_unref (pixbuf); - return TRUE; + return *pixbuf != NULL; } /** diff --git a/e-util/e-categories-config.h b/e-util/e-categories-config.h index 81ae0161a0..82294ae6b9 100644 --- a/e-util/e-categories-config.h +++ b/e-util/e-categories-config.h @@ -30,9 +30,7 @@ G_BEGIN_DECLS -gboolean e_categories_config_get_icon_for (const gchar *category, - GdkPixmap **icon, - GdkBitmap **mask); +gboolean e_categories_config_get_icon_for (const gchar *category, GdkPixbuf **pixbuf); void e_categories_config_open_dialog_for_entry (GtkEntry *entry); G_END_DECLS |