From 23463e22bcec65cf1013ae036dc126be0e1903d6 Mon Sep 17 00:00:00 2001 From: Federico Mena Quintero Date: Thu, 2 Apr 1998 06:12:25 +0000 Subject: New week view composite widget. This provides a full week view (7 day 1998-04-02 Federico Mena Quintero * gncal-week-view.[ch]: New week view composite widget. This provides a full week view (7 day views plus busy time display -- the latter is currently unimplemented). 1998-04-01 Federico Mena Quintero * gncal-day-view.c: New day view widget. It is intended to be a child widget of the week view composite widget. svn path=/trunk/; revision=90 --- calendar/ChangeLog | 9 ++ calendar/gncal-day-view.c | 189 ++++++++++++++++++++++++++--------------- calendar/gncal-day-view.h | 17 ++-- calendar/gncal-week-view.c | 142 +++++++++++++++++++++++++++++++ calendar/gncal-week-view.h | 52 ++++++++++++ calendar/gui/gncal-day-view.c | 189 ++++++++++++++++++++++++++--------------- calendar/gui/gncal-day-view.h | 17 ++-- calendar/gui/gncal-week-view.c | 142 +++++++++++++++++++++++++++++++ calendar/gui/gncal-week-view.h | 52 ++++++++++++ 9 files changed, 657 insertions(+), 152 deletions(-) create mode 100644 calendar/gncal-week-view.c create mode 100644 calendar/gncal-week-view.h create mode 100644 calendar/gui/gncal-week-view.c create mode 100644 calendar/gui/gncal-week-view.h diff --git a/calendar/ChangeLog b/calendar/ChangeLog index 536ac464f9..59bc2b5328 100644 --- a/calendar/ChangeLog +++ b/calendar/ChangeLog @@ -1,5 +1,14 @@ +1998-04-02 Federico Mena Quintero + + * gncal-week-view.[ch]: New week view composite widget. This + provides a full week view (7 day views plus busy time display -- + the latter is currently unimplemented). + 1998-04-01 Federico Mena Quintero + * gncal-day-view.c: New day view widget. It is intended to be a + child widget of the week view composite widget. + * calendar.c (calendar_get_objects_in_range): (calendar_get_events_in_range): (calendar_get_journal_in_range): diff --git a/calendar/gncal-day-view.c b/calendar/gncal-day-view.c index e6a511f736..3726c02274 100644 --- a/calendar/gncal-day-view.c +++ b/calendar/gncal-day-view.c @@ -5,8 +5,10 @@ * Author: Federico Mena */ +#include #include "gncal-day-view.h" #include "timeutil.h" +#include "view-utils.h" #define TEXT_BORDER 2 @@ -15,6 +17,7 @@ static void gncal_day_view_class_init (GncalDayViewClass *class); static void gncal_day_view_init (GncalDayView *dview); +static void gncal_day_view_destroy (GtkObject *object); static void gncal_day_view_realize (GtkWidget *widget); static void gncal_day_view_size_request (GtkWidget *widget, GtkRequisition *requisition); @@ -58,6 +61,8 @@ gncal_day_view_class_init (GncalDayViewClass *class) parent_class = gtk_type_class (gtk_widget_get_type ()); + object_class->destroy = gncal_day_view_destroy; + widget_class->realize = gncal_day_view_realize; widget_class->size_request = gncal_day_view_size_request; widget_class->expose_event = gncal_day_view_expose; @@ -71,22 +76,40 @@ gncal_day_view_init (GncalDayView *dview) dview->calendar = NULL; dview->lower = 0; - dview->upper = 24; - dview->use_am_pm = TRUE; + dview->upper = 0; } -GtkWidget * -gncal_day_view_new (Calendar *calendar) +static void +gncal_day_view_destroy (GtkObject *object) { GncalDayView *dview; + g_return_if_fail (object != NULL); + g_return_if_fail (GNCAL_IS_DAY_VIEW (object)); + + dview = GNCAL_DAY_VIEW (object); + + if (dview->day_str) + g_free (dview->day_str); + + if (GTK_OBJECT_CLASS (parent_class)->destroy) + (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); +} + +GtkWidget * +gncal_day_view_new (Calendar *calendar, time_t lower, time_t upper) +{ + GncalDayView *dview; #if 0 - g_assert (calendar != NULL); + g_return_val_if_fail (calendar != NULL, NULL); #endif - dview = gtk_type_new (gncal_day_view_get_type ()); dview->calendar = calendar; + dview->lower = lower; + dview->upper = upper; + + gncal_day_view_update (dview); return GTK_WIDGET (dview); } @@ -121,29 +144,7 @@ gncal_day_view_realize (GtkWidget *widget) widget->style = gtk_style_attach (widget->style, widget->window); - gtk_style_set_background (widget->style, widget->window, GTK_STATE_SELECTED); -} - -static int -calc_labels_width (GncalDayView *dview) -{ - int width, max_width; - GdkFont *font; - char *buf; - int i; - - font = GTK_WIDGET (dview)->style->font; - - max_width = 0; - - for (i = 0; i < 24; i++) { - buf = format_simple_hour (i, dview->use_am_pm); - width = gdk_string_width (font, buf); - if (width > max_width) - max_width = width; - } - - return width; + gdk_window_set_background (widget->window, &widget->style->bg[GTK_STATE_PRELIGHT]); } static void @@ -157,13 +158,18 @@ gncal_day_view_size_request (GtkWidget *widget, GtkRequisition *requisition) dview = GNCAL_DAY_VIEW (widget); - requisition->width = 2 * widget->style->klass->xthickness + 4 * TEXT_BORDER + MIN_INFO_WIDTH; - requisition->height = 2 * widget->style->klass->xthickness; + /* border and min width */ + + requisition->width = 2 * (widget->style->klass->xthickness + TEXT_BORDER) + MIN_INFO_WIDTH; + requisition->height = 2 * (widget->style->klass->ythickness + TEXT_BORDER); - requisition->width += calc_labels_width (dview); - requisition->height += ((dview->upper - dview->lower) - * (widget->style->font->ascent + widget->style->font->descent - + 2 * TEXT_BORDER)); + /* division line */ + + requisition->height += 2 * TEXT_BORDER + widget->style->klass->ythickness; + + /* title and at least one line of text */ + + requisition->height += 2 * (widget->style->font->ascent + widget->style->font->descent); } static gint @@ -171,9 +177,9 @@ gncal_day_view_expose (GtkWidget *widget, GdkEventExpose *event) { GncalDayView *dview; int x1, y1, width, height; - int division_x; - int row_height; - int i; + GdkRectangle rect, dest; + GdkFont *font; + int str_width; g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (GNCAL_IS_DAY_VIEW (widget), FALSE); @@ -187,11 +193,13 @@ gncal_day_view_expose (GtkWidget *widget, GdkEventExpose *event) x1 = widget->style->klass->xthickness; y1 = widget->style->klass->ythickness; width = widget->allocation.width - 2 * x1; - height = widget->allocation.width - 2 * y1; + height = widget->allocation.height - 2 * y1; /* Clear and paint frame shadow */ - gdk_window_clear_area (widget->window, event->area.x, event->area.y, event->area.width, event->area.height); + gdk_window_clear_area (widget->window, + event->area.x, event->area.y, + event->area.width, event->area.height); gtk_draw_shadow (widget->style, widget->window, GTK_STATE_NORMAL, GTK_SHADOW_IN, @@ -199,56 +207,101 @@ gncal_day_view_expose (GtkWidget *widget, GdkEventExpose *event) widget->allocation.width, widget->allocation.height); - /* Divisions */ + /* Clear and paint title */ + + font = widget->style->font; + + rect.x = x1; + rect.y = y1; + rect.width = width; + rect.height = 2 * TEXT_BORDER + font->ascent + font->descent; - division_x = x1 + 2 * TEXT_BORDER + calc_labels_width (dview); + if (gdk_rectangle_intersect (&rect, &event->area, &dest)) { + gdk_draw_rectangle (widget->window, + widget->style->bg_gc[GTK_STATE_NORMAL], + TRUE, + dest.x, dest.y, + dest.width, dest.height); + + dest = rect; + + dest.x += TEXT_BORDER; + dest.y += TEXT_BORDER; + dest.width -= 2 * TEXT_BORDER; + dest.height -= 2 * TEXT_BORDER; + + gdk_gc_set_clip_rectangle (widget->style->fg_gc[GTK_STATE_NORMAL], &dest); + + str_width = gdk_string_width (font, dview->day_str); + + gdk_draw_string (widget->window, + font, + widget->style->fg_gc[GTK_STATE_NORMAL], + dest.x + (dest.width - str_width) / 2, + dest.y + font->ascent, + dview->day_str); + + gdk_gc_set_clip_rectangle (widget->style->fg_gc[GTK_STATE_NORMAL], NULL); + } - gdk_draw_line (widget->window, - widget->style->black_gc, - division_x, y1, - division_x, y1 + height - 1); + /* Division line */ - row_height = height / (dview->upper - dview->lower); + gtk_draw_hline (widget->style, + widget->window, + GTK_STATE_NORMAL, + rect.x, + rect.x + rect.width - 1, + rect.y + rect.height); - for (i = 0; i < (dview->upper - dview->lower - 1); i++) - gdk_draw_line (widget->window, - widget->style->black_gc, - x1, - y1 + (i + 1) * row_height, - x1 + width - 1, - y1 + (i + 1) * row_height); + /* Text */ + + rect.x = x1 + TEXT_BORDER; + rect.y = y1 + 3 * TEXT_BORDER + font->ascent + font->descent + widget->style->klass->ythickness; + rect.width = width - 2 * TEXT_BORDER; + rect.height = height - (rect.y - y1) - TEXT_BORDER; + + if (gdk_rectangle_intersect (&rect, &event->area, &dest)) + view_utils_draw_events (widget, + widget->window, + widget->style->fg_gc[GTK_STATE_NORMAL], + &rect, + VIEW_UTILS_DRAW_END | VIEW_UTILS_DRAW_SPLIT, + dview->calendar, + dview->lower, + dview->upper); return FALSE; } void -gncal_day_view_set_bounds (GncalDayView *dview, int lower, int upper) +gncal_day_view_update (GncalDayView *dview) { + struct tm tm; + char buf[256]; + g_return_if_fail (dview != NULL); g_return_if_fail (GNCAL_IS_DAY_VIEW (dview)); - lower = CLAMP (lower, 0, 23); - upper = CLAMP (upper, lower + 1, 24); + if (dview->day_str) + g_free (dview->day_str); - if ((lower != dview->lower) || (upper != dview->upper)) { - dview->lower = lower; - dview->upper = upper; + tm = *localtime_r (&dview->lower); + strftime (buf, 256, "%A %d", &tm); + dview->day_str = g_strdup (buf); - gtk_widget_queue_resize (GTK_WIDGET (dview)); - } + gtk_widget_draw (GTK_WIDGET (dview), NULL); } void -gncal_day_view_set_format (GncalDayView *dview, int use_am_pm) +gncal_day_view_set_bounds (GncalDayView *dview, time_t lower, time_t upper) { g_return_if_fail (dview != NULL); g_return_if_fail (GNCAL_IS_DAY_VIEW (dview)); - use_am_pm = use_am_pm ? TRUE : FALSE; - - if (use_am_pm != dview->use_am_pm) { - dview->use_am_pm = use_am_pm; + if ((lower != dview->lower) || (upper != dview->upper)) { + dview->lower = lower; + dview->upper = upper; - gtk_widget_queue_resize (GTK_WIDGET (dview)); + gncal_day_view_update (dview); } } diff --git a/calendar/gncal-day-view.h b/calendar/gncal-day-view.h index ed918e4f37..c10c0c78f8 100644 --- a/calendar/gncal-day-view.h +++ b/calendar/gncal-day-view.h @@ -28,11 +28,12 @@ typedef struct _GncalDayViewClass GncalDayViewClass; struct _GncalDayView { GtkWidget widget; - Calendar *calendar; /* the calendar we are associated to */ + Calendar *calendar; /* the calendar we are associated to */ - int lower; /* lower and upper hours of the day to display */ - int upper; - int use_am_pm; /* use am/pm (TRUE) or 24-hour format (FALSE) */ + time_t lower; /* lower and upper times to display */ + time_t upper; + + char *day_str; /* what day is it? */ }; struct _GncalDayViewClass { @@ -40,11 +41,11 @@ struct _GncalDayViewClass { }; -guint gncal_day_view_get_type (void); -GtkWidget *gncal_day_view_new (Calendar *calendar); +guint gncal_day_view_get_type (void); +GtkWidget *gncal_day_view_new (Calendar *calendar, time_t lower, time_t upper); -void gncal_day_view_set_bounds (GncalDayView *dview, int lower, int upper); -void gncal_day_view_set_format (GncalDayView *dview, int use_am_pm); +void gncal_day_view_update (GncalDayView *dview); +void gncal_day_view_set_bounds (GncalDayView *dview, time_t lower, time_t upper); END_GNOME_DECLS diff --git a/calendar/gncal-week-view.c b/calendar/gncal-week-view.c new file mode 100644 index 0000000000..98b73ae521 --- /dev/null +++ b/calendar/gncal-week-view.c @@ -0,0 +1,142 @@ +/* Week view composite widget for gncal + * + * Copyright (C) 1998 The Free Software Foundation + * + * Author: Federico Mena + */ + +#include "gncal-week-view.h" + + +static void gncal_week_view_init (GncalWeekView *wview); + + +guint +gncal_week_view_get_type (void) +{ + static guint week_view_type = 0; + + if (!week_view_type) { + GtkTypeInfo week_view_info = { + "GncalWeekView", + sizeof (GncalWeekView), + sizeof (GncalWeekViewClass), + (GtkClassInitFunc) NULL, + (GtkObjectInitFunc) gncal_week_view_init, + (GtkArgSetFunc) NULL, + (GtkArgGetFunc) NULL + }; + + week_view_type = gtk_type_unique (gtk_table_get_type (), &week_view_info); + } + + return week_view_type; +} + +static void +gncal_week_view_init (GncalWeekView *wview) +{ + int i; + + wview->calendar = NULL; + memset (&wview->start_of_week, 0, sizeof (wview->start_of_week)); + + for (i = 0; i < 7; i++) + wview->days[i] = NULL; +} + +GtkWidget * +gncal_week_view_new (Calendar *calendar, time_t start_of_week) +{ + GncalWeekView *wview; + int i; +#if 0 + g_return_val_if_fail (calendar != NULL, NULL); +#endif + wview = gtk_type_new (gncal_week_view_get_type ()); + + wview->table.homogeneous = TRUE; /* FIXME: eeeeeeeeeek, GtkTable does not have a function to set this */ + + wview->calendar = calendar; + + for (i = 0; i < 7; i++) { + wview->days[i] = GNCAL_DAY_VIEW (gncal_day_view_new (calendar, 0, 0)); + + if (i < 5) + gtk_table_attach (GTK_TABLE (wview), GTK_WIDGET (wview->days[i]), + i, i + 1, + 0, 1, + GTK_EXPAND | GTK_FILL | GTK_SHRINK, + GTK_EXPAND | GTK_FILL | GTK_SHRINK, + 0, 0); + else + gtk_table_attach (GTK_TABLE (wview), GTK_WIDGET (wview->days[i]), + i - 2, i - 1, + 1, 2, + GTK_EXPAND | GTK_FILL | GTK_SHRINK, + GTK_EXPAND | GTK_FILL | GTK_SHRINK, + 0, 0); + + gtk_widget_show (GTK_WIDGET (wview->days[i])); + } + + gncal_week_view_set (wview, start_of_week); + + return GTK_WIDGET (wview); +} + +static void +update (GncalWeekView *wview, int update_days) +{ + int i; + + if (update_days) + for (i = 0; i < 7; i++) + gncal_day_view_update (wview->days[i]); + + /* FIXME: update extra widgets */ +} + +void +gncal_week_view_update (GncalWeekView *wview) +{ + g_return_if_fail (wview != NULL); + g_return_if_fail (GNCAL_IS_WEEK_VIEW (wview)); + + update (wview, TRUE); +} + +void +gncal_week_view_set (GncalWeekView *wview, time_t start_of_week) +{ + struct tm tm; + time_t day_start, day_end; + + g_return_if_fail (wview != NULL); + g_return_if_fail (GNCAL_IS_WEEK_VIEW (wview)); + + tm = *localtime (&start_of_week); + + /* back up to start of week */ + + tm.tm_mday -= tm.tm_wday; + + /* Start of day */ + + tm.tm_hour = 0; + tm.tm_min = 0; + tm.tm_sec = 0; + + day_start = mktime (&tm); + + for (i = 0; i < 7; i++) { /* rest of days */ + tm.tm_mday++; + day_end = mktime (&tm); + + gncal_day_view_set_bounds (days[i], day_start, day_end - 1); + + day_start = day_end; + } + + update (wview, FALSE); +} diff --git a/calendar/gncal-week-view.h b/calendar/gncal-week-view.h new file mode 100644 index 0000000000..9b626cf756 --- /dev/null +++ b/calendar/gncal-week-view.h @@ -0,0 +1,52 @@ +/* Week view composite widget for gncal + * + * Copyright (C) 1998 The Free Software Foundation + * + * Author: Federico Mena + */ + +#ifndef WEEK_VIEW_H +#define WEEK_VIEW_H + + +#include +#include +#include "gncal-day-view.h" + + +BEGIN_GNOME_DECLS + + +#define GNCAL_WEEK_VIEW(obj) GTK_CHECK_CAST (obj, gncal_week_view_get_type (), GncalWeekView) +#define GNCAL_WEEK_VIEW_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, gncal_week_view_get_type (), GncalWeekViewClass) +#define GNCAL_IS_WEEK_VIEW(obj) GTK_CHECK_TYPE (obj, gncal_week_view_get_type ()) + + +typedef struct _GncalWeekView GncalWeekView; +typedef struct _GncalWeekViewClass GncalWeekViewClass; + +struct _GncalWeekView { + GtkTable table; + + Calendar *calendar; /* the calendar we are associated to */ + + struct tm start_of_week; + + GncalDayView *days[7]; /* the day view widgets */ +}; + +struct _GncalWeekViewClass { + GtkTableClass parent_class; +}; + + +guint gncal_week_view_get_type (void); +GtkWidget *gncal_week_view_new (Calendar *calendar, time_t start_of_week); + +void gncal_week_view_update (GncalWeekView *wview); +void gncal_week_view_set (GncalWeekView *wview, time_t start_of_week); + + +END_GNOME_DECLS + +#endif diff --git a/calendar/gui/gncal-day-view.c b/calendar/gui/gncal-day-view.c index e6a511f736..3726c02274 100644 --- a/calendar/gui/gncal-day-view.c +++ b/calendar/gui/gncal-day-view.c @@ -5,8 +5,10 @@ * Author: Federico Mena */ +#include #include "gncal-day-view.h" #include "timeutil.h" +#include "view-utils.h" #define TEXT_BORDER 2 @@ -15,6 +17,7 @@ static void gncal_day_view_class_init (GncalDayViewClass *class); static void gncal_day_view_init (GncalDayView *dview); +static void gncal_day_view_destroy (GtkObject *object); static void gncal_day_view_realize (GtkWidget *widget); static void gncal_day_view_size_request (GtkWidget *widget, GtkRequisition *requisition); @@ -58,6 +61,8 @@ gncal_day_view_class_init (GncalDayViewClass *class) parent_class = gtk_type_class (gtk_widget_get_type ()); + object_class->destroy = gncal_day_view_destroy; + widget_class->realize = gncal_day_view_realize; widget_class->size_request = gncal_day_view_size_request; widget_class->expose_event = gncal_day_view_expose; @@ -71,22 +76,40 @@ gncal_day_view_init (GncalDayView *dview) dview->calendar = NULL; dview->lower = 0; - dview->upper = 24; - dview->use_am_pm = TRUE; + dview->upper = 0; } -GtkWidget * -gncal_day_view_new (Calendar *calendar) +static void +gncal_day_view_destroy (GtkObject *object) { GncalDayView *dview; + g_return_if_fail (object != NULL); + g_return_if_fail (GNCAL_IS_DAY_VIEW (object)); + + dview = GNCAL_DAY_VIEW (object); + + if (dview->day_str) + g_free (dview->day_str); + + if (GTK_OBJECT_CLASS (parent_class)->destroy) + (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); +} + +GtkWidget * +gncal_day_view_new (Calendar *calendar, time_t lower, time_t upper) +{ + GncalDayView *dview; #if 0 - g_assert (calendar != NULL); + g_return_val_if_fail (calendar != NULL, NULL); #endif - dview = gtk_type_new (gncal_day_view_get_type ()); dview->calendar = calendar; + dview->lower = lower; + dview->upper = upper; + + gncal_day_view_update (dview); return GTK_WIDGET (dview); } @@ -121,29 +144,7 @@ gncal_day_view_realize (GtkWidget *widget) widget->style = gtk_style_attach (widget->style, widget->window); - gtk_style_set_background (widget->style, widget->window, GTK_STATE_SELECTED); -} - -static int -calc_labels_width (GncalDayView *dview) -{ - int width, max_width; - GdkFont *font; - char *buf; - int i; - - font = GTK_WIDGET (dview)->style->font; - - max_width = 0; - - for (i = 0; i < 24; i++) { - buf = format_simple_hour (i, dview->use_am_pm); - width = gdk_string_width (font, buf); - if (width > max_width) - max_width = width; - } - - return width; + gdk_window_set_background (widget->window, &widget->style->bg[GTK_STATE_PRELIGHT]); } static void @@ -157,13 +158,18 @@ gncal_day_view_size_request (GtkWidget *widget, GtkRequisition *requisition) dview = GNCAL_DAY_VIEW (widget); - requisition->width = 2 * widget->style->klass->xthickness + 4 * TEXT_BORDER + MIN_INFO_WIDTH; - requisition->height = 2 * widget->style->klass->xthickness; + /* border and min width */ + + requisition->width = 2 * (widget->style->klass->xthickness + TEXT_BORDER) + MIN_INFO_WIDTH; + requisition->height = 2 * (widget->style->klass->ythickness + TEXT_BORDER); - requisition->width += calc_labels_width (dview); - requisition->height += ((dview->upper - dview->lower) - * (widget->style->font->ascent + widget->style->font->descent - + 2 * TEXT_BORDER)); + /* division line */ + + requisition->height += 2 * TEXT_BORDER + widget->style->klass->ythickness; + + /* title and at least one line of text */ + + requisition->height += 2 * (widget->style->font->ascent + widget->style->font->descent); } static gint @@ -171,9 +177,9 @@ gncal_day_view_expose (GtkWidget *widget, GdkEventExpose *event) { GncalDayView *dview; int x1, y1, width, height; - int division_x; - int row_height; - int i; + GdkRectangle rect, dest; + GdkFont *font; + int str_width; g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (GNCAL_IS_DAY_VIEW (widget), FALSE); @@ -187,11 +193,13 @@ gncal_day_view_expose (GtkWidget *widget, GdkEventExpose *event) x1 = widget->style->klass->xthickness; y1 = widget->style->klass->ythickness; width = widget->allocation.width - 2 * x1; - height = widget->allocation.width - 2 * y1; + height = widget->allocation.height - 2 * y1; /* Clear and paint frame shadow */ - gdk_window_clear_area (widget->window, event->area.x, event->area.y, event->area.width, event->area.height); + gdk_window_clear_area (widget->window, + event->area.x, event->area.y, + event->area.width, event->area.height); gtk_draw_shadow (widget->style, widget->window, GTK_STATE_NORMAL, GTK_SHADOW_IN, @@ -199,56 +207,101 @@ gncal_day_view_expose (GtkWidget *widget, GdkEventExpose *event) widget->allocation.width, widget->allocation.height); - /* Divisions */ + /* Clear and paint title */ + + font = widget->style->font; + + rect.x = x1; + rect.y = y1; + rect.width = width; + rect.height = 2 * TEXT_BORDER + font->ascent + font->descent; - division_x = x1 + 2 * TEXT_BORDER + calc_labels_width (dview); + if (gdk_rectangle_intersect (&rect, &event->area, &dest)) { + gdk_draw_rectangle (widget->window, + widget->style->bg_gc[GTK_STATE_NORMAL], + TRUE, + dest.x, dest.y, + dest.width, dest.height); + + dest = rect; + + dest.x += TEXT_BORDER; + dest.y += TEXT_BORDER; + dest.width -= 2 * TEXT_BORDER; + dest.height -= 2 * TEXT_BORDER; + + gdk_gc_set_clip_rectangle (widget->style->fg_gc[GTK_STATE_NORMAL], &dest); + + str_width = gdk_string_width (font, dview->day_str); + + gdk_draw_string (widget->window, + font, + widget->style->fg_gc[GTK_STATE_NORMAL], + dest.x + (dest.width - str_width) / 2, + dest.y + font->ascent, + dview->day_str); + + gdk_gc_set_clip_rectangle (widget->style->fg_gc[GTK_STATE_NORMAL], NULL); + } - gdk_draw_line (widget->window, - widget->style->black_gc, - division_x, y1, - division_x, y1 + height - 1); + /* Division line */ - row_height = height / (dview->upper - dview->lower); + gtk_draw_hline (widget->style, + widget->window, + GTK_STATE_NORMAL, + rect.x, + rect.x + rect.width - 1, + rect.y + rect.height); - for (i = 0; i < (dview->upper - dview->lower - 1); i++) - gdk_draw_line (widget->window, - widget->style->black_gc, - x1, - y1 + (i + 1) * row_height, - x1 + width - 1, - y1 + (i + 1) * row_height); + /* Text */ + + rect.x = x1 + TEXT_BORDER; + rect.y = y1 + 3 * TEXT_BORDER + font->ascent + font->descent + widget->style->klass->ythickness; + rect.width = width - 2 * TEXT_BORDER; + rect.height = height - (rect.y - y1) - TEXT_BORDER; + + if (gdk_rectangle_intersect (&rect, &event->area, &dest)) + view_utils_draw_events (widget, + widget->window, + widget->style->fg_gc[GTK_STATE_NORMAL], + &rect, + VIEW_UTILS_DRAW_END | VIEW_UTILS_DRAW_SPLIT, + dview->calendar, + dview->lower, + dview->upper); return FALSE; } void -gncal_day_view_set_bounds (GncalDayView *dview, int lower, int upper) +gncal_day_view_update (GncalDayView *dview) { + struct tm tm; + char buf[256]; + g_return_if_fail (dview != NULL); g_return_if_fail (GNCAL_IS_DAY_VIEW (dview)); - lower = CLAMP (lower, 0, 23); - upper = CLAMP (upper, lower + 1, 24); + if (dview->day_str) + g_free (dview->day_str); - if ((lower != dview->lower) || (upper != dview->upper)) { - dview->lower = lower; - dview->upper = upper; + tm = *localtime_r (&dview->lower); + strftime (buf, 256, "%A %d", &tm); + dview->day_str = g_strdup (buf); - gtk_widget_queue_resize (GTK_WIDGET (dview)); - } + gtk_widget_draw (GTK_WIDGET (dview), NULL); } void -gncal_day_view_set_format (GncalDayView *dview, int use_am_pm) +gncal_day_view_set_bounds (GncalDayView *dview, time_t lower, time_t upper) { g_return_if_fail (dview != NULL); g_return_if_fail (GNCAL_IS_DAY_VIEW (dview)); - use_am_pm = use_am_pm ? TRUE : FALSE; - - if (use_am_pm != dview->use_am_pm) { - dview->use_am_pm = use_am_pm; + if ((lower != dview->lower) || (upper != dview->upper)) { + dview->lower = lower; + dview->upper = upper; - gtk_widget_queue_resize (GTK_WIDGET (dview)); + gncal_day_view_update (dview); } } diff --git a/calendar/gui/gncal-day-view.h b/calendar/gui/gncal-day-view.h index ed918e4f37..c10c0c78f8 100644 --- a/calendar/gui/gncal-day-view.h +++ b/calendar/gui/gncal-day-view.h @@ -28,11 +28,12 @@ typedef struct _GncalDayViewClass GncalDayViewClass; struct _GncalDayView { GtkWidget widget; - Calendar *calendar; /* the calendar we are associated to */ + Calendar *calendar; /* the calendar we are associated to */ - int lower; /* lower and upper hours of the day to display */ - int upper; - int use_am_pm; /* use am/pm (TRUE) or 24-hour format (FALSE) */ + time_t lower; /* lower and upper times to display */ + time_t upper; + + char *day_str; /* what day is it? */ }; struct _GncalDayViewClass { @@ -40,11 +41,11 @@ struct _GncalDayViewClass { }; -guint gncal_day_view_get_type (void); -GtkWidget *gncal_day_view_new (Calendar *calendar); +guint gncal_day_view_get_type (void); +GtkWidget *gncal_day_view_new (Calendar *calendar, time_t lower, time_t upper); -void gncal_day_view_set_bounds (GncalDayView *dview, int lower, int upper); -void gncal_day_view_set_format (GncalDayView *dview, int use_am_pm); +void gncal_day_view_update (GncalDayView *dview); +void gncal_day_view_set_bounds (GncalDayView *dview, time_t lower, time_t upper); END_GNOME_DECLS diff --git a/calendar/gui/gncal-week-view.c b/calendar/gui/gncal-week-view.c new file mode 100644 index 0000000000..98b73ae521 --- /dev/null +++ b/calendar/gui/gncal-week-view.c @@ -0,0 +1,142 @@ +/* Week view composite widget for gncal + * + * Copyright (C) 1998 The Free Software Foundation + * + * Author: Federico Mena + */ + +#include "gncal-week-view.h" + + +static void gncal_week_view_init (GncalWeekView *wview); + + +guint +gncal_week_view_get_type (void) +{ + static guint week_view_type = 0; + + if (!week_view_type) { + GtkTypeInfo week_view_info = { + "GncalWeekView", + sizeof (GncalWeekView), + sizeof (GncalWeekViewClass), + (GtkClassInitFunc) NULL, + (GtkObjectInitFunc) gncal_week_view_init, + (GtkArgSetFunc) NULL, + (GtkArgGetFunc) NULL + }; + + week_view_type = gtk_type_unique (gtk_table_get_type (), &week_view_info); + } + + return week_view_type; +} + +static void +gncal_week_view_init (GncalWeekView *wview) +{ + int i; + + wview->calendar = NULL; + memset (&wview->start_of_week, 0, sizeof (wview->start_of_week)); + + for (i = 0; i < 7; i++) + wview->days[i] = NULL; +} + +GtkWidget * +gncal_week_view_new (Calendar *calendar, time_t start_of_week) +{ + GncalWeekView *wview; + int i; +#if 0 + g_return_val_if_fail (calendar != NULL, NULL); +#endif + wview = gtk_type_new (gncal_week_view_get_type ()); + + wview->table.homogeneous = TRUE; /* FIXME: eeeeeeeeeek, GtkTable does not have a function to set this */ + + wview->calendar = calendar; + + for (i = 0; i < 7; i++) { + wview->days[i] = GNCAL_DAY_VIEW (gncal_day_view_new (calendar, 0, 0)); + + if (i < 5) + gtk_table_attach (GTK_TABLE (wview), GTK_WIDGET (wview->days[i]), + i, i + 1, + 0, 1, + GTK_EXPAND | GTK_FILL | GTK_SHRINK, + GTK_EXPAND | GTK_FILL | GTK_SHRINK, + 0, 0); + else + gtk_table_attach (GTK_TABLE (wview), GTK_WIDGET (wview->days[i]), + i - 2, i - 1, + 1, 2, + GTK_EXPAND | GTK_FILL | GTK_SHRINK, + GTK_EXPAND | GTK_FILL | GTK_SHRINK, + 0, 0); + + gtk_widget_show (GTK_WIDGET (wview->days[i])); + } + + gncal_week_view_set (wview, start_of_week); + + return GTK_WIDGET (wview); +} + +static void +update (GncalWeekView *wview, int update_days) +{ + int i; + + if (update_days) + for (i = 0; i < 7; i++) + gncal_day_view_update (wview->days[i]); + + /* FIXME: update extra widgets */ +} + +void +gncal_week_view_update (GncalWeekView *wview) +{ + g_return_if_fail (wview != NULL); + g_return_if_fail (GNCAL_IS_WEEK_VIEW (wview)); + + update (wview, TRUE); +} + +void +gncal_week_view_set (GncalWeekView *wview, time_t start_of_week) +{ + struct tm tm; + time_t day_start, day_end; + + g_return_if_fail (wview != NULL); + g_return_if_fail (GNCAL_IS_WEEK_VIEW (wview)); + + tm = *localtime (&start_of_week); + + /* back up to start of week */ + + tm.tm_mday -= tm.tm_wday; + + /* Start of day */ + + tm.tm_hour = 0; + tm.tm_min = 0; + tm.tm_sec = 0; + + day_start = mktime (&tm); + + for (i = 0; i < 7; i++) { /* rest of days */ + tm.tm_mday++; + day_end = mktime (&tm); + + gncal_day_view_set_bounds (days[i], day_start, day_end - 1); + + day_start = day_end; + } + + update (wview, FALSE); +} diff --git a/calendar/gui/gncal-week-view.h b/calendar/gui/gncal-week-view.h new file mode 100644 index 0000000000..9b626cf756 --- /dev/null +++ b/calendar/gui/gncal-week-view.h @@ -0,0 +1,52 @@ +/* Week view composite widget for gncal + * + * Copyright (C) 1998 The Free Software Foundation + * + * Author: Federico Mena + */ + +#ifndef WEEK_VIEW_H +#define WEEK_VIEW_H + + +#include +#include +#include "gncal-day-view.h" + + +BEGIN_GNOME_DECLS + + +#define GNCAL_WEEK_VIEW(obj) GTK_CHECK_CAST (obj, gncal_week_view_get_type (), GncalWeekView) +#define GNCAL_WEEK_VIEW_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, gncal_week_view_get_type (), GncalWeekViewClass) +#define GNCAL_IS_WEEK_VIEW(obj) GTK_CHECK_TYPE (obj, gncal_week_view_get_type ()) + + +typedef struct _GncalWeekView GncalWeekView; +typedef struct _GncalWeekViewClass GncalWeekViewClass; + +struct _GncalWeekView { + GtkTable table; + + Calendar *calendar; /* the calendar we are associated to */ + + struct tm start_of_week; + + GncalDayView *days[7]; /* the day view widgets */ +}; + +struct _GncalWeekViewClass { + GtkTableClass parent_class; +}; + + +guint gncal_week_view_get_type (void); +GtkWidget *gncal_week_view_new (Calendar *calendar, time_t start_of_week); + +void gncal_week_view_update (GncalWeekView *wview); +void gncal_week_view_set (GncalWeekView *wview, time_t start_of_week); + + +END_GNOME_DECLS + +#endif -- cgit