[evolution/clutter-calendar-v2] Add text rendering to the month view.
- From: Srinivasa Ragavan <sragavan src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution/clutter-calendar-v2] Add text rendering to the month view.
- Date: Tue, 14 Sep 2010 08:33:36 +0000 (UTC)
commit bb356dbb27ed2e73ff48ef54f727c4fb1ce26432
Author: Srinivasa Ragavan <sragavan gnome org>
Date: Tue Sep 14 14:00:00 2010 +0530
Add text rendering to the month view.
calendar/gui/Makefile.am | 2 +
calendar/gui/e-week-view-clutter-event-item.c | 1368 +++++++++++++++++++++++++
calendar/gui/e-week-view-clutter-event-item.h | 93 ++
calendar/gui/e-week-view-layout.c | 3 +
calendar/gui/e-week-view.c | 164 +++-
calendar/gui/e-week-view.h | 6 +
6 files changed, 1622 insertions(+), 14 deletions(-)
---
diff --git a/calendar/gui/Makefile.am b/calendar/gui/Makefile.am
index 72e68c9..0bf553e 100644
--- a/calendar/gui/Makefile.am
+++ b/calendar/gui/Makefile.am
@@ -96,6 +96,8 @@ libevolution_calendar_la_SOURCES = \
e-week-view-clutter-titles-item.h \
e-week-view-clutter-main-item.c \
e-week-view-clutter-main-item.h \
+ e-week-view-clutter-event-item.c \
+ e-week-view-clutter-event-item.h \
cal-editor-utils.c \
cal-editor-utils.h \
calendar-config.c \
diff --git a/calendar/gui/e-week-view-clutter-event-item.c b/calendar/gui/e-week-view-clutter-event-item.c
new file mode 100644
index 0000000..6450b42
--- /dev/null
+++ b/calendar/gui/e-week-view-clutter-event-item.c
@@ -0,0 +1,1368 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Srinivasa Ragavan <sragavan gnome org>
+ *
+ * Copyright (C) 2010 Intel Corporation. (www.intel.com)
+ *
+ */
+
+/*
+ * EWeekViewClutterEventItem - displays the background, times and icons for an event
+ * in the week/month views. A separate EText canvas item is used to display &
+ * edit the text.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "e-util/e-categories-config.h"
+#include "e-week-view-clutter-event-item.h"
+
+#include <gtk/gtk.h>
+#include "e-calendar-view.h"
+#include "calendar-config.h"
+#include "comp-util.h"
+
+#include <text/e-text.h>
+
+#include "e-util/gtk-compat.h"
+
+#define E_WEEK_VIEW_CLUTTER_EVENT_ITEM_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_WEEK_VIEW_CLUTTER_EVENT_ITEM, EWeekViewClutterEventItemPrivate))
+
+struct _EWeekViewClutterEventItemPrivate {
+ /* The event index in the EWeekView events array. */
+ gint event_num;
+
+ /* The span index within the event. */
+ gint span_num;
+
+ /* Text */
+ char *text;
+
+ /* Texture */
+ ClutterCairoTexture *texture;
+
+ /* Week View*/
+ EWeekView *week_view;
+
+ int x1;
+ int y1;
+ int x2;
+ int y2;
+ int spanx;
+ int spany;
+};
+
+enum {
+ PROP_0,
+ PROP_EVENT_NUM,
+ PROP_SPAN_NUM,
+ PROP_TEXT
+};
+
+static gpointer parent_class;
+
+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 ECalendarViewPosition
+week_view_clutter_event_item_get_position (EWeekViewClutterEventItem *event_item,
+ gdouble x,
+ gdouble y)
+{
+ EWeekView *week_view;
+ GnomeCanvasItem *item;
+
+ week_view = event_item->priv->week_view;
+
+ if (x < event_item->priv->x1 + E_WEEK_VIEW_EVENT_L_PAD
+ || x >= event_item->priv->x2 - E_WEEK_VIEW_EVENT_R_PAD)
+ return E_CALENDAR_VIEW_POS_NONE;
+
+ /* Support left/right edge for long events only. */
+ if (!e_week_view_is_one_day_event (week_view, event_item->priv->event_num)) {
+ if (x < event_item->priv->x1 + E_WEEK_VIEW_EVENT_L_PAD
+ + E_WEEK_VIEW_EVENT_BORDER_WIDTH
+ + E_WEEK_VIEW_EVENT_EDGE_X_PAD)
+ return E_CALENDAR_VIEW_POS_LEFT_EDGE;
+
+ if (x >= event_item->priv->x2 + 1 - E_WEEK_VIEW_EVENT_R_PAD
+ - E_WEEK_VIEW_EVENT_BORDER_WIDTH
+ - E_WEEK_VIEW_EVENT_EDGE_X_PAD)
+ return E_CALENDAR_VIEW_POS_RIGHT_EDGE;
+ }
+
+ return E_CALENDAR_VIEW_POS_EVENT;
+}
+
+static gboolean
+week_view_clutter_event_item_double_click (EWeekViewClutterEventItem *event_item,
+ ClutterEvent *bevent)
+{
+ EWeekView *week_view;
+ EWeekViewEvent *event;
+ GnomeCanvasItem *item;
+
+ week_view = event_item->priv->week_view;
+
+ if (!is_array_index_in_bounds (week_view->events, event_item->priv->event_num))
+ return TRUE;
+
+ event = &g_array_index (
+ week_view->events, EWeekViewEvent,
+ event_item->priv->event_num);
+
+ if (!is_comp_data_valid (event))
+ return TRUE;
+
+ if (week_view->editing_event_num >= 0) {
+ EWeekViewEvent *editing;
+
+ if (!is_array_index_in_bounds (week_view->events, week_view->editing_event_num))
+ return TRUE;
+
+ editing = &g_array_index (
+ week_view->events, EWeekViewEvent,
+ week_view->editing_event_num);
+
+ /* Do not call edit of the component, if double clicked
+ * on the component, which is not on the server. */
+ if (editing && event &&
+ editing->comp_data == event->comp_data &&
+ is_comp_data_valid (editing) &&
+ (!event->comp_data ||
+ !is_icalcomp_on_the_server (
+ event->comp_data->icalcomp,
+ event->comp_data->client)))
+ return TRUE;
+ }
+
+ e_week_view_stop_editing_event (week_view);
+
+ e_calendar_view_edit_appointment (
+ E_CALENDAR_VIEW (week_view),
+ event->comp_data->client,
+ event->comp_data->icalcomp, FALSE);
+
+ return TRUE;
+}
+
+gboolean
+week_view_clutter_event_item_button_press (EWeekViewClutterEventItem *event_item,
+ ClutterEvent *bevent)
+{
+ EWeekView *week_view;
+ ECalendarViewPosition pos;
+ EWeekViewEvent *event;
+ EWeekViewEventSpan *span;
+
+ week_view = event_item->priv->week_view;
+
+ if (!is_array_index_in_bounds (week_view->events, event_item->priv->event_num))
+ return FALSE;
+
+ event = &g_array_index (
+ week_view->events, EWeekViewEvent,
+ event_item->priv->event_num);
+
+ if (!is_array_index_in_bounds (
+ week_view->spans, event->spans_index +
+ event_item->priv->span_num))
+ return FALSE;
+
+ span = &g_array_index (week_view->spans, EWeekViewEventSpan,
+ event->spans_index + event_item->priv->span_num);
+
+ pos = week_view_clutter_event_item_get_position (event_item, (gdouble)(bevent->button.x-(float)event_item->priv->spanx),
+ (gdouble)(bevent->button.y - (float)event_item->priv->spany) );
+
+ if (pos == E_CALENDAR_VIEW_POS_NONE)
+ return FALSE;
+
+ if (bevent->button.button == 1) {
+ week_view->pressed_event_num = event_item->priv->event_num;
+ week_view->pressed_span_num = event_item->priv->span_num;
+
+ /* Ignore clicks on the event while editing. */
+ if (span->text_item && E_TEXT (span->text_item)->editing)
+ return FALSE;
+
+ /* Remember the item clicked and the mouse position,
+ so we can start a drag if the mouse moves. */
+ week_view->drag_event_x = (gint)bevent->button.x;
+ week_view->drag_event_y = (gint)bevent->button.y;
+
+ /* FIXME: Remember the day offset from the start of the event.
+ */
+
+ return TRUE;
+ } else if (bevent->button.button == 3) {
+ GdkEventButton *gevent = (GdkEventButton *)gdk_event_new (GDK_BUTTON_PRESS);
+
+ if (!gtk_widget_has_focus (GTK_WIDGET (week_view)) && 0) {
+ gtk_widget_grab_focus (GTK_WIDGET (week_view));
+ if (week_view->event_destroyed) {
+ week_view->event_destroyed = FALSE;
+ return FALSE;
+ }
+
+ }
+
+ gevent->time = bevent->button.time;
+ gevent->button = bevent->button.button;
+
+ e_week_view_set_selected_time_range_visible (
+ week_view, event->start, event->end);
+
+ e_week_view_show_popup_menu (
+ week_view, (GdkEventButton*) gevent,
+ event_item->priv->event_num);
+ gdk_event_free (gevent);
+ //g_signal_stop_emission_by_name (
+ // event_item->canvas, "button_press_event");
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static gboolean
+week_view_clutter_event_item_button_release (EWeekViewClutterEventItem *event_item,
+ ClutterEvent *event)
+{
+ EWeekView *week_view;
+
+
+ week_view = event_item->priv->week_view;
+
+ if (week_view->pressed_event_num != -1
+ && week_view->pressed_event_num == event_item->priv->event_num
+ && week_view->pressed_span_num == event_item->priv->span_num) {
+ e_week_view_start_editing_event (week_view,
+ event_item->priv->event_num,
+ event_item->priv->span_num,
+ NULL);
+ week_view->pressed_event_num = -1;
+ return TRUE;
+ }
+
+ week_view->pressed_event_num = -1;
+
+ return FALSE;
+}
+
+static void
+week_view_draw_time (EWeekView *week_view,
+ cairo_t *cr,
+ gint time_x,
+ gint time_y,
+ gint hour,
+ gint minute)
+{
+ ECalModel *model;
+ GtkStyle *style;
+ gint hour_to_display, suffix_width;
+ gint time_y_normal_font, time_y_small_font;
+ const gchar *suffix;
+ gchar buffer[128];
+ GdkColor *fg;
+ PangoLayout *layout;
+ PangoFontDescription *small_font_desc;
+
+ model = e_calendar_view_get_model (E_CALENDAR_VIEW (week_view));
+
+ style = gtk_widget_get_style (GTK_WIDGET (week_view));
+ small_font_desc = week_view->small_font_desc;
+
+ fg = &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);
+
+
+ cairo_save (cr);
+ gdk_cairo_set_source_color (cr, &fg);
+ /* Draw the hour. */
+ if (hour_to_display < 10) {
+ pango_layout_set_text (layout, buffer + 1, 1);
+ cairo_move_to (cr,
+ time_x + week_view->digit_width,
+ time_y_normal_font);
+ pango_cairo_show_layout (cr, layout);
+ } else {
+ pango_layout_set_text (layout, buffer, 2);
+ cairo_move_to (cr,
+ time_x,
+ time_y_normal_font);
+ pango_cairo_show_layout (cr, layout);
+ }
+ cairo_stroke (cr);
+ cairo_restore (cr);
+
+ time_x += week_view->digit_width * 2;
+
+ cairo_save (cr);
+ gdk_cairo_set_source_color (cr, &fg);
+ /* 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);
+ cairo_move_to (cr,
+ time_x,
+ time_y_small_font);
+ pango_cairo_show_layout (cr, layout);
+ cairo_stroke (cr);
+ cairo_restore (cr);
+
+
+ cairo_save (cr);
+ gdk_cairo_set_source_color (cr, &fg);
+ 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_cal_model_get_use_24_hour_format (model)) {
+ pango_layout_set_text (layout, suffix, -1);
+ cairo_move_to (cr,
+ time_x,
+ time_y_normal_font);
+ pango_cairo_show_layout (cr, layout);
+ }
+ cairo_stroke (cr);
+ cairo_restore (cr);
+
+ } else {
+
+ cairo_save (cr);
+ gdk_cairo_set_source_color (cr, &fg);
+ /* 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);
+ cairo_move_to (cr,
+ time_x + week_view->digit_width,
+ time_y_normal_font);
+ pango_cairo_show_layout (cr, layout);
+ } else {
+ pango_layout_set_text (layout, buffer, -1);
+ cairo_move_to (cr,
+ time_x,
+ time_y_normal_font);
+ pango_cairo_show_layout (cr, layout);
+ }
+ cairo_stroke (cr);
+ cairo_restore (cr);
+
+ }
+ g_object_unref (layout);
+}
+
+static gint
+week_view_clutter_event_item_draw_icons (EWeekViewClutterEventItem *event_item,
+ cairo_t *cr,
+ gint icon_x,
+ gint icon_y,
+ gint x2,
+ gboolean right_align,
+ GdkRegion *draw_region)
+{
+ EWeekView *week_view;
+ EWeekViewEvent *event;
+ ECalComponent *comp;
+ GnomeCanvas *canvas;
+ 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;
+ gboolean draw_meeting_icon = FALSE;
+ GSList *categories_pixbufs = NULL, *pixbufs;
+
+ week_view = event_item->priv->week_view;
+
+ if (!is_array_index_in_bounds (week_view->events, event_item->priv->event_num))
+ return icon_x;
+
+ event = &g_array_index (week_view->events, EWeekViewEvent,
+ event_item->priv->event_num);
+
+ if (!is_comp_data_valid (event))
+ return icon_x;
+
+ comp = e_cal_component_new ();
+ e_cal_component_set_icalcomponent (
+ comp, icalcomponent_new_clone (event->comp_data->icalcomp));
+
+ 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 (e_cal_component_has_attendees (comp)) {
+ draw_meeting_icon = TRUE;
+ num_icons++;
+ }
+
+ if (event->different_timezone) {
+ draw_timezone_icon = TRUE;
+ num_icons++;
+ }
+
+ 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;
+
+ #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) {
+ draw_pixbuf (week_view->attach_icon);
+ }
+
+ if (draw_recurrence_icon && icon_x + E_WEEK_VIEW_ICON_WIDTH <= x2) {
+ draw_pixbuf (week_view->recurrence_icon);
+ }
+
+ if (draw_timezone_icon && icon_x + E_WEEK_VIEW_ICON_WIDTH <= x2) {
+ draw_pixbuf (week_view->timezone_icon);
+ }
+
+ if (draw_meeting_icon && icon_x + E_WEEK_VIEW_ICON_WIDTH <= x2) {
+ draw_pixbuf (week_view->meeting_icon);
+ }
+
+ /* draw categories icons */
+ 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);
+
+ g_object_unref(comp);
+
+ return icon_x;
+}
+
+/* This draws a little triangle to indicate that an event extends past
+ the days visible on screen. */
+static void
+week_view_clutter_event_item_draw_triangle (EWeekViewClutterEventItem *event_item,
+ cairo_t *cr,
+ GdkColor bg_color,
+ gint x,
+ gint y,
+ gint w,
+ gint h,
+ GdkRegion *draw_region)
+{
+ ECalModel *model;
+ EWeekView *week_view;
+ EWeekViewEvent *event;
+ GdkPoint points[3];
+ const gchar *color_spec;
+ gint c1, c2;
+
+ if (!can_draw_in_region (draw_region, x, y, w, h))
+ return;
+
+ week_view = event_item->priv->week_view;
+
+ if (!is_array_index_in_bounds (week_view->events, event_item->priv->event_num))
+ return;
+
+ event = &g_array_index (week_view->events, EWeekViewEvent,
+ event_item->priv->event_num);
+
+ if (!is_comp_data_valid (event))
+ return;
+
+ 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;
+
+ model = e_calendar_view_get_model (E_CALENDAR_VIEW (week_view));
+
+ color_spec =
+ e_cal_model_get_color_for_component (model, event->comp_data);
+
+ if (gdk_color_parse (color_spec, &bg_color)) {
+ GdkColormap *colormap;
+
+ colormap = gtk_widget_get_colormap (GTK_WIDGET (week_view));
+ if (gdk_colormap_alloc_color (colormap, &bg_color, TRUE, TRUE)) {
+ gdk_cairo_set_source_color (cr, &bg_color);
+ } else {
+ EWeekViewColors wvc;
+ GdkColor *color;
+
+ wvc = E_WEEK_VIEW_COLOR_EVENT_BACKGROUND;
+ color = &week_view->colors[wvc];
+
+ gdk_cairo_set_source_color (cr, color);
+ }
+ } else {
+ EWeekViewColors wvc;
+ GdkColor *color;
+
+ wvc = E_WEEK_VIEW_COLOR_EVENT_BACKGROUND;
+ color = &week_view->colors[wvc];
+
+ gdk_cairo_set_source_color (cr, color);
+ }
+
+ cairo_save (cr);
+ cairo_set_line_width (cr, 0.7);
+ cairo_move_to (cr, points[0].x, points[0].y);
+ cairo_line_to (cr, points[1].x, points[1].y);
+ cairo_line_to (cr, points[2].x, points[2].y);
+ cairo_line_to (cr, points[0].x, points[0].y);
+ cairo_fill (cr);
+ cairo_restore (cr);
+
+ cairo_save (cr);
+ gdk_cairo_set_source_color (cr, &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--;
+
+ cairo_set_line_width (cr, 0.7);
+ cairo_move_to (cr, x, y);
+ cairo_line_to (cr, x + w, c1);
+ cairo_move_to (cr, x, y + h - 1);
+ cairo_line_to (cr, x + w, c2);
+ cairo_restore (cr);
+
+}
+
+static void
+week_view_clutter_event_item_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_EVENT_NUM:
+ e_week_view_clutter_event_item_set_event_num (
+ E_WEEK_VIEW_CLUTTER_EVENT_ITEM (object),
+ g_value_get_int (value));
+ return;
+
+ case PROP_SPAN_NUM:
+ e_week_view_clutter_event_item_set_span_num (
+ E_WEEK_VIEW_CLUTTER_EVENT_ITEM (object),
+ g_value_get_int (value));
+ case PROP_TEXT:
+ e_week_view_clutter_event_item_set_text (
+ E_WEEK_VIEW_CLUTTER_EVENT_ITEM (object),
+ g_value_get_string (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+week_view_clutter_event_item_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_EVENT_NUM:
+ g_value_set_int (
+ value,
+ e_week_view_clutter_event_item_get_event_num (
+ E_WEEK_VIEW_CLUTTER_EVENT_ITEM (object)));
+ return;
+
+ case PROP_SPAN_NUM:
+ g_value_set_int (
+ value,
+ e_week_view_clutter_event_item_get_span_num (
+ E_WEEK_VIEW_CLUTTER_EVENT_ITEM (object)));
+ case PROP_TEXT:
+ g_value_set_string (
+ value,
+ e_week_view_clutter_event_item_get_text (
+ E_WEEK_VIEW_CLUTTER_EVENT_ITEM (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+week_view_clutter_event_item_draw (EWeekViewClutterEventItem *canvas_item)
+{
+ EWeekViewClutterEventItem *event_item;
+ EWeekView *week_view;
+ EWeekViewEvent *event;
+ EWeekViewEventSpan *span;
+ ECalModel *model;
+ 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 = 0;
+ 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;
+ cairo_t *cr;
+ cairo_pattern_t *pat;
+ guint16 red, green, blue;
+ gdouble radius, cx0, cy0, rect_height, rect_width;
+ gboolean gradient;
+ gdouble cc = 65535.0;
+ GdkRegion *draw_region;
+ GdkRectangle rect;
+ const gchar *color_spec;
+ int x=0,y=0;
+ int width, height;
+ gint span_x, span_y, span_w;
+
+ event_item = E_WEEK_VIEW_CLUTTER_EVENT_ITEM (canvas_item);
+
+ week_view = event_item->priv->week_view;
+
+ if (event_item->priv->event_num == -1 || event_item->priv->span_num == -1)
+ return;
+
+ g_return_if_fail (event_item->priv->event_num < week_view->events->len);
+
+ if (!is_array_index_in_bounds (week_view->events, event_item->priv->event_num))
+ return;
+
+ event = &g_array_index (week_view->events, EWeekViewEvent,
+ event_item->priv->event_num);
+
+ if (!is_comp_data_valid (event))
+ return;
+
+ g_return_if_fail (
+ event->spans_index + event_item->priv->span_num <
+ week_view->spans->len);
+
+ if (!is_array_index_in_bounds (
+ week_view->spans, event->spans_index +
+ event_item->priv->span_num))
+ return;
+
+ span = &g_array_index (
+ week_view->spans, EWeekViewEventSpan,
+ event->spans_index + event_item->priv->span_num);
+
+ if (e_week_view_get_span_position (
+ week_view, event_item->priv->event_num, event_item->priv->span_num,
+ &span_x, &span_y, &span_w)) {
+ x1 = 0;
+ y1 = 0;
+ x2 = span_w - 1;
+ y2 = week_view->row_height - 1;
+ }
+
+ event_item->priv->x1 = 0;
+ event_item->priv->y1 = 0;
+ event_item->priv->x2 = span_w;
+ event_item->priv->y2 = week_view->row_height;
+ event_item->priv->spanx = span_x;
+ event_item->priv->spany = span_y;
+ gc = week_view->main_gc;
+
+ if (x1 == x2 || y1 == y2)
+ return;
+
+ rect.x = 0;
+ rect.y = 0;
+ rect.width = x2-x1;
+ rect.height = y2-y1;
+ draw_region = gdk_region_rectangle (&rect);
+ x1 = 0; y1 = 0;
+ x2 = rect.width;
+ clutter_cairo_texture_set_surface_size (event_item->priv->texture, rect.width, rect.height);
+ clutter_actor_set_position (event_item, span_x, span_y);
+ if (!can_draw_in_region (draw_region, x1, y1, x2 - x1, y2 - y1)) {
+ gdk_region_destroy (draw_region);
+ return;
+ }
+
+ clutter_cairo_texture_clear (event_item->priv->texture);
+ cr = clutter_cairo_texture_create (event_item->priv->texture);
+ gradient = calendar_config_get_display_events_gradient ();
+
+ 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, event_item->priv->event_num);
+
+ model = e_calendar_view_get_model (E_CALENDAR_VIEW (week_view));
+
+ color_spec =
+ e_cal_model_get_color_for_component (model, event->comp_data);
+
+ bg_color = week_view->colors[E_WEEK_VIEW_COLOR_EVENT_BACKGROUND];
+ if (gdk_color_parse (color_spec, &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;
+
+ /* Here we draw the border around the event*/
+ cx0 = rect_x;
+ cy0 = y1 + 1;
+ rect_width = rect_w;
+ rect_height = y2 - y1 - 1;
+
+ radius = 12;
+
+ 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 */
+
+ cx0 = rect_x + 1.5;
+ cy0 = y1 + 2.75;
+ rect_width = rect_w - 3.;
+ rect_height = y2 - y1 - 4.5;
+
+ radius = 8;
+
+ 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);
+ }
+
+ /* 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_return_if_reached ();
+ draw_start = FALSE;
+ draw_end = FALSE;
+ break;
+ }
+
+ if (draw_start) {
+ week_view_draw_time (
+ week_view, cr, time_x,
+ time_y, start_hour, start_minute);
+ time_x += time_width;
+ }
+
+ if (draw_end) {
+ time_x += E_WEEK_VIEW_EVENT_TIME_SPACING;
+ week_view_draw_time (
+ week_view, cr, 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. */
+ icon_x = week_view_clutter_event_item_draw_icons (
+ event_item, cr, icon_x,
+ icon_y, x2, FALSE, draw_region);
+
+ /* Draw text */
+ if (icon_x < x2) {
+ PangoLayout *layout;
+ GdkColor col = e_week_view_get_text_color (week_view, event, week_view);
+
+ cairo_save (cr);
+ gdk_cairo_set_source_color (cr, &col);
+
+ icon_x += E_WEEK_VIEW_EVENT_TIME_X_PAD;
+
+ cairo_rectangle (cr, icon_x , 0, x2-icon_x, week_view->row_height);
+ cairo_clip (cr);
+ layout = gtk_widget_create_pango_layout (GTK_WIDGET (week_view), NULL);
+ pango_layout_set_text (layout, event_item->priv->text, -1);
+ cairo_move_to (cr,
+ icon_x,
+ E_WEEK_VIEW_EVENT_BORDER_HEIGHT + E_WEEK_VIEW_ICON_Y_PAD);
+
+ pango_cairo_show_layout (cr, layout);
+
+ cairo_stroke (cr);
+ cairo_restore (cr);
+ g_object_unref (layout);
+ }
+
+
+ } 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;
+ }
+
+ /* Here we draw the border around the event */
+
+ cx0 = rect_x;
+ cy0 = y1 + 1;
+ rect_width = rect_w;
+ rect_height = y2 - y1 - 1;
+
+ radius = 12;
+
+ 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*/
+
+ cx0 = rect_x + 1.5;
+ cy0 = y1 + 2.75;
+ rect_width = rect_w - 3.;
+ rect_height = y2 - y1 - 4.5;
+
+ radius = 8;
+
+ 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);
+ }
+
+ if (draw_start_triangle) {
+ week_view_clutter_event_item_draw_triangle (
+ event_item, cr, 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)) {
+ EWeekViewColors wvc;
+ GdkColor *color;
+
+ wvc = E_WEEK_VIEW_COLOR_EVENT_BORDER;
+ color = &week_view->colors[wvc];
+
+ cairo_save (cr);
+ gdk_cairo_set_source_color (cr, color);
+ cairo_set_line_width (cr, 0.7);
+ cairo_move_to (cr, rect_x, y1);
+ cairo_line_to (cr, rect_x, y2);
+ cairo_stroke (cr);
+ cairo_restore (cr);
+ }
+
+ if (draw_end_triangle) {
+ week_view_clutter_event_item_draw_triangle (
+ event_item, cr, 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)) {
+ EWeekViewColors wvc;
+ GdkColor *color;
+
+ wvc = E_WEEK_VIEW_COLOR_EVENT_BORDER;
+ color = &week_view->colors[wvc];
+
+ cairo_save (cr);
+ gdk_cairo_set_source_color (cr, color);
+ cairo_set_line_width (cr, 0.7);
+ /* rect_x2 is used uninitialized here */
+ cairo_move_to (cr, rect_x2, y2);
+ cairo_line_to (cr, rect_x2, y2);
+ cairo_stroke (cr);
+ cairo_restore (cr);
+ }
+
+ 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;
+ 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;
+
+ week_view_draw_time (
+ week_view, cr, time_x,
+ time_y, start_hour, start_minute);
+
+ /* 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;
+
+ 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;
+ 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) {
+ week_view_draw_time (
+ week_view, cr, time_x,
+ time_y, end_hour, end_minute);
+ max_icon_x -= time_width
+ + E_WEEK_VIEW_EVENT_TIME_X_PAD;
+ }
+ }
+
+ icon_x = min_end_time_x;
+ /* Draw the icons. */
+ if (
+ (week_view->editing_event_num != event_item->priv->event_num
+ || week_view->editing_span_num != event_item->priv->span_num)) {
+ icon_x = min_end_time_x;
+ icon_x += E_WEEK_VIEW_EVENT_TIME_X_PAD;
+ icon_x = week_view_clutter_event_item_draw_icons (
+ event_item, cr, icon_x,
+ icon_y, max_icon_x, FALSE, draw_region);
+ }
+
+ /* Draw text */
+ if (icon_x < time_x) {
+ PangoLayout *layout;
+ GdkColor col = e_week_view_get_text_color (week_view, event, week_view);
+
+ cairo_save (cr);
+ gdk_cairo_set_source_color (cr, &col);
+
+ icon_x += E_WEEK_VIEW_EVENT_TIME_X_PAD;
+
+ cairo_rectangle (cr, icon_x , 0, time_x-icon_x, week_view->row_height);
+ cairo_clip (cr);
+ layout = gtk_widget_create_pango_layout (GTK_WIDGET (week_view), NULL);
+ pango_layout_set_text (layout, event_item->priv->text, -1);
+ cairo_move_to (cr,
+ icon_x,
+ E_WEEK_VIEW_EVENT_BORDER_HEIGHT + E_WEEK_VIEW_ICON_Y_PAD);
+
+ pango_cairo_show_layout (cr, layout);
+
+ cairo_stroke (cr);
+ cairo_restore (cr);
+ g_object_unref (layout);
+ }
+
+ }
+ cairo_destroy (cr);
+
+ gdk_region_destroy (draw_region);
+}
+
+static gint
+week_view_clutter_event_item_event (GnomeCanvasItem *item,
+ ClutterEvent *event)
+{
+ EWeekViewClutterEventItem *event_item;
+
+ event_item = E_WEEK_VIEW_CLUTTER_EVENT_ITEM (item);
+
+ switch (event->type) {
+ case CLUTTER_BUTTON_PRESS:
+ if (event->button.click_count > 1)
+ return week_view_clutter_event_item_double_click (event_item, event);
+ else
+ return week_view_clutter_event_item_button_press (event_item, event);
+ case CLUTTER_BUTTON_RELEASE:
+ return week_view_clutter_event_item_button_release (event_item, event);
+ case CLUTTER_MOTION:
+ break;
+ default:
+ break;
+ }
+
+ return FALSE;
+}
+
+static void
+week_view_clutter_event_item_class_init (EWeekViewClutterEventItemClass *class)
+{
+ GObjectClass *object_class;
+ MxBoxLayoutClass *item_class;
+ ClutterActorClass *widget_class;
+
+ parent_class = g_type_class_peek_parent (class);
+ g_type_class_add_private (class, sizeof (EWeekViewClutterEventItemPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = week_view_clutter_event_item_set_property;
+ object_class->get_property = week_view_clutter_event_item_get_property;
+
+ item_class = MX_BOX_LAYOUT_CLASS (class);
+ //item_class->update = week_view_clutter_event_item_update;
+ //item_class->draw = week_view_clutter_event_item_draw;
+ //item_class->point = week_view_clutter_event_item_point;
+ CLUTTER_ACTOR_CLASS(item_class)->event = week_view_clutter_event_item_event;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_EVENT_NUM,
+ g_param_spec_int (
+ "event-num",
+ "Event Num",
+ NULL,
+ G_MININT,
+ G_MAXINT,
+ -1,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SPAN_NUM,
+ g_param_spec_int (
+ "span-num",
+ "Span Num",
+ NULL,
+ G_MININT,
+ G_MAXINT,
+ -1,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (
+ object_class,
+ PROP_TEXT,
+ g_param_spec_string (
+ "text",
+ "Summry Text",
+ NULL,
+ NULL,
+ G_PARAM_READWRITE));
+}
+
+static void
+week_view_clutter_event_item_init (EWeekViewClutterEventItem *event_item)
+{
+ event_item->priv = E_WEEK_VIEW_CLUTTER_EVENT_ITEM_GET_PRIVATE (event_item);
+
+ event_item->priv->event_num = -1;
+ event_item->priv->span_num = -1;
+}
+
+GType
+e_week_view_clutter_event_item_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0)) {
+ const GTypeInfo type_info = {
+ sizeof (EWeekViewClutterEventItemClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) week_view_clutter_event_item_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (EWeekViewClutterEventItem),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) week_view_clutter_event_item_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (
+ MX_TYPE_BOX_LAYOUT, "EWeekViewClutterEventItem",
+ &type_info, 0);
+ }
+
+ return type;
+}
+
+gint
+e_week_view_clutter_event_item_get_event_num (EWeekViewClutterEventItem *event_item)
+{
+ g_return_val_if_fail (E_IS_WEEK_VIEW_CLUTTER_EVENT_ITEM (event_item), -1);
+
+ return event_item->priv->event_num;
+}
+
+void
+e_week_view_clutter_event_item_set_event_num (EWeekViewClutterEventItem *event_item,
+ gint event_num)
+{
+ g_return_if_fail (E_IS_WEEK_VIEW_CLUTTER_EVENT_ITEM (event_item));
+
+ event_item->priv->event_num = event_num;
+ week_view_clutter_event_item_draw (event_item);
+
+ g_object_notify (G_OBJECT (event_item), "event-num");
+}
+
+const char *
+e_week_view_clutter_event_item_get_text (EWeekViewClutterEventItem *event_item)
+{
+ g_return_val_if_fail (E_IS_WEEK_VIEW_CLUTTER_EVENT_ITEM (event_item), -1);
+
+ return event_item->priv->text;
+}
+
+void
+e_week_view_clutter_event_item_set_text (EWeekViewClutterEventItem *event_item,
+ const char *txt)
+{
+ g_return_if_fail (E_IS_WEEK_VIEW_CLUTTER_EVENT_ITEM (event_item));
+
+ if (event_item->priv->text)
+ g_free (event_item->priv->text);
+
+ event_item->priv->text = g_strdup (txt);
+ week_view_clutter_event_item_draw (event_item);
+
+ g_object_notify (G_OBJECT (event_item), "text");
+}
+
+gint
+e_week_view_clutter_event_item_get_span_num (EWeekViewClutterEventItem *event_item)
+{
+ g_return_val_if_fail (E_IS_WEEK_VIEW_CLUTTER_EVENT_ITEM (event_item), -1);
+
+ return event_item->priv->span_num;
+}
+
+void
+e_week_view_clutter_event_item_set_span_num (EWeekViewClutterEventItem *event_item,
+ gint span_num)
+{
+ g_return_if_fail (E_IS_WEEK_VIEW_CLUTTER_EVENT_ITEM (event_item));
+
+ event_item->priv->span_num = span_num;
+ week_view_clutter_event_item_draw (event_item);
+
+ g_object_notify (G_OBJECT (event_item), "span-num");
+}
+
+EWeekViewClutterEventItem *
+e_week_view_clutter_event_item_new (EWeekView *view)
+{
+ EWeekViewClutterEventItem *item = g_object_new (E_TYPE_WEEK_VIEW_CLUTTER_EVENT_ITEM, NULL);
+ MxBoxLayout *box = (MxBoxLayout *)item;
+
+ item->priv->week_view = view;
+ item->priv->texture = clutter_cairo_texture_new (10, view->row_height);
+ clutter_actor_set_reactive (item->priv->texture, TRUE);
+
+ mx_box_layout_set_orientation (box, MX_ORIENTATION_VERTICAL);
+ mx_box_layout_add_actor (box,
+ item->priv->texture, -1);
+ clutter_container_child_set (CLUTTER_CONTAINER (box),
+ item->priv->texture,
+ "expand", TRUE,
+ "x-fill", TRUE,
+ "y-fill", TRUE,
+ NULL);
+ clutter_actor_show_all (box);
+ clutter_actor_set_reactive (box, TRUE);
+
+ return item;
+}
+
+void
+e_week_view_clutter_event_item_redraw (EWeekViewClutterEventItem *item)
+{
+ week_view_clutter_event_item_draw (item);
+}
+
diff --git a/calendar/gui/e-week-view-clutter-event-item.h b/calendar/gui/e-week-view-clutter-event-item.h
new file mode 100644
index 0000000..e23a074
--- /dev/null
+++ b/calendar/gui/e-week-view-clutter-event-item.h
@@ -0,0 +1,93 @@
+/*
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Srinivasa Ragavan <sragavan gnome org>
+ *
+ * Copyright (C) 2010 Intel Corporation. (www.intel.com)
+ *
+ */
+
+/*
+ * EWeekViewClutterEventItem - displays the background, times and icons for an event
+ * in the week/month views. A separate EText canvas item is used to display &
+ * edit the text.
+ */
+
+#ifndef E_WEEK_VIEW_CLUTTER_EVENT_ITEM_H
+#define E_WEEK_VIEW_CLUTTER_EVENT_ITEM_H
+
+#include "e-week-view.h"
+
+/* Standard GObject macros */
+#define E_TYPE_WEEK_VIEW_CLUTTER_EVENT_ITEM \
+ (e_week_view_clutter_event_item_get_type ())
+#define E_WEEK_VIEW_CLUTTER_EVENT_ITEM(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_WEEK_VIEW_CLUTTER_EVENT_ITEM, EWeekViewClutterEventItem))
+#define E_WEEK_VIEW_CLUTTER_EVENT_ITEM_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_WEEK_VIEW_CLUTTER_EVENT_ITEM, EWeekViewClutterEventItemClass))
+#define E_IS_WEEK_VIEW_CLUTTER_EVENT_ITEM(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_WEEK_VIEW_CLUTTER_EVENT_ITEM))
+#define E_IS_WEEK_VIEW_CLUTTER_EVENT_ITEM_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_WEEK_VIEW_CLUTTER_EVENT_ITEM))
+#define E_WEEK_VIEW_CLUTTER_EVENT_ITEM_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_WEEK_VIEW_CLUTTER_EVENT_ITEM, EWeekViewClutterEventItemClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EWeekViewClutterEventItem EWeekViewClutterEventItem;
+typedef struct _EWeekViewClutterEventItemClass EWeekViewClutterEventItemClass;
+typedef struct _EWeekViewClutterEventItemPrivate EWeekViewClutterEventItemPrivate;
+
+struct _EWeekViewClutterEventItem {
+ MxBoxLayout parent;
+ EWeekViewClutterEventItemPrivate *priv;
+};
+
+struct _EWeekViewClutterEventItemClass {
+ MxBoxLayoutClass parent_class;
+};
+
+GType e_week_view_clutter_event_item_get_type (void);
+gint e_week_view_clutter_event_item_get_event_num
+ (EWeekViewClutterEventItem *event_item);
+void e_week_view_clutter_event_item_set_event_num
+ (EWeekViewClutterEventItem *event_item,
+ gint event_num);
+gint e_week_view_clutter_event_item_get_span_num
+ (EWeekViewClutterEventItem *event_item);
+void e_week_view_clutter_event_item_set_span_num
+ (EWeekViewClutterEventItem *event_item,
+ gint span_num);
+void e_week_view_clutter_event_item_redraw
+ (EWeekViewClutterEventItem *item);
+const char * e_week_view_clutter_event_item_get_text
+ (EWeekViewClutterEventItem *event_item);
+void e_week_view_clutter_event_item_set_text
+ (EWeekViewClutterEventItem *event_item,
+ const char *txt);
+
+EWeekViewClutterEventItem * e_week_view_clutter_event_item_new (EWeekView *view);
+
+
+G_END_DECLS
+
+#endif /* E_WEEK_VIEW_CLUTTER_EVENT_ITEM_H */
diff --git a/calendar/gui/e-week-view-layout.c b/calendar/gui/e-week-view-layout.c
index 7863791..59f3280 100644
--- a/calendar/gui/e-week-view-layout.c
+++ b/calendar/gui/e-week-view-layout.c
@@ -187,6 +187,9 @@ e_week_view_layout_event (EWeekViewEvent *event,
span.num_days = span_end_day - span_start_day + 1;
span.row = free_row;
span.background_item = NULL;
+#if HAVE_CLUTTER
+ span.actor_item = NULL;
+#endif
span.text_item = NULL;
if (event->num_spans > span_num) {
old_span = &g_array_index (
diff --git a/calendar/gui/e-week-view.c b/calendar/gui/e-week-view.c
index 0db71c0..3769dda 100644
--- a/calendar/gui/e-week-view.c
+++ b/calendar/gui/e-week-view.c
@@ -65,6 +65,7 @@
#if HAVE_CLUTTER
#include "e-week-view-clutter-titles-item.h"
#include "e-week-view-clutter-main-item.h"
+#include "e-week-view-clutter-event-item.h"
#endif
#define WITHOUT_CLUTTER (g_getenv("WITHOUT_CLUTTER") != NULL)
@@ -122,15 +123,31 @@ static void e_week_view_paste_text (ECalendarView *week_view);
static void e_week_view_update_query (EWeekView *week_view);
static void e_week_view_draw_shadow (EWeekView *week_view);
+#if HAVE_CLUTTER
+static gboolean
+week_view_clutter_button_press (ClutterActor *actor,
+ ClutterEvent *event,
+ EWeekView *week_view);
+#endif
static gboolean e_week_view_on_button_press (GtkWidget *widget,
GdkEventButton *event,
EWeekView *week_view);
+#if HAVE_CLUTTER
+static gboolean e_week_view_on_clutter_button_release (ClutterActor *actor,
+ ClutterButtonEvent *event,
+ EWeekView *week_view);
+#endif
static gboolean e_week_view_on_button_release (GtkWidget *widget,
GdkEventButton *event,
EWeekView *week_view);
static gboolean e_week_view_on_scroll (GtkWidget *widget,
GdkEventScroll *scroll,
EWeekView *week_view);
+#if HAVE_CLUTTER
+static gboolean e_week_view_on_clutter_motion (ClutterActor *actor,
+ ClutterMotionEvent *event,
+ EWeekView *week_view);
+#endif
static gboolean e_week_view_on_motion (GtkWidget *widget,
GdkEventMotion *event,
EWeekView *week_view);
@@ -949,6 +966,12 @@ e_week_view_init (EWeekView *week_view)
e_week_view_main_item_get_type (),
"EWeekViewMainItem::week_view", week_view,
NULL);
+ g_signal_connect_after (week_view->main_canvas, "button_press_event",
+ G_CALLBACK (e_week_view_on_button_press), week_view);
+ g_signal_connect (week_view->main_canvas, "button_release_event",
+ G_CALLBACK (e_week_view_on_button_release), week_view);
+ g_signal_connect (week_view->main_canvas, "motion_notify_event",
+ G_CALLBACK (e_week_view_on_motion), week_view);
#if HAVE_CLUTTER
} else {
week_view->main_canvas_embed = gtk_clutter_embed_new ();
@@ -964,20 +987,21 @@ e_week_view_init (EWeekView *week_view)
"surface-width", 300,
"surface-height", 50,
NULL);
- clutter_actor_set_reactive (week_view->main_canvas_actor, FALSE);
+ clutter_actor_set_reactive (week_view->main_canvas_actor, TRUE);
clutter_container_add_actor ((ClutterContainer *)week_view->main_canvas_stage, (ClutterActor *)week_view->main_canvas_actor);
clutter_actor_show ((ClutterActor *)week_view->main_canvas_actor);
-
+ g_signal_connect_after (week_view->main_canvas_actor, "button-press-event",
+ G_CALLBACK (week_view_clutter_button_press), week_view);
+ g_signal_connect (week_view->main_canvas_actor, "button-release-event",
+ G_CALLBACK (e_week_view_on_clutter_button_release), week_view);
+ g_signal_connect (week_view->main_canvas_actor, "motion-event",
+ G_CALLBACK (e_week_view_on_clutter_motion), week_view);
+
}
#endif
- g_signal_connect_after (week_view->main_canvas, "button_press_event",
- G_CALLBACK (e_week_view_on_button_press), week_view);
- g_signal_connect (week_view->main_canvas, "button_release_event",
- G_CALLBACK (e_week_view_on_button_release), week_view);
+
g_signal_connect (week_view->main_canvas, "scroll_event",
G_CALLBACK (e_week_view_on_scroll), week_view);
- g_signal_connect (week_view->main_canvas, "motion_notify_event",
- G_CALLBACK (e_week_view_on_motion), week_view);
/* Create the buttons to jump to each days. */
pixbuf = gdk_pixbuf_new_from_xpm_data ((const gchar **) jump_xpm);
@@ -1215,7 +1239,7 @@ get_digit_width (PangoLayout *layout)
return max_digit_width;
}
-static GdkColor
+GdkColor
e_week_view_get_text_color (EWeekView *week_view, EWeekViewEvent *event, GtkWidget *widget)
{
GtkStyle *style;
@@ -2687,7 +2711,7 @@ e_week_view_on_button_press (GtkWidget *widget,
window = gtk_layout_get_bin_window (GTK_LAYOUT (widget));
- if (gdk_pointer_grab (window, FALSE,
+ if (!WITHOUT_CLUTTER || gdk_pointer_grab (window, FALSE,
GDK_POINTER_MOTION_MASK
| GDK_BUTTON_RELEASE_MASK,
NULL, NULL, event->time) == 0) {
@@ -2737,6 +2761,56 @@ e_week_view_on_button_press (GtkWidget *widget,
return TRUE;
}
+#if HAVE_CLUTTER
+static gboolean
+week_view_clutter_button_press (ClutterActor *actor,
+ ClutterEvent *event,
+ EWeekView *week_view)
+{
+ GdkEventButton *bevent;
+ gboolean ret;
+
+ if (event->button.click_count > 1 )
+ bevent = gdk_event_new (GDK_2BUTTON_PRESS);
+ else
+ bevent = gdk_event_new (GDK_BUTTON_PRESS);
+
+ bevent->time = event->button.time;
+ bevent->button = event->button.button;
+ bevent->x = (gfloat) event->button.x;
+ bevent->y = (gfloat) event->button.y;
+ ret = e_week_view_on_button_press (week_view->main_canvas, bevent, week_view);
+
+ gdk_event_free (bevent);
+
+ return ret;
+}
+#endif
+
+#if HAVE_CLUTTER
+static gboolean
+e_week_view_on_clutter_button_release (ClutterActor *actor,
+ ClutterButtonEvent *event,
+ EWeekView *week_view)
+{
+ GdkEventButton *bevent;
+ gboolean ret;
+
+ bevent = gdk_event_new (GDK_BUTTON_RELEASE);
+
+ bevent->time = event->time;
+ bevent->button = event->button;
+ bevent->x = (gfloat) event->x;
+ bevent->y = (gfloat) event->y;
+ ret = e_week_view_on_button_release (week_view->main_canvas, bevent, week_view);
+
+ gdk_event_free (bevent);
+
+ return ret;
+}
+
+#endif
+
static gboolean
e_week_view_on_button_release (GtkWidget *widget,
GdkEventButton *event,
@@ -2809,6 +2883,27 @@ e_week_view_on_scroll (GtkWidget *widget,
return TRUE;
}
+#if HAVE_CLUTTER
+static gboolean
+e_week_view_on_clutter_motion (ClutterActor *actor,
+ ClutterMotionEvent *event,
+ EWeekView *week_view)
+{
+ GdkEventButton *bevent;
+ gboolean ret;
+
+ bevent = gdk_event_new (GDK_MOTION_NOTIFY);
+
+ bevent->time = event->time;
+ bevent->x = (gfloat) event->x;
+ bevent->y = (gfloat) event->y;
+ ret = e_week_view_on_motion (week_view->main_canvas, bevent, week_view);
+
+ gdk_event_free (bevent);
+
+ return ret;
+}
+#endif
static gboolean
e_week_view_on_motion (GtkWidget *widget,
GdkEventMotion *mevent,
@@ -3306,7 +3401,7 @@ e_week_view_reshape_event_span (EWeekView *week_view,
gboolean one_day_event;
ECalComponent *comp;
gdouble text_x, text_y, text_w, text_h;
- gchar *text, *end_of_line;
+ gchar *text=NULL, *end_of_line;
gint line_len, text_width;
PangoFontDescription *font_desc;
PangoContext *pango_context;
@@ -3377,14 +3472,16 @@ e_week_view_reshape_event_span (EWeekView *week_view,
num_icons += cal_comp_util_get_n_icons (comp, NULL);
}
+#if HAVE_CLUTTER
+ if (WITHOUT_CLUTTER) {
+#endif
/* Create the background canvas item if necessary. */
if (!span->background_item) {
span->background_item =
gnome_canvas_item_new (GNOME_CANVAS_GROUP (GNOME_CANVAS (week_view->main_canvas)->root),
e_week_view_event_item_get_type (),
NULL);
- }
-
+
g_object_set_data ((GObject *)span->background_item, "event-num", GINT_TO_POINTER (event_num));
g_signal_connect (span->background_item, "event",
G_CALLBACK (tooltip_event_cb),
@@ -3394,9 +3491,48 @@ e_week_view_reshape_event_span (EWeekView *week_view,
"event_num", event_num,
"span_num", span_num,
NULL);
+ }
+#if HAVE_CLUTTER
+ } else {
+ char *summary;
+ gboolean free_text = FALSE;
+
+ summary = e_calendar_view_get_icalcomponent_summary (event->comp_data->client, event->comp_data->icalcomp, &free_text);
+
+ /* Create the background canvas item if necessary. */
+ if (!span->actor_item) {
+ span->actor_item = e_week_view_clutter_event_item_new (week_view);
+
+ //g_object_set_data ((GObject *)span->background_item, "event-num", GINT_TO_POINTER (event_num));
+ //g_signal_connect (span->background_item, "event",
+ // G_CALLBACK (tooltip_event_cb),
+ // week_view);
+
+ g_object_set (span->actor_item,
+ "event_num", event_num,
+ "span_num", span_num,
+ "text", summary ? summary : "",
+ NULL);
+ e_week_view_clutter_event_item_redraw (span->actor_item);
+ clutter_container_add_actor (week_view->main_canvas_stage, span->actor_item);
+ clutter_actor_raise_top (span->actor_item);
+ } else {
+ g_object_set (span->actor_item,
+ "event_num", event_num,
+ "span_num", span_num,
+ "text", summary ? summary : "",
+ NULL);
+ e_week_view_clutter_event_item_redraw (span->actor_item);
+ }
+ if (free_text)
+ g_free ((gchar *)summary);
+
+ }
+#endif
+
/* Create the text item if necessary. */
- if (!span->text_item) {
+ if (!span->text_item && 0) {
const gchar *summary;
GtkWidget *widget;
GdkColor color;
diff --git a/calendar/gui/e-week-view.h b/calendar/gui/e-week-view.h
index 2115f7d..d4f0dfd 100644
--- a/calendar/gui/e-week-view.h
+++ b/calendar/gui/e-week-view.h
@@ -162,6 +162,9 @@ struct _EWeekViewEventSpan {
guint row : 7;
GnomeCanvasItem *background_item;
GnomeCanvasItem *text_item;
+#if HAVE_CLUTTER
+ ClutterActor *actor_item;
+#endif
};
typedef struct _EWeekViewEvent EWeekViewEvent;
@@ -485,6 +488,9 @@ void e_week_view_jump_to_button_item (EWeekView *week_view,
GnomeCanvasItem *item);
void e_week_view_scroll_a_step (EWeekView *week_view,
ECalViewMoveDirection direction);
+GdkColor e_week_view_get_text_color (EWeekView *week_view,
+ EWeekViewEvent *event,
+ GtkWidget *widget);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]