aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMilan Crha <mcrha@redhat.com>2009-07-30 17:22:59 +0800
committerMatthew Barnes <mbarnes@redhat.com>2009-08-11 04:31:35 +0800
commitaa8a700dd924a83e1dcd8eb374df777fb0a83b66 (patch)
treea6571a43052aafb50ddc927c3c7d03b092d4fabd
parent7eee013e97aa3d1d28112f5b25744035941ec23c (diff)
downloadgsoc2013-evolution-aa8a700dd924a83e1dcd8eb374df777fb0a83b66.tar
gsoc2013-evolution-aa8a700dd924a83e1dcd8eb374df777fb0a83b66.tar.gz
gsoc2013-evolution-aa8a700dd924a83e1dcd8eb374df777fb0a83b66.tar.bz2
gsoc2013-evolution-aa8a700dd924a83e1dcd8eb374df777fb0a83b66.tar.lz
gsoc2013-evolution-aa8a700dd924a83e1dcd8eb374df777fb0a83b66.tar.xz
gsoc2013-evolution-aa8a700dd924a83e1dcd8eb374df777fb0a83b66.tar.zst
gsoc2013-evolution-aa8a700dd924a83e1dcd8eb374df777fb0a83b66.zip
Bug #300567 - Calendar drawing optimizations
-rw-r--r--calendar/gui/calendar-config-keys.h4
-rw-r--r--calendar/gui/calendar-config.c21
-rw-r--r--calendar/gui/calendar-config.h4
-rw-r--r--calendar/gui/comp-util.c26
-rw-r--r--calendar/gui/comp-util.h2
-rw-r--r--calendar/gui/e-day-view-main-item.c448
-rw-r--r--calendar/gui/e-day-view-top-item.c13
-rw-r--r--calendar/gui/e-day-view.c4
-rw-r--r--calendar/gui/e-week-view-event-item.c331
-rw-r--r--calendar/gui/e-week-view.c2
-rw-r--r--e-util/e-categories-config.c72
-rw-r--r--e-util/e-categories-config.h4
12 files changed, 441 insertions, 490 deletions
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 <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 {
@@ -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 <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;
@@ -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 <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
@@ -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. */
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