From eef3c90f45363207c22b664894dcf5a70779c257 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erick=20P=C3=A9rez=20Castellanos?= Date: Thu, 17 May 2012 14:56:28 -0400 Subject: [PATCH] Converted GcalMonthView to GtkContainer subclass. Added gcal_view_add_event method GcalView interface. Fixed size_allocate implementation in GcalMonthView to allocate children events. There's still work to be done here. --- src/gcal-month-view.c | 193 ++++++++++++++++++++++++++++++------------ src/gcal-month-view.h | 4 +- src/gcal-view.c | 9 ++ src/gcal-view.h | 10 ++- src/gcal-window.c | 35 ++++++-- 5 files changed, 188 insertions(+), 63 deletions(-) diff --git a/src/gcal-month-view.c b/src/gcal-month-view.c index 42a359f6..bd9f6669 100644 --- a/src/gcal-month-view.c +++ b/src/gcal-month-view.c @@ -21,6 +21,7 @@ #include "gcal-month-view.h" #include "gcal-utils.h" #include "gcal-view.h" +#include "gcal-event-widget.h" #include @@ -32,12 +33,14 @@ enum struct _GcalMonthViewPrivate { + GList *events; + GdkWindow *event_window; icaltimetype *date; + gint days_delay; gint header_font_size; - gdouble vertical_step; gdouble horizontal_step; }; @@ -56,9 +59,6 @@ const char* weekdays [] = static void _gcal_view_interface_init (GcalViewIface *iface); -static gboolean _gcal_month_view_is_in_range (GcalView *view, - icaltimetype *date); - static void gcal_month_view_set_property (GObject *object, guint property_id, const GValue *value, @@ -69,6 +69,8 @@ static void gcal_month_view_get_property (GObject *object, GValue *value, GParamSpec *pspec); +static void gcal_month_view_finalize (GObject *object); + static void gcal_month_view_realize (GtkWidget *widget); static void gcal_month_view_unrealize (GtkWidget *widget); @@ -83,27 +85,38 @@ static void gcal_month_view_size_allocate (GtkWidget *widget, static gboolean gcal_month_view_draw (GtkWidget *widget, cairo_t *cr); -static void gcal_month_view_finalize (GObject *object); +static void gcal_month_view_forall (GtkContainer *container, + gboolean include_internals, + GtkCallback callback, + gpointer callback_data); static void _gcal_month_view_draw_month_grid (GcalMonthView *mont_view, cairo_t *cr, gint x, - gint y, - gint width, - gint height); + gint y); + +static gboolean _gcal_month_view_is_in_range (GcalView *view, + icaltimetype *date); + +static void _gcal_month_view_add_event (GcalView *view, + GtkWidget *event); G_DEFINE_TYPE_WITH_CODE (GcalMonthView, gcal_month_view, - GTK_TYPE_WIDGET, + GTK_TYPE_CONTAINER, G_IMPLEMENT_INTERFACE (GCAL_TYPE_VIEW, _gcal_view_interface_init)); static void gcal_month_view_class_init (GcalMonthViewClass *klass) { - GtkWidgetClass* widget_class; + GtkContainerClass *container_class; + GtkWidgetClass *widget_class; GObjectClass *object_class; + container_class = GTK_CONTAINER_CLASS (klass); + container_class->forall = gcal_month_view_forall; + widget_class = GTK_WIDGET_CLASS (klass); widget_class->realize = gcal_month_view_realize; widget_class->unrealize = gcal_month_view_unrealize; @@ -138,23 +151,18 @@ static void gcal_month_view_init (GcalMonthView *self) self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GCAL_TYPE_MONTH_VIEW, GcalMonthViewPrivate); + + gtk_container_set_reallocate_redraws (GTK_CONTAINER (self), + TRUE); } static void _gcal_view_interface_init (GcalViewIface *iface) { iface->is_in_range = _gcal_month_view_is_in_range; + iface->add_event = _gcal_month_view_add_event; } -static gboolean -_gcal_month_view_is_in_range (GcalView *view, - icaltimetype *date) -{ - g_debug ("Implementation of is_in_range called"); - return TRUE; -} - - static void gcal_month_view_set_property (GObject *object, guint property_id, @@ -166,11 +174,20 @@ gcal_month_view_set_property (GObject *object, switch (property_id) { case PROP_DATE: - if (priv->date != NULL) - g_free (priv->date); + { + icaltimetype *first_of_month; - priv->date = g_value_dup_boxed (value); - break; + if (priv->date != NULL) + g_free (priv->date); + + priv->date = g_value_dup_boxed (value); + + first_of_month = gcal_dup_icaltime (priv->date); + first_of_month->day = 1; + priv->days_delay = - icaltime_day_of_week (*first_of_month) + 2; + g_free (first_of_month); + break; + } default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; @@ -196,6 +213,18 @@ gcal_month_view_get_property (GObject *object, } } +static void +gcal_month_view_finalize (GObject *object) +{ + GcalMonthViewPrivate *priv = GCAL_MONTH_VIEW (object)->priv; + + if (priv->date != NULL) + g_free (priv->date); + + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (gcal_month_view_parent_class)->finalize (object); +} + static void gcal_month_view_realize (GtkWidget *widget) { @@ -278,9 +307,14 @@ gcal_month_view_unmap (GtkWidget *widget) static void gcal_month_view_size_allocate (GtkWidget *widget, - GtkAllocation *allocation) + GtkAllocation *allocation) { GcalMonthViewPrivate *priv; + GList *l; + + GtkStyleContext *context; + GtkStateFlags state; + GtkBorder padding; priv = GCAL_MONTH_VIEW (widget)->priv; gtk_widget_set_allocation (widget, allocation); @@ -291,6 +325,44 @@ gcal_month_view_size_allocate (GtkWidget *widget, allocation->y, allocation->width, allocation->height); + + context = gtk_widget_get_style_context (widget); + state = gtk_widget_get_state_flags (widget); + + gtk_style_context_get_padding (context, state, &padding); + /* init values */ + priv->header_font_size = 12; + priv->horizontal_step = + (allocation->width - (allocation->x + padding.left + padding.right)) / 7; + priv->vertical_step = + (allocation->height - (allocation->y + padding.top + padding.bottom + priv->header_font_size)) / 5; + + g_debug ("[IWSIZEA]: hs %f vs %f\n", + priv->horizontal_step, + priv->vertical_step); + + for (l = priv->events; l != NULL; l = l->next) + { + icaltimetype *date; + gint pos_x; + gint pos_y; + gint min_height; + gint natural_height; + GtkAllocation child_allocation; + + date = gcal_event_widget_get_date (GCAL_EVENT_WIDGET (l->data)); + pos_x = ( (date->day + priv->days_delay + 1) % 7 ) * priv->horizontal_step; + pos_y = ( (date->day + priv->days_delay + 1) / 7 ) * priv->vertical_step; + + gtk_widget_get_preferred_height (GTK_WIDGET (l->data), + &min_height, + &natural_height); + child_allocation.x = pos_x + allocation->x + padding.left; + child_allocation.y = pos_y + allocation->y + padding.top + priv->header_font_size; + child_allocation.width = priv->horizontal_step; + child_allocation.height = MIN (natural_height, priv->vertical_step); + gtk_widget_set_allocation (GTK_WIDGET (l->data), &child_allocation); + } } static gboolean @@ -311,7 +383,6 @@ gcal_month_view_draw (GtkWidget *widget, state = gtk_widget_get_state_flags (widget); gtk_style_context_get_padding (context, state, &padding); - gtk_style_context_get_color (context, state, &color); /* header_font_size is found through pango_get_size_in_pixels */ @@ -324,32 +395,36 @@ gcal_month_view_draw (GtkWidget *widget, GCAL_MONTH_VIEW (widget), cr, alloc.x + padding.left, - alloc.y + padding.top + priv->header_font_size, - alloc.width - (alloc.x + padding.left + padding.right), - alloc.height - (alloc.y + padding.top + padding.bottom + priv->header_font_size)); + alloc.y + padding.top + priv->header_font_size); + + if (GTK_WIDGET_CLASS (gcal_month_view_parent_class)->draw != NULL) + GTK_WIDGET_CLASS (gcal_month_view_parent_class)->draw (widget, cr); return FALSE; } static void -gcal_month_view_finalize (GObject *object) +gcal_month_view_forall (GtkContainer *container, + gboolean include_internals, + GtkCallback callback, + gpointer callback_data) { - GcalMonthViewPrivate *priv = GCAL_MONTH_VIEW (object)->priv; + GcalMonthViewPrivate *priv; + GList *l; - if (priv->date != NULL) - g_free (priv->date); + priv = GCAL_MONTH_VIEW (container)->priv; - /* Chain up to parent's finalize() method. */ - G_OBJECT_CLASS (gcal_month_view_parent_class)->finalize (object); + for (l = priv->events; l != NULL; l = l->next) + { + (* callback) (l->data, callback_data); + } } static void _gcal_month_view_draw_month_grid (GcalMonthView *month_view, cairo_t *cr, gint x, - gint y, - gint width, - gint height) + gint y) { GcalMonthViewPrivate *priv; GtkWidget *widget; @@ -363,8 +438,6 @@ _gcal_month_view_draw_month_grid (GcalMonthView *month_view, gint font_height; guint8 n_days_in_month; - icaltimetype *first_of_month; - gint space; PangoLayout *layout; gchar *day; @@ -382,18 +455,9 @@ _gcal_month_view_draw_month_grid (GcalMonthView *month_view, gtk_style_context_get_font (context, state)); - priv->vertical_step = (gdouble) height / 5; - priv->horizontal_step= (gdouble) width / 7; - n_days_in_month = icaltime_days_in_month (priv->date->month, priv->date->year); - first_of_month = gcal_dup_icaltime (priv->date); - first_of_month->day = 1; - - space = - icaltime_day_of_week (*first_of_month) + 2; - g_free (first_of_month); - for (i = 0; i < 7; i++) { pango_layout_set_text (layout, weekdays[i], -1); @@ -406,7 +470,7 @@ _gcal_month_view_draw_month_grid (GcalMonthView *month_view, for (j = 0; j < 5; j++) { - gint n_day = j * 7 + i + space; + gint n_day = j * 7 + i + priv->days_delay; if (n_day <= 0 || n_day > n_days_in_month) continue; @@ -428,19 +492,44 @@ _gcal_month_view_draw_month_grid (GcalMonthView *month_view, { cairo_move_to (cr, x, y + priv->vertical_step * i); cairo_line_to (cr, - x + priv->horizontal_step * 7, - y + priv->vertical_step * i); + x + priv->horizontal_step * 7, + y + priv->vertical_step * i); } for (i = 0; i < 8; i++) { cairo_move_to (cr, x + priv->horizontal_step * i, y); - cairo_line_to (cr, x + priv->horizontal_step * i, y + height); + cairo_line_to (cr, + x + priv->horizontal_step * i, + y + priv->vertical_step * 5); } cairo_stroke (cr); } +static gboolean +_gcal_month_view_is_in_range (GcalView *view, + icaltimetype *date) +{ + g_debug ("Implementation of is_in_range called"); + return TRUE; +} + +static void +_gcal_month_view_add_event (GcalView *view, + GtkWidget *event) +{ + GcalMonthViewPrivate *priv; + + g_return_if_fail (GCAL_IS_MONTH_VIEW (view)); + g_return_if_fail (GCAL_IS_EVENT_WIDGET (event)); + g_return_if_fail (gtk_widget_get_parent (event) == NULL); + priv = GCAL_MONTH_VIEW (view)->priv; + + priv->events = g_list_append (priv->events, event); + gtk_widget_set_parent (event, GTK_WIDGET (view)); +} + /** * gcal_month_view_new: * @date: diff --git a/src/gcal-month-view.h b/src/gcal-month-view.h index 01f789ad..7ac7541b 100644 --- a/src/gcal-month-view.h +++ b/src/gcal-month-view.h @@ -39,7 +39,7 @@ typedef struct _GcalMonthViewPrivate GcalMonthViewPrivate; struct _GcalMonthView { - GtkWidget parent; + GtkContainer parent; /* add your public declarations here */ GcalMonthViewPrivate *priv; @@ -47,7 +47,7 @@ struct _GcalMonthView struct _GcalMonthViewClass { - GtkWidgetClass parent_class; + GtkContainerClass parent_class; }; GType gcal_month_view_get_type (void); diff --git a/src/gcal-view.c b/src/gcal-view.c index 8fc772bf..a30ff038 100644 --- a/src/gcal-view.c +++ b/src/gcal-view.c @@ -70,3 +70,12 @@ gcal_view_is_in_range (GcalView *view, return GCAL_VIEW_GET_INTERFACE (view)->is_in_range (view, date); } + +void +gcal_view_add_event (GcalView *view, + GtkWidget *event) +{ + g_return_if_fail (GCAL_IS_VIEW (view)); + + GCAL_VIEW_GET_INTERFACE (view)->add_event (view, event); +} diff --git a/src/gcal-view.h b/src/gcal-view.h index c0c91eb1..636dd3a0 100644 --- a/src/gcal-view.h +++ b/src/gcal-view.h @@ -21,6 +21,7 @@ #define __GCAL_VIEW_H__ #include +#include #include @@ -39,12 +40,17 @@ struct _GcalViewIface { GTypeInterface parent_iface; - gboolean (*is_in_range) (GcalView *view, icaltimetype* date); + gboolean (*is_in_range) (GcalView *view, icaltimetype *date); + void (*add_event) (GcalView *view, GtkWidget *event); }; GType gcal_view_get_type (void); -gboolean gcal_view_is_in_range (GcalView *view, icaltimetype* date); +gboolean gcal_view_is_in_range (GcalView *view, + icaltimetype *date); + +void gcal_view_add_event (GcalView *view, + GtkWidget *event); G_END_DECLS diff --git a/src/gcal-window.c b/src/gcal-window.c index a893367d..aab3254e 100644 --- a/src/gcal-window.c +++ b/src/gcal-window.c @@ -23,6 +23,7 @@ #include "gcal-main-toolbar.h" #include "gcal-month-view.h" #include "gcal-view.h" +#include "gcal-event-widget.h" #include "gcal-utils.h" #include @@ -397,24 +398,26 @@ _gcal_window_events_added (GcalManager *manager, { GcalWindowPrivate *priv; GSList *l; - icaltimetype *starting_date; + gchar **tokens; gchar *source_uid; gchar *event_uid; + GtkWidget *event; + icaltimetype *starting_date; + gchar *summary; + GdkRGBA *color; + priv = GCAL_WINDOW (user_data)->priv; - g_debug ("[IWEA]: obtained %d events", g_slist_length (events_list)); for (l = events_list; l != NULL; l = l->next) { - g_debug ("event %s", (gchar*) l->data); tokens = g_strsplit ((gchar*) l->data, ":", -1); source_uid = tokens[0]; event_uid = tokens[1]; - starting_date = gcal_manager_get_start_date (manager, - source_uid, - event_uid); - g_debug ("starts on %s", icaltime_as_ical_string (*starting_date)); + starting_date = gcal_manager_get_event_start_date (manager, + source_uid, + event_uid); g_debug ("GcalViewTypeEnum in GcalWindow %d", priv->active_view); /* FIXME: here priv->views[priv->active_view] instead of hardcoding * GCAL_VIEW_TYPE_MONTHLY */ @@ -422,7 +425,25 @@ _gcal_window_events_added (GcalManager *manager, GCAL_VIEW (priv->views[GCAL_VIEW_TYPE_MONTHLY]), starting_date)) { + summary = gcal_manager_get_event_summary (manager, + source_uid, + event_uid); + color = gcal_manager_get_event_color (manager, + source_uid, + event_uid); + event = + gcal_event_widget_new_with_summary_and_color (summary, color); + gcal_event_widget_set_date (GCAL_EVENT_WIDGET (event), + starting_date); + gcal_view_add_event ( + GCAL_VIEW (priv->views[GCAL_VIEW_TYPE_MONTHLY]), + event); + gtk_style_context_add_class (gtk_widget_get_style_context (event), + "event"); + gtk_widget_show (event); g_debug ("Returned true call on interface function"); + g_free (summary); + gdk_rgba_free (color); } else {