diff options
-rw-r--r-- | calendar/ChangeLog | 29 | ||||
-rw-r--r-- | calendar/gui/apps_evolution_calendar.schemas.in.in | 12 | ||||
-rw-r--r-- | calendar/gui/e-calendar-view.c | 2 | ||||
-rw-r--r-- | calendar/gui/e-calendar-view.h | 2 | ||||
-rw-r--r-- | calendar/gui/e-day-view-main-item.c | 703 | ||||
-rw-r--r-- | calendar/gui/e-day-view-time-item.c | 224 | ||||
-rw-r--r-- | calendar/gui/e-day-view-top-item.c | 534 | ||||
-rw-r--r-- | calendar/gui/e-day-view.c | 55 | ||||
-rw-r--r-- | calendar/gui/e-week-view-event-item.c | 621 | ||||
-rw-r--r-- | calendar/gui/e-week-view-main-item.c | 206 | ||||
-rw-r--r-- | calendar/gui/e-week-view.c | 36 |
11 files changed, 2370 insertions, 54 deletions
diff --git a/calendar/ChangeLog b/calendar/ChangeLog index ed63eda81b..39381be95f 100644 --- a/calendar/ChangeLog +++ b/calendar/ChangeLog @@ -1,3 +1,32 @@ +2006-05-04 Rajeev Ramanathan <rajeevramanathan_2004@yahoo.co.in> + + Commited few pending cairo stuff. This adds a macro ENABLE_CAIRO to + disable cairo for slow performing machines. Also added a patch to + disable gradient and select foreground color based on the back ground + color. + + * gui/apps_evolution_calendar.schemas.in.in: + * gui/e-calendar-view.c: + * gui/e-calendar-view.h: + * gui/e-day-view-main-item.c: (e_day_view_main_item_draw), + (e_day_view_main_item_draw_events_in_vbars), + (e_day_view_main_item_draw_long_events_in_vbars), + (e_day_view_main_item_draw_day_events), + (e_day_view_main_item_draw_day_event): + * gui/e-day-view-time-item.c: (e_day_view_time_item_draw): + * gui/e-day-view-top-item.c: (e_day_view_top_item_draw), + (e_day_view_top_item_draw_long_event), + (e_day_view_top_item_draw_triangle): + * gui/e-day-view.c: (e_day_view_get_text_color), + (e_day_view_style_set), (e_day_view_reshape_long_event), + (e_day_view_reshape_day_event): + * gui/e-week-view-event-item.c: (e_week_view_event_item_draw), + (e_week_view_draw_time), (e_week_view_event_item_draw_icons), + (e_week_view_event_item_draw_triangle): + * gui/e-week-view-main-item.c: (e_week_view_main_item_draw_day): + * gui/e-week-view.c: (e_week_view_get_text_color), + (e_week_view_reshape_event_span): + 2006-05-04 Harish Krishnaswamy <kharish@novell.com> * gui/dialogs/event-page.glade: Set mnemonic to diff --git a/calendar/gui/apps_evolution_calendar.schemas.in.in b/calendar/gui/apps_evolution_calendar.schemas.in.in index 768c7c42a8..1952ddc472 100644 --- a/calendar/gui/apps_evolution_calendar.schemas.in.in +++ b/calendar/gui/apps_evolution_calendar.schemas.in.in @@ -329,6 +329,18 @@ </locale> </schema> + <schema> + <key>/schemas/apps/evolution/calendar/display/events_gradient</key> + <applyto>/apps/evolution/calendar/display/events_gradient</applyto> + <owner>evolution-calendar</owner> + <type>bool</type> + <default>true</default> + <locale name="C"> + <short>Event Gradient</short> + <long>Gradient of the events in calendar views.</long> + </locale> + </schema> + <!-- Tasks --> <schema> diff --git a/calendar/gui/e-calendar-view.c b/calendar/gui/e-calendar-view.c index f405cd80b4..f1c7c2d954 100644 --- a/calendar/gui/e-calendar-view.c +++ b/calendar/gui/e-calendar-view.c @@ -2261,6 +2261,7 @@ e_calendar_view_get_tooltips (ECalendarViewEventData *data) return FALSE; } +#ifdef ENABLE_CAIRO void draw_curved_rectangle (cairo_t *cr, double x0, double y0, double rect_width, double rect_height, @@ -2310,3 +2311,4 @@ draw_curved_rectangle (cairo_t *cr, double x0, double y0, } cairo_close_path (cr); } +#endif diff --git a/calendar/gui/e-calendar-view.h b/calendar/gui/e-calendar-view.h index bbf95da71e..2fae9350c8 100644 --- a/calendar/gui/e-calendar-view.h +++ b/calendar/gui/e-calendar-view.h @@ -29,6 +29,8 @@ #include "e-cal-model.h" #include "gnome-cal.h" +#define ENABLE_CAIRO + G_BEGIN_DECLS /* diff --git a/calendar/gui/e-day-view-main-item.c b/calendar/gui/e-day-view-main-item.c index cc6390ebd8..c4261ce948 100644 --- a/calendar/gui/e-day-view-main-item.c +++ b/calendar/gui/e-day-view-main-item.c @@ -153,8 +153,675 @@ e_day_view_main_item_update (GnomeCanvasItem *item, /* * DRAWING ROUTINES - functions to paint the canvas item. */ +#ifndef ENABLE_CAIRO +static void +e_day_view_main_item_draw (GnomeCanvasItem *canvas_item, GdkDrawable *drawable, + int x, int y, int width, int height) +{ + EDayViewMainItem *dvmitem; + EDayView *day_view; + GtkStyle *style; + GdkGC *gc; + gint row, row_y, grid_x1, grid_x2; + gint day, grid_y1, grid_y2; + gint work_day_start_y, work_day_end_y; + gint day_x, day_w, work_day; + gint start_row, end_row, rect_x, rect_y, rect_width, rect_height; + struct icaltimetype day_start_tt; + gint weekday; + +#if 0 + g_print ("In e_day_view_main_item_draw %i,%i %ix%i\n", + x, y, width, height); +#endif + dvmitem = E_DAY_VIEW_MAIN_ITEM (canvas_item); + day_view = dvmitem->day_view; + g_return_if_fail (day_view != NULL); + + style = gtk_widget_get_style (GTK_WIDGET (day_view)); + + /* Paint the background colors. */ + gc = day_view->main_gc; + 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; + work_day_end_y = e_day_view_convert_time_to_position (day_view, day_view->work_day_end_hour, day_view->work_day_end_minute) - y; + + for (day = 0; day < day_view->days_shown; day++) { + day_start_tt = icaltime_from_timet_with_zone (day_view->day_starts[day], FALSE, + e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); + weekday = icaltime_day_of_week (day_start_tt) - 1; + + work_day = day_view->working_days & (1 << weekday); + + day_x = day_view->day_offsets[day] - x; + day_w = day_view->day_widths[day]; + + if (work_day) { + gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_BG_NOT_WORKING]); + gdk_draw_rectangle (drawable, gc, TRUE, + day_x, 0 - y, + day_w, work_day_start_y - (0 - y)); + gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_BG_WORKING]); + gdk_draw_rectangle (drawable, gc, TRUE, + day_x, work_day_start_y, + day_w, work_day_end_y - work_day_start_y); + gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_BG_NOT_WORKING]); + gdk_draw_rectangle (drawable, gc, TRUE, + day_x, work_day_end_y, + day_w, height - work_day_end_y); + } else { + gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_BG_NOT_WORKING]); + gdk_draw_rectangle (drawable, gc, TRUE, + day_x, 0, + day_w, height); + } + } + + /* Paint the selection background. */ + if (day_view->selection_start_day != -1 + && !day_view->selection_in_top_canvas) { + for (day = day_view->selection_start_day; + day <= day_view->selection_end_day; + day++) { + if (day == day_view->selection_start_day + && day_view->selection_start_row != -1) + start_row = day_view->selection_start_row; + else + start_row = 0; + if (day == day_view->selection_end_day + && day_view->selection_end_row != -1) + end_row = day_view->selection_end_row; + else + end_row = day_view->rows - 1; + + rect_x = day_view->day_offsets[day] - x; + rect_width = day_view->day_widths[day]; + 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)) + gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_BG_SELECTED]); + else + gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_BG_SELECTED_UNFOCUSSED]); + gdk_draw_rectangle (drawable, gc, TRUE, + rect_x, rect_y, + rect_width, rect_height); + } + } + + /* Drawing the horizontal grid lines. */ + grid_x1 = day_view->day_offsets[0] - x; + grid_x2 = day_view->day_offsets[day_view->days_shown] - x; + + gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_BG_GRID]); + for (row = 0, row_y = 0 - y; + row < day_view->rows && row_y < height; + row++, row_y += day_view->row_height) { + if (row_y >= 0 && row_y < height) + gdk_draw_line (drawable, gc, + grid_x1, row_y, grid_x2, row_y); + } + + /* Draw the vertical bars down the left of each column. */ + grid_y1 = 0; + grid_y2 = height; + for (day = 0; day < day_view->days_shown; day++) { + grid_x1 = day_view->day_offsets[day] - x; + + /* Skip if it isn't visible. */ + if (grid_x1 >= width || grid_x1 + E_DAY_VIEW_BAR_WIDTH <= 0) + continue; + + gdk_draw_line (drawable, style->black_gc, + grid_x1, grid_y1, + grid_x1, grid_y2); + gdk_draw_line (drawable, style->black_gc, + grid_x1 + E_DAY_VIEW_BAR_WIDTH - 1, grid_y1, + grid_x1 + E_DAY_VIEW_BAR_WIDTH - 1, grid_y2); + gdk_draw_rectangle (drawable, style->white_gc, TRUE, + grid_x1 + 1, grid_y1, + E_DAY_VIEW_BAR_WIDTH - 2, grid_y2 - grid_y1); + + /* Fill in the bars when the user is busy. */ + e_day_view_main_item_draw_events_in_vbars (dvmitem, drawable, + x, y, + width, height, + day); + } + + /* 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); + + /* 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); + } + + + if (e_day_view_get_show_marcus_bains (day_view)) { + icaltimezone *zone; + struct icaltimetype time_now, day_start; + int marcus_bains_y; + GdkColor mb_color; + + gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_MARCUS_BAINS_LINE]); + + if (day_view->marcus_bains_day_view_color && gdk_color_parse (day_view->marcus_bains_day_view_color, &mb_color)) { + GdkColormap *colormap; + + colormap = gtk_widget_get_colormap (GTK_WIDGET (day_view)); + if (gdk_colormap_alloc_color (colormap, &mb_color, TRUE, TRUE)) { + gdk_gc_set_foreground (gc, &mb_color); + } + } + + zone = e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view)); + time_now = icaltime_current_time_with_zone (zone); + + for (day = 0; day < day_view->days_shown; day++) { + day_start = icaltime_from_timet_with_zone (day_view->day_starts[day], FALSE, zone); + + if ((day_start.year == time_now.year) && + (day_start.month == time_now.month) && + (day_start.day == time_now.day)) { + + grid_x1 = day_view->day_offsets[day] - x + E_DAY_VIEW_BAR_WIDTH; + grid_x2 = day_view->day_offsets[day + 1] - x - 1; + marcus_bains_y = (time_now.hour * 60 + time_now.minute) * day_view->row_height / day_view->mins_per_row - y; + gdk_draw_line (drawable, gc, grid_x1, marcus_bains_y, grid_x2, marcus_bains_y); + } + } + } + + +} +static void +e_day_view_main_item_draw_events_in_vbars (EDayViewMainItem *dvmitem, + GdkDrawable *drawable, + int x, int y, + int width, int height, + gint day) +{ + EDayView *day_view; + EDayViewEvent *event; + GdkGC *gc; + gint grid_x, event_num, bar_y, bar_h; + ECalComponentTransparency transparency; + + day_view = dvmitem->day_view; + + gc = day_view->main_gc; + gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_EVENT_VBAR]); + + 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); + + 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) + continue; + + /* 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) + continue; + + bar_y = event->start_minute * day_view->row_height / day_view->mins_per_row; + bar_h = event->end_minute * day_view->row_height / day_view->mins_per_row - bar_y; + bar_y -= y; + + /* Skip it if it isn't visible. */ + if (bar_y >= height || bar_y + bar_h <= 0) + continue; + + gdk_draw_rectangle (drawable, gc, TRUE, + grid_x, bar_y, + E_DAY_VIEW_BAR_WIDTH - 2, bar_h); + + g_object_unref (comp); + } +} + + +static void +e_day_view_main_item_draw_long_events_in_vbars (EDayViewMainItem *dvmitem, + GdkDrawable *drawable, + int x, int y, + int width, int height) +{ + EDayView *day_view; + EDayViewEvent *event; + gint event_num, start_day, end_day, day, bar_y1, bar_y2, grid_x; + GdkGC *gc; + ECalComponentTransparency transparency; + + day_view = dvmitem->day_view; + + gc = day_view->main_gc; + gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_EVENT_VBAR]); + + 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); + + 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) + continue; + + if (!e_day_view_find_long_event_days (event, + day_view->days_shown, + day_view->day_starts, + &start_day, &end_day)) + continue; + + for (day = start_day; day <= end_day; day++) { + grid_x = day_view->day_offsets[day] + 1 - x; + + /* Skip if it isn't visible. */ + if (grid_x >= width + || grid_x + E_DAY_VIEW_BAR_WIDTH <= 0) + continue; + + if (event->start <= day_view->day_starts[day]) { + bar_y1 = 0; + } else { + bar_y1 = event->start_minute * day_view->row_height / day_view->mins_per_row - y; + } + + if (event->end >= day_view->day_starts[day + 1]) { + bar_y2 = height; + } else { + 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) { + gdk_draw_rectangle (drawable, gc, TRUE, + grid_x, bar_y1, + E_DAY_VIEW_BAR_WIDTH - 2, + bar_y2 - bar_y1); + } + } + + + g_object_unref (comp); + } +} + + +static void +e_day_view_main_item_draw_day_events (EDayViewMainItem *dvmitem, + GdkDrawable *drawable, + int x, int y, int width, int height, + gint day) +{ + EDayView *day_view; + gint event_num; + + day_view = dvmitem->day_view; + + for (event_num = 0; event_num < day_view->events[day]->len; + event_num++) { + e_day_view_main_item_draw_day_event (dvmitem, drawable, + x, y, width, height, + day, event_num); + } +} + static void +e_day_view_main_item_draw_day_event (EDayViewMainItem *dvmitem, + GdkDrawable *drawable, + int x, int y, int width, int height, + gint day, gint event_num) +{ + EDayView *day_view; + EDayViewEvent *event; + gint item_x, item_y, item_w, item_h, bar_y1, bar_y2; + GdkGC *gc; + GdkColor bg_color; + ECalComponent *comp; + gint num_icons, icon_x, icon_y, icon_x_inc, icon_y_inc; + 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; + + day_view = dvmitem->day_view; + + /* 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) + return; + + gc = day_view->main_gc; + + /* Get the position of the event. If it is not shown skip it.*/ + if (!e_day_view_get_event_position (day_view, day, event_num, + &item_x, &item_y, + &item_w, &item_h)) + return; + + item_x -= x; + item_y -= y; + + event = &g_array_index (day_view->events[day], EDayViewEvent, + event_num); + + /* Fill in the event background. Note that for events in the first + column of the day, we might not want to paint over the vertical bar, + since that is used for multiple events. But then you can't see + where the event in the first column finishes. */ + + gdk_gc_set_foreground (gc, &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_gc_set_foreground (gc, &bg_color); + } + +#if 1 + if (event->start_row_or_col == 0) + gdk_draw_rectangle (drawable, gc, TRUE, + item_x + E_DAY_VIEW_BAR_WIDTH, item_y + 1, + MAX (item_w - E_DAY_VIEW_BAR_WIDTH - 1, 0), + item_h - 2); + else +#endif + gdk_draw_rectangle (drawable, gc, TRUE, + item_x + 1, item_y + 1, + MAX (item_w - 2, 0), item_h - 2); + + gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_EVENT_VBAR]); + + /* Draw the right edge of the vertical bar. */ + gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BORDER]); + gdk_draw_line (drawable, gc, + item_x + E_DAY_VIEW_BAR_WIDTH - 1, + item_y + 1, + item_x + E_DAY_VIEW_BAR_WIDTH - 1, + item_y + item_h - 2); + + /* Draw the vertical colored bar showing when the appointment + begins & ends. */ + bar_y1 = event->start_minute * day_view->row_height / day_view->mins_per_row - y; + bar_y2 = event->end_minute * day_view->row_height / day_view->mins_per_row - y; + + /* When an item is being resized, we fill the bar up to the new row. */ + if (day_view->resize_drag_pos != E_CALENDAR_VIEW_POS_NONE + && day_view->resize_event_day == day + && day_view->resize_event_num == event_num) { + if (day_view->resize_drag_pos == E_CALENDAR_VIEW_POS_TOP_EDGE) + bar_y1 = item_y + 1; + else if (day_view->resize_drag_pos == E_CALENDAR_VIEW_POS_BOTTOM_EDGE) + bar_y2 = item_y + item_h - 1; + } + + comp = e_cal_component_new (); + e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp)); + + /* Only fill it in if the event isn't TRANSPARENT. */ + e_cal_component_get_transparency (comp, &transparency); + if (transparency != E_CAL_COMPONENT_TRANSP_TRANSPARENT) { + gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_EVENT_VBAR]); + gdk_draw_rectangle (drawable, gc, TRUE, + item_x + 1, bar_y1, + E_DAY_VIEW_BAR_WIDTH - 2, bar_y2 - bar_y1); + } + + /* Draw the box around the entire event. Do this after drawing + the colored bar so we don't have to worry about being 1 + pixel out. */ + gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BORDER]); + gdk_draw_rectangle (drawable, gc, FALSE, + item_x, item_y, MAX (item_w - 1, 0), item_h - 1); + gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_EVENT_VBAR]); + +#if 0 + /* Draw the horizontal bars above and beneath the event if it + is currently being edited. */ + if (day_view->editing_event_day == day + && day_view->editing_event_num == event_num) { + gdk_draw_rectangle (drawable, gc, TRUE, + item_x, + item_y - E_DAY_VIEW_BAR_HEIGHT, + item_w, + E_DAY_VIEW_BAR_HEIGHT); + gdk_draw_rectangle (drawable, gc, TRUE, + item_x, item_y + item_h, + item_w, E_DAY_VIEW_BAR_HEIGHT); + } +#endif + + /* Draw the reminder & recurrence icons, if needed. */ + num_icons = 0; + draw_reminder_icon = FALSE; + draw_recurrence_icon = FALSE; + draw_timezone_icon = FALSE; + draw_meeting_icon = FALSE; + draw_attach_icon = FALSE; + icon_x = item_x + E_DAY_VIEW_BAR_WIDTH + E_DAY_VIEW_ICON_X_PAD; + icon_y = item_y + E_DAY_VIEW_EVENT_BORDER_HEIGHT + + E_DAY_VIEW_ICON_Y_PAD; + + if (e_cal_component_has_alarms (comp)) { + draw_reminder_icon = TRUE; + num_icons++; + } + + if (e_cal_component_has_recurrences (comp) || e_cal_component_is_instance (comp)) { + draw_recurrence_icon = TRUE; + num_icons++; + } + if (e_cal_component_has_attachments (comp)) { + draw_attach_icon = TRUE; + num_icons++; + } + /* If the DTSTART or DTEND are in a different timezone to our current + timezone, we display the timezone icon. */ + if (event->different_timezone) { + draw_timezone_icon = TRUE; + num_icons++; + } + + if (e_cal_component_has_organizer (comp)) { + draw_meeting_icon = TRUE; + num_icons++; + } + + e_cal_component_get_categories_list (comp, &categories_list); + for (elem = categories_list; elem; elem = elem->next) { + char *category; + GdkPixmap *pixmap = NULL; + GdkBitmap *mask = NULL; + + category = (char *) elem->data; + if (e_categories_config_get_icon_for (category, &pixmap, &mask)) + num_icons++; + } + + if (num_icons != 0) { + if (item_h >= (E_DAY_VIEW_ICON_HEIGHT + E_DAY_VIEW_ICON_Y_PAD) + * num_icons) { + icon_x_inc = 0; + icon_y_inc = E_DAY_VIEW_ICON_HEIGHT + + E_DAY_VIEW_ICON_Y_PAD; + } else { + icon_x_inc = E_DAY_VIEW_ICON_WIDTH + + E_DAY_VIEW_ICON_X_PAD; + icon_y_inc = 0; + } + + if (draw_reminder_icon) { + 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_mask (gc, NULL); + gdk_draw_pixbuf (drawable, gc, + day_view->reminder_icon, + 0, 0, icon_x, icon_y, + MIN (E_DAY_VIEW_ICON_WIDTH, + max_icon_w), + MIN (E_DAY_VIEW_ICON_HEIGHT, + max_icon_h), + GDK_RGB_DITHER_NORMAL, + 0, 0); + icon_x += icon_x_inc; + icon_y += icon_y_inc; + } + + if (draw_recurrence_icon) { + 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_mask (gc, NULL); + gdk_draw_pixbuf (drawable, gc, + day_view->recurrence_icon, + 0, 0, icon_x, icon_y, + MIN (E_DAY_VIEW_ICON_WIDTH, + max_icon_w), + MIN (E_DAY_VIEW_ICON_HEIGHT, + max_icon_h), + GDK_RGB_DITHER_NORMAL, + 0, 0); + icon_x += icon_x_inc; + icon_y += icon_y_inc; + } + if (draw_attach_icon) { + 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_mask (gc, NULL); + gdk_draw_pixbuf (drawable, gc, + day_view->attach_icon, + 0, 0, icon_x, icon_y, + MIN (E_DAY_VIEW_ICON_WIDTH, + max_icon_w), + MIN (E_DAY_VIEW_ICON_HEIGHT, + max_icon_h), + GDK_RGB_DITHER_NORMAL, + 0, 0); + icon_x += icon_x_inc; + icon_y += icon_y_inc; + } + if (draw_timezone_icon) { + 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_mask (gc, NULL); + gdk_draw_pixbuf (drawable, gc, + day_view->timezone_icon, + 0, 0, icon_x, icon_y, + MIN (E_DAY_VIEW_ICON_WIDTH, + max_icon_w), + MIN (E_DAY_VIEW_ICON_HEIGHT, + max_icon_h), + GDK_RGB_DITHER_NORMAL, + 0, 0); + icon_x += icon_x_inc; + icon_y += icon_y_inc; + } + + + if (draw_meeting_icon) { + 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_mask (gc, NULL); + gdk_draw_pixbuf (drawable, gc, + day_view->meeting_icon, + 0, 0, icon_x, icon_y, + MIN (E_DAY_VIEW_ICON_WIDTH, + max_icon_w), + MIN (E_DAY_VIEW_ICON_HEIGHT, + max_icon_h), + GDK_RGB_DITHER_NORMAL, + 0, 0); + icon_x += icon_x_inc; + icon_y += icon_y_inc; + } + + /* draw categories icons */ + for (elem = categories_list; elem; elem = elem->next) { + char *category; + GdkPixmap *pixmap = NULL; + GdkBitmap *mask = NULL; + + category = (char *) 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_pixmap (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)); + + gdk_pixmap_unref (pixmap); + if (mask != NULL) + gdk_bitmap_unref (mask); + + icon_x += icon_x_inc; + icon_y += icon_y_inc; + } + + gdk_gc_set_clip_mask (gc, NULL); + } + + /* free memory */ + e_cal_component_free_categories_list (categories_list); + g_object_unref (comp); +} +#endif + +#ifdef ENABLE_CAIRO +static void e_day_view_main_item_draw (GnomeCanvasItem *canvas_item, GdkDrawable *drawable, int x, int y, int width, int height) { @@ -172,10 +839,12 @@ e_day_view_main_item_draw (GnomeCanvasItem *canvas_item, GdkDrawable *drawable, cairo_t *cr; cr = gdk_cairo_create (drawable); + #if 0 g_print ("In e_day_view_main_item_draw %i,%i %ix%i\n", x, y, width, height); #endif + dvmitem = E_DAY_VIEW_MAIN_ITEM (canvas_item); day_view = dvmitem->day_view; g_return_if_fail (day_view != NULL); @@ -221,7 +890,6 @@ e_day_view_main_item_draw (GnomeCanvasItem *canvas_item, GdkDrawable *drawable, height - work_day_end_y); cairo_fill (cr); cairo_restore (cr); - } else { cairo_save (cr); gdk_cairo_set_source_color (cr, &day_view->colors[E_DAY_VIEW_COLOR_BG_NOT_WORKING]); @@ -303,7 +971,6 @@ e_day_view_main_item_draw (GnomeCanvasItem *canvas_item, GdkDrawable *drawable, /* Skip if it isn't visible. */ if (grid_x1 >= width || grid_x1 + E_DAY_VIEW_BAR_WIDTH <= 0) continue; - cairo_save (cr); gdk_cairo_set_source_color (cr, @@ -313,7 +980,7 @@ e_day_view_main_item_draw (GnomeCanvasItem *canvas_item, GdkDrawable *drawable, cairo_stroke (cr); gdk_cairo_set_source_color (cr, - &day_view->colors[E_DAY_VIEW_COLOR_BG_GRID]); + &day_view->colors[E_DAY_VIEW_COLOR_BG_GRID]); cairo_move_to (cr, grid_x1 + E_DAY_VIEW_BAR_WIDTH - 1, grid_y1); cairo_line_to (cr, grid_x1 + E_DAY_VIEW_BAR_WIDTH - 1, grid_y2); @@ -328,7 +995,6 @@ e_day_view_main_item_draw (GnomeCanvasItem *canvas_item, GdkDrawable *drawable, cairo_restore (cr); - /* Fill in the bars when the user is busy. */ e_day_view_main_item_draw_events_in_vbars (dvmitem, drawable, x, y, @@ -367,7 +1033,6 @@ e_day_view_main_item_draw (GnomeCanvasItem *canvas_item, GdkDrawable *drawable, if (gdk_colormap_alloc_color (colormap, &mb_color, TRUE, TRUE)) gdk_cairo_set_source_color (cr, &mb_color); } - zone = e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view)); time_now = icaltime_current_time_with_zone (zone); @@ -410,8 +1075,6 @@ e_day_view_main_item_draw_events_in_vbars (EDayViewMainItem *dvmitem, cr = gdk_cairo_create (drawable); cairo_save (cr); -// gdk_cairo_set_source_color (cr, -// &day_view->colors[E_DAY_VIEW_COLOR_EVENT_VBAR]); gdk_cairo_set_source_color (cr, &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BACKGROUND]); @@ -598,6 +1261,7 @@ e_day_view_main_item_draw_day_event (EDayViewMainItem *dvmitem, gint i; gdouble radius, x0, y0, rect_height, rect_width; gfloat alpha; + gboolean gradient; gdouble cc = 65535.0; day_view = dvmitem->day_view; @@ -611,6 +1275,10 @@ e_day_view_main_item_draw_day_event (EDayViewMainItem *dvmitem, "/apps/evolution/calendar/display/events_transparency", NULL); + gradient = gconf_client_get_bool (gconf_client_get_default (), + "/apps/evolution/calendar/display/events_gradient", + NULL); + /* 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 @@ -697,13 +1365,18 @@ e_day_view_main_item_draw_day_event (EDayViewMainItem *dvmitem, draw_curved_rectangle (cr, x0, y0, rect_width, rect_height, radius); - pat = cairo_pattern_create_linear (item_x + E_DAY_VIEW_BAR_WIDTH + 1.75, item_y + 2.75, - item_x + E_DAY_VIEW_BAR_WIDTH + 1.75, item_y + item_h - 2.75); - 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); + if (gradient) { + pat = cairo_pattern_create_linear (item_x + E_DAY_VIEW_BAR_WIDTH + 1.75, item_y + 2.75, + item_x + E_DAY_VIEW_BAR_WIDTH + 1.75, item_y + item_h - 2.75); + 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); @@ -965,7 +1638,7 @@ e_day_view_main_item_draw_day_event (EDayViewMainItem *dvmitem, g_object_unref (comp); cairo_destroy (cr); } - +#endif /* This is supposed to return the nearest item to the point and the distance. Since we are the only item we just return ourself and 0 for the distance. diff --git a/calendar/gui/e-day-view-time-item.c b/calendar/gui/e-day-view-time-item.c index 015356af6f..2bd1bc9e41 100644 --- a/calendar/gui/e-day-view-time-item.c +++ b/calendar/gui/e-day-view-time-item.c @@ -237,7 +237,229 @@ e_day_view_time_item_get_column_width (EDayViewTimeItem *dvtmitem) /* * DRAWING ROUTINES - functions to paint the canvas item. */ +#ifndef ENABLE_CAIRO +static void +e_day_view_time_item_draw (GnomeCanvasItem *canvas_item, + GdkDrawable *drawable, + int x, + int y, + int width, + int height) +{ + EDayView *day_view; + EDayViewTimeItem *dvtmitem; + GtkStyle *style; + GdkGC *gc, *fg_gc, *dark_gc; + gchar buffer[64], *suffix; + gint hour, display_hour, minute, row; + gint row_y, start_y, large_hour_y_offset, small_font_y_offset; + gint long_line_x1, long_line_x2, short_line_x1; + gint large_hour_x2, minute_x2; + gint hour_width, minute_width, suffix_width; + gint max_suffix_width, max_minute_or_suffix_width; + PangoLayout *layout; + PangoContext *context; + PangoFontDescription *small_font_desc; + PangoFontMetrics *large_font_metrics, *small_font_metrics; + + dvtmitem = E_DAY_VIEW_TIME_ITEM (canvas_item); + day_view = dvtmitem->day_view; + g_return_if_fail (day_view != NULL); + + style = gtk_widget_get_style (GTK_WIDGET (day_view)); + small_font_desc = style->font_desc; + + context = gtk_widget_get_pango_context (GTK_WIDGET (day_view)); + large_font_metrics = pango_context_get_metrics (context, day_view->large_font_desc, + pango_context_get_language (context)); + small_font_metrics = pango_context_get_metrics (context, small_font_desc, + pango_context_get_language (context)); + + gc = day_view->main_gc; + fg_gc = style->fg_gc[GTK_STATE_NORMAL]; + dark_gc = style->dark_gc[GTK_STATE_NORMAL]; + /* The start and end of the long horizontal line between hours. */ + long_line_x1 = E_DVTMI_TIME_GRID_X_PAD - x; + long_line_x2 = dvtmitem->column_width - E_DVTMI_TIME_GRID_X_PAD - x; + + if (day_view->mins_per_row == 60) { + /* The right edge of the complete time string in 60-min + divisions, e.g. "14:00" or "2 pm". */ + minute_x2 = long_line_x2 - E_DVTMI_60_MIN_X_PAD; + + /* These aren't used for 60-minute divisions, but we initialize + them to keep gcc happy. */ + short_line_x1 = 0; + large_hour_x2 = 0; + } else { + max_suffix_width = MAX (day_view->am_string_width, + day_view->pm_string_width); + + max_minute_or_suffix_width = MAX (max_suffix_width, + day_view->max_minute_width); + + /* The start of the short horizontal line between the periods + within each hour. */ + short_line_x1 = long_line_x2 - E_DVTMI_MIN_X_PAD * 2 + - max_minute_or_suffix_width; + + /* The right edge of the large hour string. */ + large_hour_x2 = short_line_x1 - E_DVTMI_HOUR_R_PAD; + + /* The right edge of the minute part of the time. */ + minute_x2 = long_line_x2 - E_DVTMI_MIN_X_PAD; + } + + /* Start with the first hour & minute shown in the EDayView. */ + hour = day_view->first_hour_shown; + minute = day_view->first_minute_shown; + + /* The offset of the large hour string from the top of the row. */ + large_hour_y_offset = E_DVTMI_LARGE_HOUR_Y_PAD; + + /* The offset of the small time/minute string from top of row. */ + small_font_y_offset = E_DVTMI_SMALL_FONT_Y_PAD; + + /* Calculate the minimum y position of the first row we need to draw. + This is normally one row height above the 0 position, but if we + are using the large font we may have to go back a bit further. */ + start_y = 0 - MAX (day_view->row_height, + (pango_font_metrics_get_ascent (large_font_metrics) + + pango_font_metrics_get_descent (large_font_metrics)) / PANGO_SCALE + + E_DVTMI_LARGE_HOUR_Y_PAD); + + /* Draw the Marcus Bains Line first, so it appears under other elements. */ + if (e_day_view_get_show_marcus_bains (day_view)) { + struct icaltimetype time_now; + int marcus_bains_y; + GdkColor mb_color; + + gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_MARCUS_BAINS_LINE]); + + if (day_view->marcus_bains_time_bar_color && gdk_color_parse (day_view->marcus_bains_time_bar_color, &mb_color)) { + GdkColormap *colormap; + + colormap = gtk_widget_get_colormap (GTK_WIDGET (day_view)); + if (gdk_colormap_alloc_color (colormap, &mb_color, TRUE, TRUE)) { + gdk_gc_set_foreground (gc, &mb_color); + } + } + + time_now = icaltime_current_time_with_zone (e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); + marcus_bains_y = (time_now.hour * 60 + time_now.minute) * day_view->row_height / day_view->mins_per_row - y; + gdk_draw_line (drawable, gc, + long_line_x1, marcus_bains_y, + long_line_x2, marcus_bains_y); + } + + /* Step through each row, drawing the times and the horizontal lines + between them. */ + for (row = 0, row_y = 0 - y; + row < day_view->rows && row_y < height; + row++, row_y += day_view->row_height) { + + /* If the row is above the first row we want to draw just + increment the time and skip to the next row. */ + if (row_y < start_y) { + e_day_view_time_item_increment_time (&hour, &minute, + day_view->mins_per_row); + continue; + } + + /* Calculate the actual hour number to display. For 12-hour + format we convert 0-23 to 12-11am/12-11pm. */ + e_day_view_convert_time_to_display (day_view, hour, + &display_hour, + &suffix, &suffix_width); + + if (day_view->mins_per_row == 60) { + /* 60 minute intervals - draw a long horizontal line + between hours and display as one long string, + e.g. "14:00" or "2 pm". */ + gdk_draw_line (drawable, dark_gc, + long_line_x1, row_y, + long_line_x2, row_y); + + if (e_calendar_view_get_use_24_hour_format (E_CALENDAR_VIEW (day_view))) { + g_snprintf (buffer, sizeof (buffer), "%i:%02i", + display_hour, minute); + } else { + g_snprintf (buffer, sizeof (buffer), "%i %s", + display_hour, suffix); + } + + layout = gtk_widget_create_pango_layout (GTK_WIDGET (day_view), buffer); + pango_layout_get_pixel_size (layout, &minute_width, NULL); + gdk_draw_layout (drawable, fg_gc, + minute_x2 - minute_width, + row_y + small_font_y_offset, + layout); + g_object_unref (layout); + } else { + /* 5/10/15/30 minute intervals. */ + + if (minute == 0) { + /* On the hour - draw a long horizontal line + before the hour and display the hour in the + large font. */ + gdk_draw_line (drawable, dark_gc, + long_line_x1, row_y, + long_line_x2, row_y); + + g_snprintf (buffer, sizeof (buffer), "%i", + display_hour); + + layout = gtk_widget_create_pango_layout (GTK_WIDGET (day_view), buffer); + pango_layout_set_font_description (layout, day_view->large_font_desc); + pango_layout_get_pixel_size (layout, &hour_width, NULL); + gdk_draw_layout (drawable, fg_gc, + large_hour_x2 - hour_width, + row_y + large_hour_y_offset, + layout); + g_object_unref (layout); + } else { + /* Within the hour - draw a short line before + the time. */ + gdk_draw_line (drawable, dark_gc, + short_line_x1, row_y, + long_line_x2, row_y); + } + + /* Normally we display the minute in each + interval, but when using 30-minute intervals + we don't display the '30'. */ + if (day_view->mins_per_row != 30 || minute != 30) { + /* In 12-hour format we display 'am' or 'pm' + instead of '00'. */ + if (minute == 0 + && !e_calendar_view_get_use_24_hour_format (E_CALENDAR_VIEW (day_view))) { + strcpy (buffer, suffix); + } else { + g_snprintf (buffer, sizeof (buffer), + "%02i", minute); + } + + layout = gtk_widget_create_pango_layout (GTK_WIDGET (day_view), buffer); + pango_layout_get_pixel_size (layout, &minute_width, NULL); + gdk_draw_layout (drawable, fg_gc, + minute_x2 - minute_width, + row_y + small_font_y_offset, + layout); + g_object_unref (layout); + } + } + + e_day_view_time_item_increment_time (&hour, &minute, + day_view->mins_per_row); + } + + pango_font_metrics_unref (large_font_metrics); + pango_font_metrics_unref (small_font_metrics); +} +#endif + +#ifdef ENABLE_CAIRO static void e_day_view_time_item_draw (GnomeCanvasItem *canvas_item, GdkDrawable *drawable, @@ -490,7 +712,7 @@ e_day_view_time_item_draw (GnomeCanvasItem *canvas_item, pango_font_metrics_unref (small_font_metrics); cairo_destroy (cr); } - +#endif /* Increment the time by the 5/10/15/30/60 minute interval. Note that mins_per_row is never > 60, so we never have to diff --git a/calendar/gui/e-day-view-top-item.c b/calendar/gui/e-day-view-top-item.c index 77138eedf1..e2818eaf2f 100644 --- a/calendar/gui/e-day-view-top-item.c +++ b/calendar/gui/e-day-view-top-item.c @@ -147,7 +147,512 @@ e_day_view_top_item_update (GnomeCanvasItem *item, /* * DRAWING ROUTINES - functions to paint the canvas item. */ +#ifndef ENABLE_CAIRO +static void +e_day_view_top_item_draw (GnomeCanvasItem *canvas_item, + GdkDrawable *drawable, + int x, + int y, + int width, + int height) +{ + EDayViewTopItem *dvtitem; + EDayView *day_view; + GtkStyle *style; + GdkGC *gc, *fg_gc, *bg_gc, *light_gc, *dark_gc; + gchar buffer[128]; + GdkRectangle clip_rect; + gint canvas_width, canvas_height, left_edge, day, date_width, date_x; + gint item_height, event_num; + PangoLayout *layout; + +#if 0 + g_print ("In e_day_view_top_item_draw %i,%i %ix%i\n", + x, y, width, height); +#endif + dvtitem = E_DAY_VIEW_TOP_ITEM (canvas_item); + day_view = dvtitem->day_view; + g_return_if_fail (day_view != NULL); + + style = gtk_widget_get_style (GTK_WIDGET (day_view)); + gc = day_view->main_gc; + fg_gc = style->fg_gc[GTK_STATE_NORMAL]; + bg_gc = style->bg_gc[GTK_STATE_NORMAL]; + light_gc = style->light_gc[GTK_STATE_NORMAL]; + dark_gc = style->dark_gc[GTK_STATE_NORMAL]; + canvas_width = GTK_WIDGET (canvas_item->canvas)->allocation.width; + canvas_height = GTK_WIDGET (canvas_item->canvas)->allocation.height; + left_edge = 0; + item_height = day_view->top_row_height - E_DAY_VIEW_TOP_CANVAS_Y_GAP; + + /* Draw the shadow around the dates. */ + gdk_draw_line (drawable, light_gc, + left_edge - x, 1 - y, + canvas_width - 2 - x, 1 - y); + gdk_draw_line (drawable, light_gc, + left_edge - x, 2 - y, + left_edge - x, item_height - 2 - y); + gdk_draw_line (drawable, dark_gc, + left_edge - x, item_height - 1 - y, + canvas_width - 1 - x, item_height - 1 - y); + gdk_draw_line (drawable, dark_gc, + canvas_width - 1 - x, 1 - y, + canvas_width - 1 - x, item_height - 1 - y); + + /* Draw the background for the dates. */ + gdk_draw_rectangle (drawable, bg_gc, TRUE, + left_edge + 2 - x, 2 - y, + canvas_width - left_edge - 3, + item_height - 3); + + /* Clear the main area background. */ + gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_BG_TOP_CANVAS]); + gdk_draw_rectangle (drawable, gc, TRUE, + left_edge - x, item_height - y, + canvas_width - left_edge, + canvas_height - item_height); + /* Draw the selection background. */ + if (GTK_WIDGET_HAS_FOCUS (day_view) + && day_view->selection_start_day != -1) { + gint start_col, end_col, rect_x, rect_y, rect_w, rect_h; + + start_col = day_view->selection_start_day; + end_col = day_view->selection_end_day; + + if (end_col > start_col + || day_view->selection_start_row == -1 + || day_view->selection_end_row == -1) { + rect_x = day_view->day_offsets[start_col]; + rect_y = item_height; + rect_w = day_view->day_offsets[end_col + 1] - rect_x; + rect_h = canvas_height - 1 - rect_y; + + gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_BG_TOP_CANVAS_SELECTED]); + gdk_draw_rectangle (drawable, gc, TRUE, + rect_x - x, rect_y - y, + rect_w, rect_h); + } + } + + /* Draw the date. Set a clipping rectangle so we don't draw over the + next day. */ + for (day = 0; day < day_view->days_shown; day++) { + e_day_view_top_item_get_day_label (day_view, day, + buffer, sizeof (buffer)); + clip_rect.x = day_view->day_offsets[day] - x; + clip_rect.y = 2 - y; + clip_rect.width = day_view->day_widths[day]; + clip_rect.height = item_height - 2; + gdk_gc_set_clip_rectangle (fg_gc, &clip_rect); + + layout = gtk_widget_create_pango_layout (GTK_WIDGET (day_view), buffer); + pango_layout_get_pixel_size (layout, &date_width, NULL); + date_x = day_view->day_offsets[day] + (day_view->day_widths[day] - date_width) / 2; + + gdk_draw_layout (drawable, fg_gc, + date_x - x, + 3 - y, + layout); + g_object_unref (layout); + + gdk_gc_set_clip_rectangle (fg_gc, NULL); + + /* Draw the lines down the left and right of the date cols. */ + if (day != 0) { + gdk_draw_line (drawable, light_gc, + day_view->day_offsets[day] - x, + 4 - y, + day_view->day_offsets[day] - x, + item_height - 4 - y); + + gdk_draw_line (drawable, dark_gc, + day_view->day_offsets[day] - 1 - x, + 4 - y, + day_view->day_offsets[day] - 1 - x, + item_height - 4 - y); + } + + /* Draw the lines between each column. */ + if (day != 0) { + gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_BG_TOP_CANVAS_GRID]); + gdk_draw_line (drawable, gc, + day_view->day_offsets[day] - x, + item_height - y, + day_view->day_offsets[day] - x, + canvas_height - y); + } + } + + /* Draw the long events. */ + for (event_num = 0; event_num < day_view->long_events->len; + event_num++) { + e_day_view_top_item_draw_long_event (dvtitem, event_num, + drawable, + x, y, width, height); + } +} + + +/* This draws one event in the top canvas. */ +static void +e_day_view_top_item_draw_long_event (EDayViewTopItem *dvtitem, + gint event_num, + GdkDrawable *drawable, + int x, + int y, + int width, + int height) +{ + EDayView *day_view; + EDayViewEvent *event; + GtkStyle *style; + GdkGC *gc, *fg_gc; + gint start_day, end_day; + gint item_x, item_y, item_w, item_h; + gint text_x, icon_x, icon_y, icon_x_inc; + ECalComponent *comp; + gchar buffer[16]; + gint hour, display_hour, minute, offset, time_width, time_x; + gint min_end_time_x, suffix_width, max_icon_x; + gchar *suffix; + gboolean draw_start_triangle, draw_end_triangle; + GdkRectangle clip_rect; + GSList *categories_list, *elem; + PangoLayout *layout; + GdkColor bg_color; + + day_view = dvtitem->day_view; + + /* 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 == E_DAY_VIEW_LONG_EVENT + && day_view->drag_event_num == event_num) + return; + + if (!e_day_view_get_long_event_position (day_view, event_num, + &start_day, &end_day, + &item_x, &item_y, + &item_w, &item_h)) + return; + + event = &g_array_index (day_view->long_events, EDayViewEvent, + event_num); + + style = gtk_widget_get_style (GTK_WIDGET (day_view)); + gc = day_view->main_gc; + fg_gc = style->fg_gc[GTK_STATE_NORMAL]; + comp = e_cal_component_new (); + e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp)); + + /* Draw the lines across the top & bottom of the entire event. */ + gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_LONG_EVENT_BORDER]); + gdk_draw_line (drawable, gc, + item_x - x, item_y - y, + item_x + item_w - 1 - x, item_y - y); + gdk_draw_line (drawable, gc, + item_x - x, item_y + item_h - 1 - y, + item_x + item_w - 1 - x, item_y + item_h - 1 - y); + + /* Fill it in. */ + 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_gc_set_foreground (gc, &bg_color); + else + gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_LONG_EVENT_BACKGROUND]); + } else + gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_LONG_EVENT_BACKGROUND]); + gdk_draw_rectangle (drawable, gc, TRUE, + item_x - x, item_y + 1 - y, + item_w, item_h - 2); + + /* When resizing we don't draw the triangles.*/ + draw_start_triangle = TRUE; + draw_end_triangle = TRUE; + if (day_view->resize_drag_pos != E_CALENDAR_VIEW_POS_NONE + && day_view->resize_event_day == E_DAY_VIEW_LONG_EVENT + && day_view->resize_event_num == event_num) { + if (day_view->resize_drag_pos == E_CALENDAR_VIEW_POS_LEFT_EDGE) + draw_start_triangle = FALSE; + + if (day_view->resize_drag_pos == E_CALENDAR_VIEW_POS_RIGHT_EDGE) + draw_end_triangle = FALSE; + } + + /* If the event starts before the first day shown, draw a triangle, + else just draw a vertical line down the left. */ + if (draw_start_triangle + && event->start < day_view->day_starts[start_day]) { + e_day_view_top_item_draw_triangle (dvtitem, drawable, + item_x - x, item_y - y, + -E_DAY_VIEW_BAR_WIDTH, + item_h, event_num); + } else { + gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_LONG_EVENT_BORDER]); + gdk_draw_line (drawable, gc, + item_x - x, item_y - y, + item_x - x, item_y + item_h - 1 - y); + } + + /* Similar for the event end. */ + if (draw_end_triangle + && event->end > day_view->day_starts[end_day + 1]) { + e_day_view_top_item_draw_triangle (dvtitem, drawable, + item_x + item_w - 1 - x, + item_y - y, + E_DAY_VIEW_BAR_WIDTH, + item_h, event_num); + } else { + gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_LONG_EVENT_BORDER]); + gdk_draw_line (drawable, gc, + item_x + item_w - 1 - x, + item_y - y, + item_x + item_w - 1 - x, + item_y + item_h - 1 - y); + } + + /* If we are editing the event we don't show the icons or the start + & end times. */ + if (day_view->editing_event_day == E_DAY_VIEW_LONG_EVENT + && day_view->editing_event_num == event_num) + return; + + /* Determine the position of the label, so we know where to place the + icons. Note that since the top canvas never scrolls we don't need + to take the scroll offset into account. It will always be 0. */ + text_x = event->canvas_item->x1; + + /* Draw the start & end times, if necessary. */ + min_end_time_x = item_x + E_DAY_VIEW_LONG_EVENT_X_PAD - x; + + time_width = e_day_view_get_time_string_width (day_view); + + if (event->start > day_view->day_starts[start_day]) { + offset = day_view->first_hour_shown * 60 + + day_view->first_minute_shown + event->start_minute; + hour = offset / 60; + minute = offset % 60; + /* Calculate the actual hour number to display. For 12-hour + format we convert 0-23 to 12-11am/12-11pm. */ + e_day_view_convert_time_to_display (day_view, hour, + &display_hour, + &suffix, &suffix_width); + if (e_calendar_view_get_use_24_hour_format (E_CALENDAR_VIEW (day_view))) { + g_snprintf (buffer, sizeof (buffer), "%i:%02i", + display_hour, minute); + } else { + g_snprintf (buffer, sizeof (buffer), "%i:%02i%s", + display_hour, minute, suffix); + } + + clip_rect.x = item_x - x; + clip_rect.y = item_y - y; + clip_rect.width = item_w - E_DAY_VIEW_LONG_EVENT_BORDER_WIDTH; + clip_rect.height = item_h; + gdk_gc_set_clip_rectangle (fg_gc, &clip_rect); + + time_x = item_x + E_DAY_VIEW_LONG_EVENT_X_PAD - x; + if (display_hour < 10) + time_x += day_view->digit_width; + + layout = gtk_widget_create_pango_layout (GTK_WIDGET (day_view), buffer); + gdk_draw_layout (drawable, fg_gc, + time_x, + item_y + E_DAY_VIEW_LONG_EVENT_BORDER_HEIGHT + + E_DAY_VIEW_LONG_EVENT_Y_PAD - y, + layout); + g_object_unref (layout); + + gdk_gc_set_clip_rectangle (fg_gc, NULL); + + min_end_time_x += time_width + + E_DAY_VIEW_LONG_EVENT_TIME_X_PAD; + } + + max_icon_x = item_x + item_w - E_DAY_VIEW_LONG_EVENT_X_PAD + - E_DAY_VIEW_ICON_WIDTH; + + if (event->end < day_view->day_starts[end_day + 1]) { + offset = day_view->first_hour_shown * 60 + + day_view->first_minute_shown + + event->end_minute; + hour = offset / 60; + minute = offset % 60; + time_x = item_x + item_w - E_DAY_VIEW_LONG_EVENT_X_PAD - time_width - E_DAY_VIEW_LONG_EVENT_TIME_X_PAD - x; + + if (time_x >= min_end_time_x) { + /* Calculate the actual hour number to display. */ + e_day_view_convert_time_to_display (day_view, hour, + &display_hour, + &suffix, + &suffix_width); + if (e_calendar_view_get_use_24_hour_format (E_CALENDAR_VIEW (day_view))) { + g_snprintf (buffer, sizeof (buffer), + "%i:%02i", display_hour, minute); + } else { + g_snprintf (buffer, sizeof (buffer), + "%i:%02i%s", display_hour, minute, + suffix); + } + + if (display_hour < 10) + time_x += day_view->digit_width; + + layout = gtk_widget_create_pango_layout (GTK_WIDGET (day_view), buffer); + gdk_draw_layout (drawable, fg_gc, + time_x, + item_y + E_DAY_VIEW_LONG_EVENT_Y_PAD + 1 - y, + layout); + g_object_unref (layout); + + max_icon_x -= time_width + E_DAY_VIEW_LONG_EVENT_TIME_X_PAD; + } + } + + /* Draw the icons. */ + icon_x_inc = E_DAY_VIEW_ICON_WIDTH + E_DAY_VIEW_ICON_X_PAD; + icon_x = text_x - E_DAY_VIEW_LONG_EVENT_ICON_R_PAD + - icon_x_inc - x; + icon_y = item_y + E_DAY_VIEW_LONG_EVENT_BORDER_HEIGHT + + E_DAY_VIEW_ICON_Y_PAD - y; + + if (icon_x <= max_icon_x && (e_cal_component_has_recurrences (comp) || e_cal_component_is_instance (comp))) { + gdk_gc_set_clip_mask (gc, NULL); + gdk_draw_pixbuf (drawable, gc, + day_view->recurrence_icon, + 0, 0, icon_x, icon_y, + E_DAY_VIEW_ICON_WIDTH, + E_DAY_VIEW_ICON_HEIGHT, + GDK_RGB_DITHER_NORMAL, + 0, 0); + icon_x -= icon_x_inc; + } + + if (icon_x <= max_icon_x && e_cal_component_has_attachments (comp)) { + gdk_gc_set_clip_mask (gc, NULL); + gdk_draw_pixbuf (drawable, gc, + day_view->attach_icon, + 0, 0, icon_x, icon_y, + E_DAY_VIEW_ICON_WIDTH, + E_DAY_VIEW_ICON_HEIGHT, + GDK_RGB_DITHER_NORMAL, + 0, 0); + icon_x -= icon_x_inc; + } + if (icon_x <= max_icon_x && e_cal_component_has_alarms (comp)) { + gdk_gc_set_clip_mask (gc, NULL); + gdk_draw_pixbuf (drawable, gc, + day_view->reminder_icon, + 0, 0, icon_x, icon_y, + E_DAY_VIEW_ICON_WIDTH, + E_DAY_VIEW_ICON_HEIGHT, + GDK_RGB_DITHER_NORMAL, + 0, 0); + icon_x -= icon_x_inc; + } + + /* draw categories icons */ + e_cal_component_get_categories_list (comp, &categories_list); + for (elem = categories_list; elem; elem = elem->next) { + char *category; + GdkPixmap *pixmap = NULL; + GdkBitmap *mask = NULL; + + category = (char *) elem->data; + e_categories_config_get_icon_for (category, &pixmap, &mask); + if (pixmap == NULL) + continue; + + if (icon_x <= max_icon_x) { + gdk_gc_set_clip_origin (gc, icon_x, icon_y); + if (mask != NULL) + gdk_gc_set_clip_mask (gc, mask); + gdk_draw_pixmap (drawable, gc, + pixmap, + 0, 0, icon_x, icon_y, + E_DAY_VIEW_ICON_WIDTH, + E_DAY_VIEW_ICON_HEIGHT); + icon_x -= icon_x_inc; + } + + gdk_pixmap_unref (pixmap); + if (mask != NULL) + gdk_bitmap_unref (mask); + } + + e_cal_component_free_categories_list (categories_list); + g_object_unref (comp); + + gdk_gc_set_clip_mask (gc, NULL); +} + + +/* This draws a little triangle to indicate that an event extends past + the days visible on screen. */ +static void +e_day_view_top_item_draw_triangle (EDayViewTopItem *dvtitem, + GdkDrawable *drawable, + gint x, + gint y, + gint w, + gint h, + gint event_num) +{ + EDayView *day_view; + EDayViewEvent *event; + GdkGC *gc; + GdkColor bg_color; + GdkPoint points[3]; + gint c1, c2; + + day_view = dvtitem->day_view; + + gc = day_view->main_gc; + + points[0].x = x; + points[0].y = y; + points[1].x = x + w; + points[1].y = y + (h / 2); + points[2].x = x; + points[2].y = y + h - 1; + + /* If the height is odd we can use the same central point for both + lines. If it is even we use different end-points. */ + c1 = c2 = y + (h / 2); + if (h % 2 == 0) + c1--; + + event = &g_array_index (day_view->long_events, EDayViewEvent, + event_num); + + /* Fill it in. */ + 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_gc_set_foreground (gc, &bg_color); + else + gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_LONG_EVENT_BACKGROUND]); + } else + gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_LONG_EVENT_BACKGROUND]); + + gdk_draw_polygon (drawable, gc, TRUE, points, 3); + + gdk_gc_set_foreground (gc, &day_view->colors[E_DAY_VIEW_COLOR_LONG_EVENT_BORDER]); + gdk_draw_line (drawable, gc, x, y, x + w, c1); + gdk_draw_line (drawable, gc, x, y + h - 1, x + w, c2); +} +#endif + +#ifdef ENABLE_CAIRO static void e_day_view_top_item_draw (GnomeCanvasItem *canvas_item, GdkDrawable *drawable, @@ -353,6 +858,7 @@ e_day_view_top_item_draw_long_event (EDayViewTopItem *dvtitem, guint16 red, green, blue; GdkColor fg; gdouble cc = 65535.0; + gboolean gradient; gfloat alpha; gdouble x0, y0, rect_height, rect_width, radius; @@ -361,7 +867,11 @@ e_day_view_top_item_draw_long_event (EDayViewTopItem *dvtitem, alpha = gconf_client_get_float (gconf_client_get_default (), "/apps/evolution/calendar/display/events_transparency", - NULL); + NULL); + + gradient = gconf_client_get_bool (gconf_client_get_default (), + "/apps/evolution/calendar/display/events_gradient", + NULL); /* If the event is currently being dragged, don't draw it. It will be drawn in the special drag items. */ @@ -452,14 +962,18 @@ e_day_view_top_item_draw_long_event (EDayViewTopItem *dvtitem, draw_curved_rectangle (cr, x0, y0, rect_width, rect_height, radius); - pat = cairo_pattern_create_linear (item_x - x + 5.5, item_y + 2.5 - y, - item_x - x + 5, item_y - y + item_h + 7.5); - 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); - + if (gradient){ + pat = cairo_pattern_create_linear (item_x - x + 5.5, item_y + 2.5 - y, + item_x - x + 5, item_y - y + item_h + 7.5); + 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); cairo_set_line_width (cr, 0.5); cairo_stroke (cr); @@ -739,7 +1253,7 @@ e_day_view_top_item_draw_triangle (EDayViewTopItem *dvtitem, cairo_destroy (cr); } - +#endif /* This is supposed to return the nearest item the the point and the distance. Since we are the only item we just return ourself and 0 for the distance. diff --git a/calendar/gui/e-day-view.c b/calendar/gui/e-day-view.c index 75744d2347..fa80114970 100644 --- a/calendar/gui/e-day-view.c +++ b/calendar/gui/e-day-view.c @@ -1193,6 +1193,35 @@ e_day_view_unrealize (GtkWidget *widget) (*GTK_WIDGET_CLASS (e_day_view_parent_class)->unrealize)(widget); } +static GdkColor +e_day_view_get_text_color (EDayView *day_view, EDayViewEvent *event, GtkWidget *widget) +{ + GdkColor color, bg_color; + guint16 red, green, blue; + gdouble cc = 65535.0; + + red = day_view->colors[E_DAY_VIEW_COLOR_EVENT_BACKGROUND].red; + green = day_view->colors[E_DAY_VIEW_COLOR_EVENT_BACKGROUND].green; + blue = day_view->colors[E_DAY_VIEW_COLOR_EVENT_BACKGROUND].blue; + + 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)) { + red = bg_color.red; + green = bg_color.green; + blue = bg_color.blue; + } + } + + if ((red/cc > 0.7) || (green/cc > 0.7) || (blue/cc > 0.7 )) + color = widget->style->text[GTK_STATE_NORMAL]; + else + color = widget->style->text[GTK_STATE_ACTIVE]; + + return color; +} static void e_day_view_style_set (GtkWidget *widget, @@ -1214,6 +1243,7 @@ e_day_view_style_set (GtkWidget *widget, PangoLayout *layout; gint week_day, event_num; EDayViewEvent *event; + GdkColor color; if (GTK_WIDGET_CLASS (e_day_view_parent_class)->style_set) (*GTK_WIDGET_CLASS (e_day_view_parent_class)->style_set)(widget, previous_style); @@ -1224,18 +1254,22 @@ e_day_view_style_set (GtkWidget *widget, for (week_day = 0; week_day < E_DAY_VIEW_MAX_DAYS; week_day++){ for (event_num = 0; event_num < day_view->events[week_day]->len; event_num++) { event = &g_array_index (day_view->events[week_day], EDayViewEvent, event_num); - if (event->canvas_item) + if (event->canvas_item) { + color = e_day_view_get_text_color (day_view, event, widget); gnome_canvas_item_set (event->canvas_item, - "fill_color_gdk", &widget->style->text[GTK_STATE_NORMAL], + "fill_color_gdk", &color, NULL); + } } } for (event_num = 0; event_num < day_view->long_events->len; event_num++) { event = &g_array_index (day_view->long_events, EDayViewEvent, event_num); - if (event->canvas_item) + if (event->canvas_item) { + color = e_day_view_get_text_color (day_view, event, widget); gnome_canvas_item_set (event->canvas_item, - "fill_color_gdk", &widget->style->text[GTK_STATE_NORMAL], + "fill_color_gdk", &color, NULL); + } } gnome_canvas_item_set (day_view->main_canvas_top_resize_bar_item, "fill_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_VBAR], @@ -4395,6 +4429,7 @@ e_day_view_reshape_long_event (EDayView *day_view, num_icons++; if (event->different_timezone) num_icons++; + if (e_cal_component_has_organizer (comp)) num_icons++; if (e_cal_component_has_attachments (comp)) @@ -4414,8 +4449,12 @@ e_day_view_reshape_long_event (EDayView *day_view, if (!event->canvas_item) { GtkWidget *widget; + GdkColor color; widget = (GtkWidget *)day_view; + + color = e_day_view_get_text_color (day_view, event, widget); + event->canvas_item = gnome_canvas_item_new (GNOME_CANVAS_GROUP (GNOME_CANVAS (day_view->top_canvas)->root), e_text_get_type (), @@ -4425,7 +4464,7 @@ e_day_view_reshape_long_event (EDayView *day_view, "editable", TRUE, "use_ellipsis", TRUE, "draw_background", FALSE, - "fill_color_gdk", &widget->style->text[GTK_STATE_NORMAL], + "fill_color_gdk", &color, "im_context", E_CANVAS (day_view->top_canvas)->im_context, NULL); g_object_set_data (G_OBJECT (event->canvas_item), "event-num", GINT_TO_POINTER (event_num)); @@ -4597,8 +4636,12 @@ e_day_view_reshape_day_event (EDayView *day_view, if (!event->canvas_item) { GtkWidget *widget; + GdkColor color; widget = (GtkWidget *)day_view; + + color = e_day_view_get_text_color (day_view, event, widget); + event->canvas_item = gnome_canvas_item_new (GNOME_CANVAS_GROUP (GNOME_CANVAS (day_view->main_canvas)->root), e_text_get_type (), @@ -4608,7 +4651,7 @@ e_day_view_reshape_day_event (EDayView *day_view, "clip", TRUE, "use_ellipsis", TRUE, "draw_background", FALSE, - "fill_color_gdk", &widget->style->text[GTK_STATE_NORMAL], + "fill_color_gdk", &color, "im_context", E_CANVAS (day_view->main_canvas)->im_context, NULL); g_object_set_data (G_OBJECT (event->canvas_item), "event-num", GINT_TO_POINTER (event_num)); diff --git a/calendar/gui/e-week-view-event-item.c b/calendar/gui/e-week-view-event-item.c index 3250c72595..4c7813b30e 100644 --- a/calendar/gui/e-week-view-event-item.c +++ b/calendar/gui/e-week-view-event-item.c @@ -207,8 +207,583 @@ e_week_view_event_item_update (GnomeCanvasItem *item, /* * DRAWING ROUTINES - functions to paint the canvas item. */ +#ifndef ENABLE_CAIRO +static void +e_week_view_event_item_draw (GnomeCanvasItem *canvas_item, + GdkDrawable *drawable, + int x, + int y, + int width, + int height) +{ + EWeekViewEventItem *wveitem; + EWeekView *week_view; + EWeekViewEvent *event; + EWeekViewEventSpan *span; + 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; + gint rect_x, rect_w, rect_x2; + gboolean one_day_event, editing_span = FALSE; + gint start_hour, start_minute, end_hour, end_minute; + gboolean draw_start, draw_end; + gboolean draw_start_triangle = FALSE, draw_end_triangle = FALSE; + GdkRectangle clip_rect; + GdkColor bg_color; + +#if 0 + g_print ("In e_week_view_event_item_draw %i,%i %ix%i\n", + x, y, width, height); +#endif + + wveitem = E_WEEK_VIEW_EVENT_ITEM (canvas_item); + week_view = E_WEEK_VIEW (GTK_WIDGET (canvas_item->canvas)->parent); + g_return_if_fail (E_IS_WEEK_VIEW (week_view)); + + if (wveitem->event_num == -1 || wveitem->span_num == -1) + return; + + 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); + + span = &g_array_index (week_view->spans, EWeekViewEventSpan, + event->spans_index + wveitem->span_num); + + gc = week_view->main_gc; + + x1 = canvas_item->x1 - x; + y1 = canvas_item->y1 - y; + x2 = canvas_item->x2 - x; + y2 = canvas_item->y2 - y; + + if (x1 == x2 || y1 == y2) + return; + + icon_x = 0; + icon_y = y1 + E_WEEK_VIEW_EVENT_BORDER_HEIGHT + E_WEEK_VIEW_ICON_Y_PAD; + + /* Get the start & end times in 24-hour format. */ + start_hour = event->start_minute / 60; + start_minute = event->start_minute % 60; + + /* Modulo 24 because a midnight end time will be '24' */ + end_hour = (event->end_minute / 60) % 24; + end_minute = event->end_minute % 60; + + time_y = y1 + E_WEEK_VIEW_EVENT_BORDER_HEIGHT + + E_WEEK_VIEW_EVENT_TEXT_Y_PAD; + + 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); + 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)) + gdk_gc_set_foreground (gc, &bg_color); + else + gdk_gc_set_foreground (gc, &week_view->colors[E_WEEK_VIEW_COLOR_EVENT_BACKGROUND]); + } else + gdk_gc_set_foreground (gc, &week_view->colors[E_WEEK_VIEW_COLOR_EVENT_BACKGROUND]); + gdk_draw_rectangle (drawable, gc, TRUE, rect_x, y1 + 1, rect_w, y2 - y1 - 1); + + gdk_gc_set_foreground (gc, &week_view->colors[E_WEEK_VIEW_COLOR_EVENT_BORDER]); + gdk_draw_line (drawable, gc, rect_x, y1 + 1, rect_x + rect_w, y1 + 1); + gdk_draw_line (drawable, gc, rect_x, y2, rect_x + rect_w, y2); + gdk_draw_line (drawable, gc, rect_x, y1 + 1, rect_x, y1 + (y2 - (y1 + 1))); + gdk_draw_line (drawable, gc, rect_x + rect_w, y1 + 1, rect_x + rect_w, y1 + (y2 - (y1 + 1))); + + /* Draw the start and end times, as required. */ + switch (week_view->time_format) { + case E_WEEK_VIEW_TIME_BOTH_SMALL_MIN: + case E_WEEK_VIEW_TIME_BOTH: + draw_start = TRUE; + draw_end = TRUE; + break; + + case E_WEEK_VIEW_TIME_START_SMALL_MIN: + case E_WEEK_VIEW_TIME_START: + draw_start = TRUE; + draw_end = FALSE; + break; + + case E_WEEK_VIEW_TIME_NONE: + draw_start = FALSE; + draw_end = FALSE; + break; + default: + g_assert_not_reached(); + draw_start = FALSE; + draw_end = FALSE; + break; + } + + if (draw_start) { + e_week_view_draw_time (week_view, drawable, + time_x, time_y, + start_hour, start_minute); + time_x += time_width; + } + + if (draw_end) { + time_x += E_WEEK_VIEW_EVENT_TIME_SPACING; + e_week_view_draw_time (week_view, drawable, + time_x, time_y, + end_hour, end_minute); + time_x += time_width; + } + + icon_x = time_x; + if (draw_start) + icon_x += E_WEEK_VIEW_EVENT_TIME_X_PAD; + + /* Draw the icons. */ + e_week_view_event_item_draw_icons (wveitem, drawable, + icon_x, icon_y, + x2, FALSE); + + } else { + 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; + + /* Draw the triangles at the start & end, if needed. + They also use the first few pixels at the edge of the + event so we update rect_x & rect_w so we don't draw over + them. */ + if (event->start < week_view->day_starts[span->start_day]) { + draw_start_triangle = TRUE; + rect_x += 2; + rect_w -= 2; + } + + if (event->end > week_view->day_starts[span->start_day + + span->num_days]) { + draw_end_triangle = TRUE; + rect_w -= 2; + } + + 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)) + gdk_gc_set_foreground (gc, &bg_color); + else + gdk_gc_set_foreground (gc, &week_view->colors[E_WEEK_VIEW_COLOR_EVENT_BACKGROUND]); + } else + gdk_gc_set_foreground (gc, &week_view->colors[E_WEEK_VIEW_COLOR_EVENT_BACKGROUND]); + gdk_draw_rectangle (drawable, gc, TRUE, rect_x, y1 + 1, rect_w, y2 - y1 - 1); + + gdk_gc_set_foreground (gc, &week_view->colors[E_WEEK_VIEW_COLOR_EVENT_BORDER]); + rect_x2 = rect_x + rect_w - 1; + gdk_draw_line (drawable, gc, rect_x, y1, rect_x2, y1); + gdk_draw_line (drawable, gc, rect_x, y2, rect_x2, y2); + + 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 { + gdk_draw_line (drawable, gc, rect_x, y1, rect_x, y2); + } + + 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 { + gdk_draw_line (drawable, gc, rect_x2, y1, rect_x2, y2); + } + + if (span->text_item && E_TEXT (span->text_item)->editing) + editing_span = TRUE; + + /* Draw the start & end times, if they are not on day + boundaries. The start time would always be shown if it was + needed, though it may be clipped as the window shrinks. + The end time is only displayed if there is enough room. + We calculate the minimum position for the end time, which + depends on whether the start time is displayed. If the end + time doesn't fit, then we don't draw it. */ + min_end_time_x = x1 + E_WEEK_VIEW_EVENT_L_PAD + + E_WEEK_VIEW_EVENT_BORDER_WIDTH + + E_WEEK_VIEW_EVENT_EDGE_X_PAD; + if (!editing_span + && event->start > week_view->day_starts[span->start_day]) { + time_x = x1 + E_WEEK_VIEW_EVENT_L_PAD + + E_WEEK_VIEW_EVENT_BORDER_WIDTH + + E_WEEK_VIEW_EVENT_EDGE_X_PAD; + + clip_rect.x = x1; + clip_rect.y = y1; + clip_rect.width = x2 - x1 - E_WEEK_VIEW_EVENT_R_PAD + - E_WEEK_VIEW_EVENT_BORDER_WIDTH + 1; + clip_rect.height = y2 - y1 + 1; + gdk_gc_set_clip_rectangle (gc, &clip_rect); + + gdk_gc_set_foreground (gc, &week_view->colors[E_WEEK_VIEW_COLOR_EVENT_TEXT]); + + e_week_view_draw_time (week_view, drawable, + time_x, time_y, + start_hour, start_minute); + + gdk_gc_set_clip_rectangle (gc, NULL); + + /* We don't want the end time to be drawn over the + start time, so we increase the minimum position. */ + min_end_time_x += time_width + + E_WEEK_VIEW_EVENT_TIME_X_PAD; + } + + max_icon_x = x2 + 1 - E_WEEK_VIEW_EVENT_R_PAD + - E_WEEK_VIEW_EVENT_BORDER_WIDTH + - E_WEEK_VIEW_EVENT_EDGE_X_PAD; + + if (!editing_span + && event->end < week_view->day_starts[span->start_day + + span->num_days]) { + /* Calculate where the end time should be displayed. */ + time_x = x2 + 1 - E_WEEK_VIEW_EVENT_R_PAD + - E_WEEK_VIEW_EVENT_BORDER_WIDTH + - E_WEEK_VIEW_EVENT_EDGE_X_PAD + - time_width; + + /* Draw the end time, if the position is greater than + the minimum calculated above. */ + if (time_x >= min_end_time_x) { + e_week_view_draw_time (week_view, drawable, + time_x, time_y, + end_hour, end_minute); + max_icon_x -= time_width + + E_WEEK_VIEW_EVENT_TIME_X_PAD; + } + } + + /* Draw the icons. */ + if (span->text_item + && (week_view->editing_event_num != wveitem->event_num + || week_view->editing_span_num != wveitem->span_num)) { + 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); + } + } +} + static void +e_week_view_draw_time (EWeekView *week_view, + GdkDrawable *drawable, + gint time_x, + gint time_y, + gint hour, + gint minute) +{ + GtkStyle *style; + GdkGC *gc; + gint hour_to_display, suffix_width; + gint time_y_normal_font, time_y_small_font; + gchar buffer[128], *suffix; + PangoLayout *layout; + PangoFontDescription *small_font_desc; + + style = gtk_widget_get_style (GTK_WIDGET (week_view)); + small_font_desc = week_view->small_font_desc; + gc = week_view->main_gc; + + gdk_gc_set_foreground (gc, &week_view->colors[E_WEEK_VIEW_COLOR_EVENT_TEXT]); + + layout = gtk_widget_create_pango_layout (GTK_WIDGET (week_view), NULL); + + time_y_normal_font = time_y_small_font = time_y; + if (small_font_desc) + time_y_small_font = time_y; + + e_week_view_convert_time_to_display (week_view, hour, &hour_to_display, + &suffix, &suffix_width); + + if (week_view->use_small_font && week_view->small_font_desc) { + g_snprintf (buffer, sizeof (buffer), "%2i:%02i", + hour_to_display, minute); + + /* Draw the hour. */ + if (hour_to_display < 10) { + pango_layout_set_text (layout, buffer + 1, 1); + gdk_draw_layout (drawable, gc, + time_x + week_view->digit_width, + time_y_normal_font, + layout); + } else { + pango_layout_set_text (layout, buffer, 2); + gdk_draw_layout (drawable, gc, + time_x, + time_y_normal_font, + layout); + } + + time_x += week_view->digit_width * 2; + + /* Draw the start minute, in the small font. */ + pango_layout_set_font_description (layout, week_view->small_font_desc); + pango_layout_set_text (layout, buffer + 3, 2); + gdk_draw_layout (drawable, gc, + time_x, + time_y_small_font, + layout); + + pango_layout_set_font_description (layout, style->font_desc); + + time_x += week_view->small_digit_width * 2; + + /* Draw the 'am'/'pm' suffix, if 12-hour format. */ + if (!e_calendar_view_get_use_24_hour_format (E_CALENDAR_VIEW (week_view))) { + pango_layout_set_text (layout, suffix, -1); + gdk_draw_layout (drawable, gc, + time_x, + time_y_normal_font, + layout); + } + } else { + /* Draw the start time in one go. */ + g_snprintf (buffer, sizeof (buffer), "%2i:%02i%s", + hour_to_display, minute, suffix); + if (hour_to_display < 10) { + pango_layout_set_text (layout, buffer + 1, -1); + gdk_draw_layout (drawable, gc, + time_x + week_view->digit_width, + time_y_normal_font, + layout); + } else { + pango_layout_set_text (layout, buffer, -1); + gdk_draw_layout (drawable, gc, + time_x, + time_y_normal_font, + layout); + } + + } + + g_object_unref (layout); +} + + +static void +e_week_view_event_item_draw_icons (EWeekViewEventItem *wveitem, + GdkDrawable *drawable, + gint icon_x, + gint icon_y, + gint x2, + gboolean right_align) +{ + EWeekView *week_view; + EWeekViewEvent *event; + ECalComponent *comp; + GdkGC *gc; + gint num_icons = 0, icon_x_inc; + gboolean draw_reminder_icon = FALSE, draw_recurrence_icon = FALSE; + gboolean draw_timezone_icon = FALSE, draw_attach_icon = FALSE; + GSList *categories_list, *elem; + + week_view = E_WEEK_VIEW (GTK_WIDGET (GNOME_CANVAS_ITEM (wveitem)->canvas)->parent); + + event = &g_array_index (week_view->events, EWeekViewEvent, + wveitem->event_num); + comp = e_cal_component_new (); + e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp)); + + gc = week_view->main_gc; + + if (e_cal_component_has_alarms (comp)) { + draw_reminder_icon = TRUE; + num_icons++; + } + + if (e_cal_component_has_recurrences (comp) || e_cal_component_is_instance (comp)) { + draw_recurrence_icon = TRUE; + num_icons++; + } + + if (e_cal_component_has_attachments (comp)) { + draw_attach_icon = TRUE; + num_icons++; + } + + if (event->different_timezone) { + draw_timezone_icon = TRUE; + num_icons++; + } + + e_cal_component_get_categories_list (comp, &categories_list); + for (elem = categories_list; elem; elem = elem->next) { + char *category; + GdkPixmap *pixmap = NULL; + GdkBitmap *mask = NULL; + + category = (char *) elem->data; + if (e_categories_config_get_icon_for (category, &pixmap, &mask)) + num_icons++; + } + + 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) { + gdk_gc_set_clip_mask (gc, NULL); + gdk_draw_pixbuf (drawable, gc, + week_view->reminder_icon, + 0, 0, icon_x, icon_y, + E_WEEK_VIEW_ICON_WIDTH, + E_WEEK_VIEW_ICON_HEIGHT, + GDK_RGB_DITHER_NORMAL, + 0, 0); + icon_x += icon_x_inc; + } + + if (draw_attach_icon && icon_x + E_WEEK_VIEW_ICON_WIDTH <= x2) { + gdk_gc_set_clip_mask (gc, NULL); + gdk_draw_pixbuf (drawable, gc, + week_view->attach_icon, + 0, 0, icon_x, icon_y, + E_WEEK_VIEW_ICON_WIDTH, + E_WEEK_VIEW_ICON_HEIGHT, + GDK_RGB_DITHER_NORMAL, + 0, 0); + icon_x += icon_x_inc; + } + + if (draw_recurrence_icon && icon_x + E_WEEK_VIEW_ICON_WIDTH <= x2) { + gdk_gc_set_clip_mask (gc, NULL); + gdk_draw_pixbuf (drawable, gc, + week_view->recurrence_icon, + 0, 0, icon_x, icon_y, + E_WEEK_VIEW_ICON_WIDTH, + E_WEEK_VIEW_ICON_HEIGHT, + GDK_RGB_DITHER_NORMAL, + 0, 0); + icon_x += icon_x_inc; + } + + if (draw_timezone_icon && icon_x + E_WEEK_VIEW_ICON_WIDTH <= x2) { + gdk_gc_set_clip_mask (gc, NULL); + gdk_draw_pixbuf (drawable, gc, + week_view->timezone_icon, + 0, 0, icon_x, icon_y, + E_WEEK_VIEW_ICON_WIDTH, + E_WEEK_VIEW_ICON_HEIGHT, + GDK_RGB_DITHER_NORMAL, + 0, 0); + icon_x += icon_x_inc; + } + + /* draw categories icons */ + for (elem = categories_list; elem; elem = elem->next) { + char *category; + GdkPixmap *pixmap = NULL; + GdkBitmap *mask = NULL; + + category = (char *) 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_pixmap (drawable, gc, + pixmap, + 0, 0, icon_x, icon_y, + E_WEEK_VIEW_ICON_WIDTH, + E_WEEK_VIEW_ICON_HEIGHT); + icon_x += icon_x_inc; + } + gdk_pixmap_unref (pixmap); + if (mask != NULL) + gdk_bitmap_unref (mask); + } + + e_cal_component_free_categories_list (categories_list); + g_object_unref(comp); + + gdk_gc_set_clip_mask (gc, NULL); +} + + +/* This draws a little triangle to indicate that an event extends past + the days visible on screen. */ +static void +e_week_view_event_item_draw_triangle (EWeekViewEventItem *wveitem, + GdkDrawable *drawable, + gint x, + gint y, + gint w, + gint h) +{ + EWeekView *week_view; + EWeekViewEvent *event; + GdkGC *gc; + GdkColor bg_color; + GdkPoint points[3]; + gint c1, c2; + + week_view = E_WEEK_VIEW (GTK_WIDGET (GNOME_CANVAS_ITEM (wveitem)->canvas)->parent); + + event = &g_array_index (week_view->events, EWeekViewEvent, + wveitem->event_num); + + gc = week_view->main_gc; + + points[0].x = x; + points[0].y = y; + points[1].x = x + w; + points[1].y = y + (h / 2); + points[2].x = x; + points[2].y = y + h - 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)) + gdk_gc_set_foreground (gc, &bg_color); + else + gdk_gc_set_foreground (gc, &week_view->colors[E_WEEK_VIEW_COLOR_EVENT_BACKGROUND]); + } else + gdk_gc_set_foreground (gc, &week_view->colors[E_WEEK_VIEW_COLOR_EVENT_BACKGROUND]); + + gdk_draw_polygon (drawable, gc, TRUE, points, 3); + + gdk_gc_set_foreground (gc, &week_view->colors[E_WEEK_VIEW_COLOR_EVENT_BORDER]); + + /* If the height is odd we can use the same central point for both + lines. If it is even we use different end-points. */ + c1 = c2 = y + (h / 2); + if (h % 2 == 0) + c1--; + + gdk_draw_line (drawable, gc, x, y, x + w, c1); + gdk_draw_line (drawable, gc, x, y + h - 1, x + w, c2); +} +#endif + +#ifdef ENABLE_CAIRO +static void e_week_view_event_item_draw (GnomeCanvasItem *canvas_item, GdkDrawable *drawable, int x, @@ -234,6 +809,7 @@ e_week_view_event_item_draw (GnomeCanvasItem *canvas_item, cairo_pattern_t *pat; guint16 red, green, blue; gdouble radius, cx0, cy0, rect_height, rect_width; + gboolean gradient; gdouble cc = 65535.0; #if 0 @@ -252,6 +828,10 @@ e_week_view_event_item_draw (GnomeCanvasItem *canvas_item, g_return_if_fail(wveitem->event_num < week_view->events->len); + gradient = gconf_client_get_bool (gconf_client_get_default (), + "/apps/evolution/calendar/display/events_gradient", + NULL); + event = &g_array_index (week_view->events, EWeekViewEvent, wveitem->event_num); @@ -344,14 +924,18 @@ e_week_view_event_item_draw (GnomeCanvasItem *canvas_item, draw_curved_rectangle (cr, cx0, cy0, rect_width, rect_height, radius); - 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); - + 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); @@ -478,14 +1062,18 @@ e_week_view_event_item_draw (GnomeCanvasItem *canvas_item, draw_curved_rectangle (cr, cx0, cy0, rect_width, rect_height, radius); - pat = cairo_pattern_create_linear (rect_x + 2, y1 + 1, + 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); - + 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); @@ -592,7 +1180,6 @@ e_week_view_event_item_draw (GnomeCanvasItem *canvas_item, cairo_destroy (cr); } - static void e_week_view_draw_time (EWeekView *week_view, GdkDrawable *drawable, @@ -898,7 +1485,7 @@ e_week_view_event_item_draw_triangle (EWeekViewEventItem *wveitem, cairo_destroy (cr); } - +#endif /* This is supposed to return the nearest item the the point and the distance. Since we are the only item we just return ourself and 0 for the distance. diff --git a/calendar/gui/e-week-view-main-item.c b/calendar/gui/e-week-view-main-item.c index 32ac8546aa..5da9600562 100644 --- a/calendar/gui/e-week-view-main-item.c +++ b/calendar/gui/e-week-view-main-item.c @@ -139,7 +139,6 @@ e_week_view_main_item_update (GnomeCanvasItem *item, /* * DRAWING ROUTINES - functions to paint the canvas item. */ - static void e_week_view_main_item_draw (GnomeCanvasItem *canvas_item, GdkDrawable *drawable, @@ -185,8 +184,209 @@ e_week_view_main_item_draw (GnomeCanvasItem *canvas_item, g_date_add_days (&date, 1); } } +#ifndef ENABLE_CAIRO +static void +e_week_view_main_item_draw_day (EWeekViewMainItem *wvmitem, + gint day, + GDate *date, + GdkDrawable *drawable, + gint x, + gint y, + gint width, + gint height) +{ + EWeekView *week_view; + GtkStyle *style; + GdkGC *gc; + gint right_edge, bottom_edge, date_width, date_x, line_y; + gboolean show_day_name, show_month_name, selected; + gchar buffer[128], *format_string; + gint month, day_of_month, max_width; + GdkColor *bg_color; + PangoFontDescription *font_desc; + PangoContext *pango_context; + PangoFontMetrics *font_metrics; + PangoLayout *layout; + gboolean today = FALSE; + +#if 0 + g_print ("Drawing Day:%i at %i,%i\n", day, x, y); +#endif + week_view = wvmitem->week_view; + style = gtk_widget_get_style (GTK_WIDGET (week_view)); + gc = week_view->main_gc; + + /* Set up Pango prerequisites */ + font_desc = style->font_desc; + pango_context = gtk_widget_get_pango_context (GTK_WIDGET (week_view)); + font_metrics = pango_context_get_metrics (pango_context, font_desc, + pango_context_get_language (pango_context)); + + g_return_if_fail (gc != NULL); + + month = g_date_month (date); + day_of_month = g_date_day (date); + line_y = y + E_WEEK_VIEW_DATE_T_PAD + + PANGO_PIXELS (pango_font_metrics_get_ascent (font_metrics)) + + PANGO_PIXELS (pango_font_metrics_get_descent (font_metrics)) + + E_WEEK_VIEW_DATE_LINE_T_PAD; + /* Draw the background of the day. In the month view odd months are + one color and even months another, so you can easily see when each + month starts (defaults are white for odd - January, March, ... and + light gray for even). In the week view the background is always the + same color, the color used for the odd months in the month view. */ + if (week_view->multi_week_view && (month % 2 == 0)) + bg_color = &week_view->colors[E_WEEK_VIEW_COLOR_EVEN_MONTHS]; + else + bg_color = &week_view->colors[E_WEEK_VIEW_COLOR_ODD_MONTHS]; + gdk_gc_set_foreground (gc, bg_color); + gdk_draw_rectangle (drawable, gc, TRUE, x, y, width, height); + + /* Draw the lines on the right and bottom of the cell. The canvas is + sized so that the lines on the right & bottom edges will be off the + edge of the canvas, so we don't have to worry about them. */ + right_edge = x + width - 1; + bottom_edge = y + height - 1; + + gdk_gc_set_foreground (gc, &week_view->colors[E_WEEK_VIEW_COLOR_GRID]); + gdk_draw_line (drawable, gc, + right_edge, y, right_edge, bottom_edge); + gdk_draw_line (drawable, gc, + x, bottom_edge, right_edge, bottom_edge); + + /* If the day is selected, draw the blue background. */ + selected = TRUE; + if (week_view->selection_start_day == -1 + || week_view->selection_start_day > day + || week_view->selection_end_day < day) + selected = FALSE; + if (selected) { + if (GTK_WIDGET_HAS_FOCUS (week_view)) + gdk_gc_set_foreground (gc, &week_view->colors[E_WEEK_VIEW_COLOR_SELECTED]); + else + gdk_gc_set_foreground (gc, &week_view->colors[E_WEEK_VIEW_COLOR_SELECTED_UNFOCUSSED]); + + if (week_view->multi_week_view) { + gdk_draw_rectangle (drawable, gc, TRUE, + x + 2, y + 1, + width - 5, + E_WEEK_VIEW_DATE_T_PAD - 1 + + PANGO_PIXELS (pango_font_metrics_get_ascent (font_metrics)) + + PANGO_PIXELS (pango_font_metrics_get_descent (font_metrics))); + } else { + gdk_draw_rectangle (drawable, gc, TRUE, + x + 2, y + 1, + width - 5, line_y - y); + } + } + + /* Display the date in the top of the cell. + In the week view, display the long format "10 January" in all cells, + or abbreviate it to "10 Jan" or "10" if that doesn't fit. + In the month view, only use the long format for the first cell and + the 1st of each month, otherwise use "10". */ + show_day_name = FALSE; + show_month_name = FALSE; + if (!week_view->multi_week_view) { + show_day_name = TRUE; + show_month_name = TRUE; + } else if (day == 0 || day_of_month == 1) { + show_month_name = TRUE; + } + + /* Now find the longest form of the date that will fit. */ + max_width = width - 4; + format_string = NULL; + if (show_day_name) { + if (week_view->max_day_width + week_view->digit_width * 2 + + week_view->space_width * 2 + + week_view->month_widths[month - 1] < max_width) + /* strftime format %A = full weekday name, %d = day of + month, %B = full month name. You can change the + order but don't change the specifiers or add + anything. */ + format_string = _("%A %d %B"); + else if (week_view->max_abbr_day_width + + week_view->digit_width * 2 + + week_view->space_width * 2 + + week_view->abbr_month_widths[month - 1] < max_width) + /* strftime format %a = abbreviated weekday name, + %d = day of month, %b = abbreviated month name. + You can change the order but don't change the + specifiers or add anything. */ + format_string = _("%a %d %b"); + } + if (!format_string && show_month_name) { + if (week_view->digit_width * 2 + week_view->space_width + + week_view->month_widths[month - 1] < max_width) + /* strftime format %d = day of month, %B = full + month name. You can change the order but don't + change the specifiers or add anything. */ + format_string = _("%d %B"); + else if (week_view->digit_width * 2 + week_view->space_width + + week_view->abbr_month_widths[month - 1] < max_width) + /* strftime format %d = day of month, %b = abbreviated + month name. You can change the order but don't + change the specifiers or add anything. */ + format_string = _("%d %b"); + } + + if (selected) { + gdk_gc_set_foreground (gc, &week_view->colors[E_WEEK_VIEW_COLOR_DATES_SELECTED]); + } else if (week_view->multi_week_view) { + struct icaltimetype tt; + + /* Check if we are drawing today */ + tt = icaltime_from_timet_with_zone (time (NULL), FALSE, + e_calendar_view_get_timezone (E_CALENDAR_VIEW (week_view))); + if (g_date_year (date) == tt.year + && g_date_month (date) == tt.month + && g_date_day (date) == tt.day) { + gdk_gc_set_foreground (gc, &week_view->colors[E_WEEK_VIEW_COLOR_TODAY]); + today = TRUE; + } + else + gdk_gc_set_foreground (gc, &week_view->colors[E_WEEK_VIEW_COLOR_DATES]); + } else { + gdk_gc_set_foreground (gc, &week_view->colors[E_WEEK_VIEW_COLOR_DATES]); + } + + if (today) { + g_date_strftime (buffer, sizeof (buffer), + format_string ? format_string : "<b>%d</b>", date); + layout = gtk_widget_create_pango_layout (GTK_WIDGET (week_view), buffer); + pango_layout_set_markup (layout, buffer, strlen(buffer)); + } else { + g_date_strftime (buffer, sizeof (buffer), + format_string ? format_string : "%d", date); + layout = gtk_widget_create_pango_layout (GTK_WIDGET (week_view), buffer); + } + + pango_layout_get_pixel_size (layout, &date_width, NULL); + date_x = x + width - date_width - E_WEEK_VIEW_DATE_R_PAD; + date_x = MAX (date_x, x + 1); + + gdk_draw_layout (drawable, gc, + date_x, + y + E_WEEK_VIEW_DATE_T_PAD, + layout); + g_object_unref (layout); + + /* Draw the line under the date. */ + if (!week_view->multi_week_view) { + gdk_gc_set_foreground (gc, &week_view->colors[E_WEEK_VIEW_COLOR_GRID]); + gdk_draw_line (drawable, gc, + x + E_WEEK_VIEW_DATE_LINE_L_PAD, line_y, + right_edge, line_y); + } + + pango_font_metrics_unref (font_metrics); +} +#endif + +#ifdef ENABLE_CAIRO static void e_week_view_main_item_draw_day (EWeekViewMainItem *wvmitem, gint day, @@ -412,9 +612,7 @@ e_week_view_main_item_draw_day (EWeekViewMainItem *wvmitem, pango_font_metrics_unref (font_metrics); cairo_destroy (cr); } - - - +#endif /* This is supposed to return the nearest item the the point and the distance. Since we are the only item we just return ourself and 0 for the distance. diff --git a/calendar/gui/e-week-view.c b/calendar/gui/e-week-view.c index cc2f88a385..45021ad3f2 100644 --- a/calendar/gui/e-week-view.c +++ b/calendar/gui/e-week-view.c @@ -767,6 +767,36 @@ get_digit_width (PangoLayout *layout) return max_digit_width; } +static GdkColor +e_week_view_get_text_color (EWeekView *week_view, EWeekViewEvent *event, GtkWidget *widget) +{ + GdkColor color, bg_color; + guint16 red, green, blue; + gdouble cc = 65535.0; + + 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; + + 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; + } + } + + if ((red/cc > 0.7) || (green/cc > 0.7) || (blue/cc > 0.7 )) + color = widget->style->text[GTK_STATE_NORMAL]; + else + color = widget->style->text[GTK_STATE_ACTIVE]; + + return color; +} + static void e_week_view_style_set (GtkWidget *widget, GtkStyle *previous_style) @@ -2675,8 +2705,12 @@ e_week_view_reshape_event_span (EWeekView *week_view, if (!span->text_item) { ECalComponentText cal_text; GtkWidget *widget; + GdkColor color; widget = (GtkWidget *)week_view; + + color = e_week_view_get_text_color (week_view, event, widget); + e_cal_component_get_summary (comp, &cal_text); span->text_item = gnome_canvas_item_new (GNOME_CANVAS_GROUP (GNOME_CANVAS (week_view->main_canvas)->root), @@ -2687,7 +2721,7 @@ e_week_view_reshape_event_span (EWeekView *week_view, "editable", TRUE, "text", cal_text.value ? cal_text.value : "", "use_ellipsis", TRUE, - "fill_color_gdk", &widget->style->text[GTK_STATE_NORMAL], + "fill_color_gdk", &color, "im_context", E_CANVAS (week_view->main_canvas)->im_context, NULL); |