diff --git a/src/gcal-day-view.c b/src/gcal-day-view.c index 3f82bac7..745fdb67 100644 --- a/src/gcal-day-view.c +++ b/src/gcal-day-view.c @@ -19,12 +19,12 @@ */ #include "gcal-day-view.h" -#include "gcal-view.h" #include "gcal-all-day-grid.h" #include "gcal-days-grid.h" #include "gcal-viewport.h" #include "gcal-utils.h" #include "gcal-view.h" +#include "gcal-event-widget.h" #include @@ -64,6 +64,9 @@ static void gcal_day_view_get_property (GObject *objec GValue *value, GParamSpec *pspec); +static void gcal_day_view_add (GtkContainer *container, + GtkWidget *widget); + static void gcal_day_view_set_date (GcalDayView *view, icaltimetype *date); @@ -90,15 +93,8 @@ G_DEFINE_TYPE_WITH_CODE (GcalDayView, static void gcal_day_view_class_init (GcalDayViewClass *klass) { - /* FIXME: Uncomment stuff here */ - /* GtkContainerClass *container_class; */ GObjectClass *object_class; - - /* container_class = GTK_CONTAINER_CLASS (klass); */ - /* container_class->add = gcal_day_view_add; */ - /* container_class->remove = gcal_day_view_remove; */ - /* container_class->forall = gcal_day_view_forall; */ - /* gtk_container_class_handle_border_width (container_class); */ + GtkContainerClass *container_class; object_class = G_OBJECT_CLASS (klass); object_class->constructed = gcal_day_view_constructed; @@ -106,6 +102,13 @@ gcal_day_view_class_init (GcalDayViewClass *klass) object_class->set_property = gcal_day_view_set_property; object_class->get_property = gcal_day_view_get_property; + container_class = GTK_CONTAINER_CLASS (klass); + container_class->add = gcal_day_view_add; + /* FIXME: Uncomment stuff here */ + /* container_class->remove = gcal_day_view_remove; */ + /* container_class->forall = gcal_day_view_forall; */ + /* gtk_container_class_handle_border_width (container_class); */ + g_object_class_override_property (object_class, PROP_DATE, "active-date"); g_type_class_add_private ((gpointer)klass, sizeof (GcalDayViewPrivate)); @@ -143,9 +146,7 @@ gcal_day_view_constructed (GObject *object) { GcalDayViewPrivate *priv; - /* FIXME: debug code */ GtkWidget *sw; /* involve overlay in it */ - GdkRGBA color; g_return_if_fail (GCAL_IS_DAY_VIEW (object)); priv = GCAL_DAY_VIEW (object)->priv; @@ -249,6 +250,54 @@ gcal_day_view_get_property (GObject *object, } } +/* GtkContainer API */ +static void +gcal_day_view_add (GtkContainer *container, + GtkWidget *widget) +{ + GcalDayViewPrivate *priv; + icaltimetype *dt_start; + icaltimetype *dt_end; + gchar* summ; + + g_return_if_fail (GCAL_IS_EVENT_WIDGET (widget)); + g_return_if_fail (gtk_widget_get_parent (widget) == NULL); + priv = GCAL_DAY_VIEW (container)->priv; + + summ = gcal_event_widget_get_summary (GCAL_EVENT_WIDGET (widget)); + dt_start = gcal_event_widget_get_date (GCAL_EVENT_WIDGET (widget)); + dt_end = gcal_event_widget_get_end_date (GCAL_EVENT_WIDGET (widget)); + /* FIXME: recheck conditions to add, what, where */ + /* Maybe, should be good to add, inside days views only contained events */ + if (gcal_event_widget_get_all_day (GCAL_EVENT_WIDGET (widget))) + { + g_debug ("[all-day-grid] %s from %s to %s", + summ, + icaltime_as_ical_string (*dt_start), + icaltime_as_ical_string (*dt_end)); + gcal_all_day_grid_place (GCAL_ALL_DAY_GRID (priv->all_day_grid), + widget, + priv->date->day == dt_start->day ? 0 : 1); + } + else + { + g_debug ("[days-grid] %s from %s to %s", + summ, + icaltime_as_ical_string (*dt_start), + icaltime_as_ical_string (*dt_end)); + gcal_days_grid_place (GCAL_DAYS_GRID (priv->day_grid), + widget, + priv->date->day == dt_start->day ? 0 : 1, + dt_start->hour * 2 + (dt_start->minute / 30), + dt_end->hour * 2 + (dt_end->minute / 30)); /* FIXME Include half hour and length */ + } + + g_free (dt_start); + g_free (dt_end); + g_free (summ); +} + + static void gcal_day_view_set_date (GcalDayView *view, icaltimetype *date) diff --git a/src/gcal-days-grid.c b/src/gcal-days-grid.c index bdd041bc..6cb39342 100644 --- a/src/gcal-days-grid.c +++ b/src/gcal-days-grid.c @@ -24,6 +24,15 @@ #include #include +#include + +/* + * Notes: + * 1. the widget's height is divided between 48 cells + * representing each a half-hour of the day. + * the preferred value of the cell is kept is req_cell_heigth + * private field. + */ static const double dashed [] = { @@ -43,7 +52,10 @@ struct _ChildInfo { GtkWidget *widget; - guint cell; + guint start_cell; + guint end_cell; + guint sub_column; + gboolean hidden; }; @@ -64,6 +76,10 @@ struct _GcalDaysGridPrivate GdkWindow *event_window; }; +/* Helpers and private */ +static gint compare_child_info (gconstpointer a, + gconstpointer b); + static void gcal_days_grid_finalize (GObject *object); static void gcal_days_grid_set_property (GObject *object, @@ -115,8 +131,26 @@ static void gcal_days_grid_forall (GtkContainer *con GtkCallback callback, gpointer callback_data); + G_DEFINE_TYPE (GcalDaysGrid,gcal_days_grid, GTK_TYPE_CONTAINER); +/* Helpers and private */ +static gint +compare_child_info (gconstpointer a, + gconstpointer b) +{ + ChildInfo *ac = (ChildInfo*) a; + ChildInfo *bc = (ChildInfo*) b; + + if (ac->start_cell < bc->start_cell) + return -1; + else if (ac->start_cell == bc->start_cell) + return 0; + else + return 1; +} + + static void gcal_days_grid_class_init (GcalDaysGridClass *klass) { @@ -449,13 +483,106 @@ static void gcal_days_grid_size_allocate (GtkWidget *widget, GtkAllocation *allocation) { - /* GcalDaysGridPrivate *priv; */ + GcalDaysGridPrivate *priv; - /* priv = GCAL_DAYS_GRID (widget)->priv; */ + GtkBorder padding; + gint width; + gint height; + gint width_block; + gint height_block; + + GList *columns; + gint idx; + + priv = GCAL_DAYS_GRID (widget)->priv; gtk_widget_set_allocation (widget, allocation); - /* FIXME: Todo, write later, - maybe write through delegation */ + /* Placing the event_window */ + if (gtk_widget_get_realized (widget)) + { + gdk_window_move_resize (priv->event_window, + allocation->x, + allocation->y, + allocation->width, + allocation->height); + } + + gtk_style_context_get_padding (gtk_widget_get_style_context (widget), + gtk_widget_get_state_flags (widget), + &padding); + + width = allocation->width - (padding.left + padding.right) - priv->scale_width; + width_block = width / priv->columns_nr; + height = allocation->height - (padding.top + padding.bottom); + height_block = height / 48; + + /* detecting columns and allocs */ + for (columns = priv->children, idx = 0; + columns != NULL; + columns = g_list_next (columns), ++idx) + { + GtkAllocation child_allocation; + GArray *last_y; + GList* column = (GList*) columns->data; + + /* last_y value for each column, + will keep the amount of columns as well */ + last_y = g_array_new (FALSE, FALSE, sizeof (guint)); + + /* going through widgets */ + for (;column != NULL; column = g_list_next (column)) + { + ChildInfo *info; + gboolean new_column = TRUE; + gint i; + + info = (ChildInfo*) column->data; + + for (i = 0; i < last_y->len; ++i) + { + /* start before */ + if (info->start_cell > g_array_index (last_y, guint, i)) + { + info->sub_column = i; + new_column = FALSE; + break; + } + } + + if (new_column) + { + /* adding column to array */ + g_array_append_val (last_y, info->end_cell); + info->sub_column = last_y->len - 1; + } + else + { + g_array_index (last_y, guint, info->sub_column) = info->end_cell; + } + } + + /* allocating */ + for (column = (GList*) columns->data; + column != NULL; + column = g_list_next (column)) + { + ChildInfo *info; + guint sub_column_block; + + info = (ChildInfo*) column->data; + sub_column_block = width_block / last_y->len; + + child_allocation.x = allocation->x + priv->scale_width + padding.left + + idx * width_block + sub_column_block * info->sub_column; + child_allocation.y = info->start_cell * height_block; + child_allocation.width = sub_column_block; + child_allocation.height = (info->end_cell - info->start_cell) * height_block; + + gtk_widget_size_allocate (info->widget, &child_allocation); + } + + g_array_free (last_y, TRUE); + } } static gboolean @@ -599,12 +726,15 @@ gcal_days_grid_button_release_event (GtkWidget *widget, } /* GtkContainer API */ -/* +/** * gcal_days_grid_add: + * @container: + * @widget: * * @gtk_container_add implementation. It assumes the widget will go * to the first column. If there's no column set, will set columns to 1 - */ + * + **/ static void gcal_days_grid_add (GtkContainer *container, GtkWidget *widget) @@ -616,7 +746,7 @@ gcal_days_grid_add (GtkContainer *container, gcal_days_grid_place (GCAL_DAYS_GRID (container), widget, - 0, 0); + 0, 0, 0); } static void @@ -629,30 +759,27 @@ gcal_days_grid_remove (GtkContainer *container, priv = GCAL_DAYS_GRID (container)->priv; - if (priv->children != NULL) + for (columns = priv->children; + columns != NULL; + columns = g_list_next (columns)) { - for (columns = priv->children; - columns != NULL; - columns = g_list_next (columns)) + GList* column = (GList*) columns->data; + for (;column != NULL; column = g_list_next (column)) { - GList* column = (GList*) columns->data; - for (;column != NULL; column = g_list_next (column)) + ChildInfo *info = (ChildInfo*) column->data; + if (widget == info->widget) { - ChildInfo *info = (ChildInfo*) column->data; - if (widget == info->widget) - { - GList* orig = (GList*) columns->data; - orig = g_list_delete_link (orig, column); + GList* orig = (GList*) columns->data; + orig = g_list_delete_link (orig, column); - g_free (info); + g_free (info); - gtk_widget_unparent (widget); + gtk_widget_unparent (widget); - columns->data = orig; + columns->data = orig; - columns = NULL; - break; - } + columns = NULL; + break; } } } @@ -670,24 +797,20 @@ gcal_days_grid_forall (GtkContainer *container, priv = GCAL_DAYS_GRID (container)->priv; - if (priv->children != NULL) + columns = priv->children; + while (columns) { - columns = priv->children; + GList *column; - while (columns) + column = columns->data; + columns = columns->next; + + while (column) { - GList *column; + ChildInfo *info = (ChildInfo*) column->data; + column = column->next; - column = columns->data; - columns = columns->next; - - while (column) - { - ChildInfo *info = (ChildInfo*) column->data; - column = column->next; - - (* callback) (info->widget, callback_data); - } + (* callback) (info->widget, callback_data); } } } @@ -753,10 +876,11 @@ gcal_days_grid_get_scale_width (GcalDaysGrid *days_grid) /** * gcal_days_grid_place: - * @all_day: A #GcalDaysGrid widget - * @widget: The child widget to add - * @column_idx: The index of the column, starting with zero - * @cell_idx: The cell, refering the month, starting with zero + * @all_day: a #GcalDaysGrid widget + * @widget: the child widget to add + * @column_idx: the index of the column, starting with zero + * @start_cell: the start-cell, refering the hour, starting with zero + * @end_cell: the end-cell, refering the hour, starting with zero * * Adding a widget to a specified column. If the column index * is bigger than the #GcalDaysGrid:columns property set, @@ -766,7 +890,8 @@ void gcal_days_grid_place (GcalDaysGrid *all_day, GtkWidget *widget, guint column_idx, - guint cell_idx) + guint start_cell, + guint end_cell) { GcalDaysGridPrivate *priv; GList* children_link; @@ -783,8 +908,10 @@ gcal_days_grid_place (GcalDaysGrid *all_day, info = g_new0 (ChildInfo, 1); info->widget = widget; info->hidden = FALSE; - info->cell = cell_idx; - children_link->data = g_list_append (column, info); + info->start_cell = start_cell; + info->end_cell = end_cell; + info->sub_column = 0; + children_link->data = g_list_insert_sorted (column, info, compare_child_info); gtk_widget_set_parent (widget, GTK_WIDGET (all_day)); } diff --git a/src/gcal-days-grid.h b/src/gcal-days-grid.h index 78045c84..d7cb89ea 100644 --- a/src/gcal-days-grid.h +++ b/src/gcal-days-grid.h @@ -60,7 +60,8 @@ guint gcal_days_grid_get_scale_width (GcalDaysGrid *days_gr void gcal_days_grid_place (GcalDaysGrid *days_grid, GtkWidget *widget, guint column_idx, - guint cell_idx); + guint start_cell, + guint end_cell); GtkWidget* gcal_days_grid_get_by_uuid (GcalDaysGrid *days_grid, const gchar *uuid);