From 84fa00e42a593a4e4e64866090df30c9d7c066b9 Mon Sep 17 00:00:00 2001 From: Federico Mena Quintero Date: Fri, 4 Sep 1998 00:43:06 +0000 Subject: Finished with the properties dialog. You can jump to days from the year Finished with the properties dialog. You can jump to days from the year view now. I'm off to rewrite gnome-popupmenu and friends. 1998-09-03 Federico Mena Quintero * gncal-full-day.c (gncal_full_day_forall): Updated foreach -> forall from Gtk changes, bleah. * year-view.c (day_event): New function to handle events from days. Jumps to the day that is clicked. * main.c: Use a watch cursor while the previous/today/next functions are doing their job. * mark.c (month_item_prepare_prelight): New public utility function to prepare a month item for prelighting. It will store the proper prelight information and attach the appropriate signals. (mark_current_day): Make the current day bold as well (useful for color-blind people, I guess). * prop.c (set_current_day): Reset the date in the sample calendar and mark the current day. (fake_mark_days): Mark fake events in the sample calendar. * year-view.c (year_view_set): Use the general prelighting engine. * goto.c (day_event): Just process button presses, as prelighting is done behind the scenes now. (update): Use the general prelighting engine. * prop.c (create_colors_page): We can now configure the colors of svn path=/trunk/; revision=361 --- calendar/ChangeLog | 25 +++++++++ calendar/TODO | 16 ++---- calendar/gncal-full-day.c | 7 +-- calendar/goto.c | 50 +----------------- calendar/gui/gncal-full-day.c | 7 +-- calendar/gui/goto.c | 50 +----------------- calendar/gui/main.c | 26 ++++++++++ calendar/gui/mark.c | 118 ++++++++++++++++++++++++++++++++++++++++++ calendar/gui/mark.h | 21 ++++++++ calendar/gui/month-view.c | 3 +- calendar/gui/prop.c | 78 +++++++++++++++++++++++++--- calendar/gui/year-view.c | 58 +++++++++++++++++++-- calendar/main.c | 26 ++++++++++ calendar/mark.c | 118 ++++++++++++++++++++++++++++++++++++++++++ calendar/mark.h | 21 ++++++++ calendar/month-view.c | 3 +- calendar/prop.c | 78 +++++++++++++++++++++++++--- calendar/year-view.c | 58 +++++++++++++++++++-- 18 files changed, 623 insertions(+), 140 deletions(-) (limited to 'calendar') diff --git a/calendar/ChangeLog b/calendar/ChangeLog index 22c0b96b1e..5aa30085cc 100644 --- a/calendar/ChangeLog +++ b/calendar/ChangeLog @@ -1,5 +1,30 @@ 1998-09-03 Federico Mena Quintero + * gncal-full-day.c (gncal_full_day_forall): Updated foreach -> + forall from Gtk changes, bleah. + + * year-view.c (day_event): New function to handle events from + days. Jumps to the day that is clicked. + + * main.c: Use a watch cursor while the previous/today/next + functions are doing their job. + + * mark.c (month_item_prepare_prelight): New public utility + function to prepare a month item for prelighting. It will store + the proper prelight information and attach the appropriate signals. + (mark_current_day): Make the current day bold as well (useful for + color-blind people, I guess). + + * prop.c (set_current_day): Reset the date in the sample calendar + and mark the current day. + (fake_mark_days): Mark fake events in the sample calendar. + + * year-view.c (year_view_set): Use the general prelighting engine. + + * goto.c (day_event): Just process button presses, as prelighting + is done behind the scenes now. + (update): Use the general prelighting engine. + * prop.c (create_colors_page): We can now configure the colors of the monthly calendars! Wheeeeee! There are still some nits to be fixed, which are listed in the TODO file. diff --git a/calendar/TODO b/calendar/TODO index 7b9e28c545..ce059ada8e 100644 --- a/calendar/TODO +++ b/calendar/TODO @@ -3,20 +3,8 @@ BUGS: - Recurrence end date is wrong. An event that repeats daily will not be included in the ending date of the recurrence (off-by-one error?). -General: - -- Color properties, highlight some days and such. - -- Mark the current day in BOLD as well as different color (color blind users will need it). - -- Write online help. Nice help. Lots of help. - Year view: -- Prelight days on mouse enter/leave. Share that code with goto.c. - -- Double click on a day takes you to the day view. - - Button-3 popup with options: Create new appointment in this day --- separator --- @@ -56,3 +44,7 @@ Event editor dialog: Gnome date selection widget: - Make the displayed date be localized properly -- use strftime(). + +General: + +- Write online help. Nice help. Lots of help. diff --git a/calendar/gncal-full-day.c b/calendar/gncal-full-day.c index ecc2a0d0cb..a84e185eb1 100644 --- a/calendar/gncal-full-day.c +++ b/calendar/gncal-full-day.c @@ -106,7 +106,8 @@ static gint gncal_full_day_focus_in (GtkWidget *widget, GdkEventFocus *event); static gint gncal_full_day_focus_out (GtkWidget *widget, GdkEventFocus *event); -static void gncal_full_day_foreach (GtkContainer *container, +static void gncal_full_day_forall (GtkContainer *container, + gboolean include_internals, GtkCallback callback, gpointer callback_data); @@ -981,7 +982,7 @@ gncal_full_day_class_init (GncalFullDayClass *class) widget_class->focus_in_event = gncal_full_day_focus_in; widget_class->focus_out_event = gncal_full_day_focus_out; - container_class->foreach = gncal_full_day_foreach; + container_class->forall = gncal_full_day_forall; class->range_activated = range_activated; } @@ -2097,7 +2098,7 @@ gncal_full_day_focus_out (GtkWidget *widget, GdkEventFocus *event) } static void -gncal_full_day_foreach (GtkContainer *container, GtkCallback callback, gpointer callback_data) +gncal_full_day_forall (GtkContainer *container, gboolean include_internals, GtkCallback callback, gpointer callback_data) { GncalFullDay *fullday; GList *children; diff --git a/calendar/goto.c b/calendar/goto.c index 16fada2f5b..7a4068fb85 100644 --- a/calendar/goto.c +++ b/calendar/goto.c @@ -17,7 +17,6 @@ static GtkWidget *goto_win; /* The goto dialog window */ static GnomeCanvasItem *month_item; /* The month item in the dialog */ static GnomeCalendar *gnome_calendar; /* The gnome calendar the dialog refers to */ -static gulong day_pixels[42]; /* Colors of the day backgrounds */ /* Updates the specified month item by marking it appropriately from the calendar the dialog refers @@ -25,29 +24,9 @@ static gulong day_pixels[42]; /* Colors of the day backgrounds */ static void update (void) { - int i; - GnomeCanvasItem *item; - GtkArg arg; - GdkColor *c; - - /* First, mark the days */ - unmark_month_item (GNOME_MONTH_ITEM (month_item)); mark_month_item (GNOME_MONTH_ITEM (month_item), gnome_calendar->cal); - - /* Now save the colors of the day backgrounds */ - - for (i = 0; i < 42; i++) { - arg.name = "fill_color_gdk"; - - item = gnome_month_item_num2child (GNOME_MONTH_ITEM (month_item), - GNOME_MONTH_ITEM_DAY_BOX + i); - gtk_object_getv (GTK_OBJECT (item), 1, &arg); - - c = GTK_VALUE_BOXED (arg); - day_pixels[i] = c->pixel; - g_free (c); - } + month_item_prepare_prelight (GNOME_MONTH_ITEM (month_item), default_prelight_func, NULL); } /* Callback used when the year adjustment is changed */ @@ -163,24 +142,16 @@ set_scroll_region (GtkWidget *widget, GtkAllocation *allocation) } /* Event handler for day groups in the month item. A button press makes the calendar jump to the - * selected day and destroys the Go-to dialog box. Days are prelighted as appropriate on - * enter_notify and leave_notify events. + * selected day and destroys the Go-to dialog box. */ static gint day_event (GnomeCanvasItem *item, GdkEvent *event, gpointer data) { - GnomeCanvasItem *box; int child_num, day; - GdkColor color; child_num = gnome_month_item_child2num (GNOME_MONTH_ITEM (month_item), item); day = gnome_month_item_num2day (GNOME_MONTH_ITEM (month_item), child_num); - child_num -= GNOME_MONTH_ITEM_DAY_GROUP; - - if (day == 0) - return FALSE; - switch (event->type) { case GDK_BUTTON_PRESS: if ((event->button.button == 1) && (day != 0)) { @@ -191,23 +162,6 @@ day_event (GnomeCanvasItem *item, GdkEvent *event, gpointer data) } break; - case GDK_ENTER_NOTIFY: - box = gnome_month_item_num2child (GNOME_MONTH_ITEM (month_item), - child_num + GNOME_MONTH_ITEM_DAY_BOX); - gnome_canvas_item_set (box, - "fill_color", color_spec_from_prop (COLOR_PROP_PRELIGHT_DAY_BG), - NULL); - break; - - case GDK_LEAVE_NOTIFY: - box = gnome_month_item_num2child (GNOME_MONTH_ITEM (month_item), - child_num + GNOME_MONTH_ITEM_DAY_BOX); - color.pixel = day_pixels[child_num]; - gnome_canvas_item_set (box, - "fill_color_gdk", &color, - NULL); - break; - default: break; } diff --git a/calendar/gui/gncal-full-day.c b/calendar/gui/gncal-full-day.c index ecc2a0d0cb..a84e185eb1 100644 --- a/calendar/gui/gncal-full-day.c +++ b/calendar/gui/gncal-full-day.c @@ -106,7 +106,8 @@ static gint gncal_full_day_focus_in (GtkWidget *widget, GdkEventFocus *event); static gint gncal_full_day_focus_out (GtkWidget *widget, GdkEventFocus *event); -static void gncal_full_day_foreach (GtkContainer *container, +static void gncal_full_day_forall (GtkContainer *container, + gboolean include_internals, GtkCallback callback, gpointer callback_data); @@ -981,7 +982,7 @@ gncal_full_day_class_init (GncalFullDayClass *class) widget_class->focus_in_event = gncal_full_day_focus_in; widget_class->focus_out_event = gncal_full_day_focus_out; - container_class->foreach = gncal_full_day_foreach; + container_class->forall = gncal_full_day_forall; class->range_activated = range_activated; } @@ -2097,7 +2098,7 @@ gncal_full_day_focus_out (GtkWidget *widget, GdkEventFocus *event) } static void -gncal_full_day_foreach (GtkContainer *container, GtkCallback callback, gpointer callback_data) +gncal_full_day_forall (GtkContainer *container, gboolean include_internals, GtkCallback callback, gpointer callback_data) { GncalFullDay *fullday; GList *children; diff --git a/calendar/gui/goto.c b/calendar/gui/goto.c index 16fada2f5b..7a4068fb85 100644 --- a/calendar/gui/goto.c +++ b/calendar/gui/goto.c @@ -17,7 +17,6 @@ static GtkWidget *goto_win; /* The goto dialog window */ static GnomeCanvasItem *month_item; /* The month item in the dialog */ static GnomeCalendar *gnome_calendar; /* The gnome calendar the dialog refers to */ -static gulong day_pixels[42]; /* Colors of the day backgrounds */ /* Updates the specified month item by marking it appropriately from the calendar the dialog refers @@ -25,29 +24,9 @@ static gulong day_pixels[42]; /* Colors of the day backgrounds */ static void update (void) { - int i; - GnomeCanvasItem *item; - GtkArg arg; - GdkColor *c; - - /* First, mark the days */ - unmark_month_item (GNOME_MONTH_ITEM (month_item)); mark_month_item (GNOME_MONTH_ITEM (month_item), gnome_calendar->cal); - - /* Now save the colors of the day backgrounds */ - - for (i = 0; i < 42; i++) { - arg.name = "fill_color_gdk"; - - item = gnome_month_item_num2child (GNOME_MONTH_ITEM (month_item), - GNOME_MONTH_ITEM_DAY_BOX + i); - gtk_object_getv (GTK_OBJECT (item), 1, &arg); - - c = GTK_VALUE_BOXED (arg); - day_pixels[i] = c->pixel; - g_free (c); - } + month_item_prepare_prelight (GNOME_MONTH_ITEM (month_item), default_prelight_func, NULL); } /* Callback used when the year adjustment is changed */ @@ -163,24 +142,16 @@ set_scroll_region (GtkWidget *widget, GtkAllocation *allocation) } /* Event handler for day groups in the month item. A button press makes the calendar jump to the - * selected day and destroys the Go-to dialog box. Days are prelighted as appropriate on - * enter_notify and leave_notify events. + * selected day and destroys the Go-to dialog box. */ static gint day_event (GnomeCanvasItem *item, GdkEvent *event, gpointer data) { - GnomeCanvasItem *box; int child_num, day; - GdkColor color; child_num = gnome_month_item_child2num (GNOME_MONTH_ITEM (month_item), item); day = gnome_month_item_num2day (GNOME_MONTH_ITEM (month_item), child_num); - child_num -= GNOME_MONTH_ITEM_DAY_GROUP; - - if (day == 0) - return FALSE; - switch (event->type) { case GDK_BUTTON_PRESS: if ((event->button.button == 1) && (day != 0)) { @@ -191,23 +162,6 @@ day_event (GnomeCanvasItem *item, GdkEvent *event, gpointer data) } break; - case GDK_ENTER_NOTIFY: - box = gnome_month_item_num2child (GNOME_MONTH_ITEM (month_item), - child_num + GNOME_MONTH_ITEM_DAY_BOX); - gnome_canvas_item_set (box, - "fill_color", color_spec_from_prop (COLOR_PROP_PRELIGHT_DAY_BG), - NULL); - break; - - case GDK_LEAVE_NOTIFY: - box = gnome_month_item_num2child (GNOME_MONTH_ITEM (month_item), - child_num + GNOME_MONTH_ITEM_DAY_BOX); - color.pixel = day_pixels[child_num]; - gnome_canvas_item_set (box, - "fill_color_gdk", &color, - NULL); - break; - default: break; } diff --git a/calendar/gui/main.c b/calendar/gui/main.c index 5ccdeee3ff..462e71a06a 100644 --- a/calendar/gui/main.c +++ b/calendar/gui/main.c @@ -251,22 +251,48 @@ quit_cmd (void) } } +/* Sets a clock cursor for the specified calendar window */ +static void +set_clock_cursor (GnomeCalendar *gcal) +{ + GdkCursor *cursor; + + cursor = gdk_cursor_new (GDK_WATCH); + gdk_window_set_cursor (GTK_WIDGET (gcal)->window, cursor); + gdk_cursor_destroy (cursor); + gdk_flush (); +} + +/* Resets the normal cursor for the specified calendar window */ +static void +set_normal_cursor (GnomeCalendar *gcal) +{ + gdk_window_set_cursor (GTK_WIDGET (gcal)->window, NULL); + gdk_flush (); +} + static void previous_clicked (GtkWidget *widget, GnomeCalendar *gcal) { + set_clock_cursor (gcal); gnome_calendar_previous (gcal); + set_normal_cursor (gcal); } static void next_clicked (GtkWidget *widget, GnomeCalendar *gcal) { + set_clock_cursor (gcal); gnome_calendar_next (gcal); + set_normal_cursor (gcal); } static void today_clicked (GtkWidget *widget, GnomeCalendar *gcal) { + set_clock_cursor (gcal); gnome_calendar_goto_today (gcal); + set_normal_cursor (gcal); } static void diff --git a/calendar/gui/mark.c b/calendar/gui/mark.c index 6aab8b1b74..f3725bb7e5 100644 --- a/calendar/gui/mark.c +++ b/calendar/gui/mark.c @@ -61,6 +61,7 @@ mark_current_day (GnomeMonthItem *mitem) item = gnome_month_item_num2child (mitem, GNOME_MONTH_ITEM_DAY_LABEL + day_index); gnome_canvas_item_set (item, "fill_color", color_spec_from_prop (COLOR_PROP_CURRENT_DAY_FG), + "font", CURRENT_DAY_FONT, NULL); } } @@ -115,4 +116,121 @@ unmark_month_item (GnomeMonthItem *mitem) gnome_canvas_item_set (GNOME_CANVAS_ITEM (mitem), "day_color", color_spec_from_prop (COLOR_PROP_DAY_FG), NULL); + + gnome_canvas_item_set (GNOME_CANVAS_ITEM (mitem), + "day_font", NORMAL_DAY_FONT, + NULL); +} + +/* Frees the prelight information in the month item when it is destroyed */ +static void +free_prelight_info (GtkObject *object, gpointer data) +{ + g_free (gtk_object_get_data (object, "prelight_info")); +} + +/* Handles EnterNotify and LeaveNotify events from the month item's day groups, and performs + * appropriate prelighting. + */ +static gint +day_event (GnomeCanvasItem *item, GdkEvent *event, gpointer data) +{ + GnomeCanvasItem *mitem; + GnomeCanvasItem *box; + int child_num, day; + gulong *day_pixels; + GetPrelightColorFunc func; + gpointer func_data; + char *spec; + GdkColor color; + + mitem = data; + child_num = gnome_month_item_child2num (GNOME_MONTH_ITEM (mitem), item); + day = gnome_month_item_num2day (GNOME_MONTH_ITEM (mitem), child_num); + + if (day == 0) + return FALSE; /* it was a day outside the month's range */ + + child_num -= GNOME_MONTH_ITEM_DAY_GROUP; + box = gnome_month_item_num2child (GNOME_MONTH_ITEM (mitem), GNOME_MONTH_ITEM_DAY_BOX + child_num); + + day_pixels = gtk_object_get_data (GTK_OBJECT (mitem), "prelight_info_pixels"); + func = gtk_object_get_data (GTK_OBJECT (mitem), "prelight_info_func"); + func_data = gtk_object_get_data (GTK_OBJECT (mitem), "prelight_info_data"); + + switch (event->type) { + case GDK_ENTER_NOTIFY: + spec = (* func) (func_data); + gnome_canvas_item_set (box, + "fill_color", spec, + NULL); + break; + + case GDK_LEAVE_NOTIFY: + color.pixel = day_pixels[child_num]; + gnome_canvas_item_set (box, + "fill_color_gdk", &color, + NULL); + break; + + default: + break; + } + + return FALSE; +} + +void +month_item_prepare_prelight (GnomeMonthItem *mitem, GetPrelightColorFunc func, gpointer func_data) +{ + gulong *day_pixels; + GnomeCanvasItem *day_group; + GnomeCanvasItem *box; + GtkArg arg; + GdkColor *color; + int i; + + day_pixels = gtk_object_get_data (GTK_OBJECT (mitem), "prelight_info_pixels"); + + /* Set up the buffer for day background colors and attach it to the month item, if necessary */ + + if (!day_pixels) { + /* Create the buffer and attach it */ + + day_pixels = g_new (gulong, 42); + gtk_object_set_data (GTK_OBJECT (mitem), "prelight_info_pixels", day_pixels); + gtk_object_set_data (GTK_OBJECT (mitem), "prelight_info_func", func); + gtk_object_set_data (GTK_OBJECT (mitem), "prelight_info_data", func_data); + gtk_signal_connect (GTK_OBJECT (mitem), "destroy", + (GtkSignalFunc) free_prelight_info, + NULL); + + /* Connect the appropriate signals to perform prelighting */ + + for (i = 0; i < 42; i++) { + day_group = gnome_month_item_num2child (GNOME_MONTH_ITEM (mitem), GNOME_MONTH_ITEM_DAY_GROUP + i); + gtk_signal_connect (GTK_OBJECT (day_group), "event", + (GtkSignalFunc) day_event, + mitem); + } + } + + /* Fetch the background colors from the day boxes and store them in the prelight info */ + + for (i = 0; i < 42; i++) { + box = gnome_month_item_num2child (mitem, GNOME_MONTH_ITEM_DAY_BOX + i); + + arg.name = "fill_color_gdk"; + gtk_object_getv (GTK_OBJECT (box), 1, &arg); + + color = GTK_VALUE_BOXED (arg); + day_pixels[i] = color->pixel; + g_free (color); + } +} + +char * +default_prelight_func (gpointer data) +{ + return color_spec_from_prop (COLOR_PROP_PRELIGHT_DAY_BG); } diff --git a/calendar/gui/mark.h b/calendar/gui/mark.h index 9ffafe20a7..0b849e96cc 100644 --- a/calendar/gui/mark.h +++ b/calendar/gui/mark.h @@ -12,6 +12,12 @@ #include "gnome-month-item.h" +/* These are the fonts used for the montly calendars */ + +#define NORMAL_DAY_FONT "-adobe-helvetica-medium-r-normal--10-*-72-72-p-*-iso8859-1" +#define CURRENT_DAY_FONT "-adobe-helvetica-bold-r-normal--12-*-72-72-p-*-iso8859-1" + + /* Takes a monthly calendar item and marks the days that have events scheduled for them in the * specified calendar. It also highlights the current day. */ @@ -20,5 +26,20 @@ void mark_month_item (GnomeMonthItem *mitem, Calendar *cal); /* Unmarks all the days in the specified month item */ void unmark_month_item (GnomeMonthItem *mitem); +/* Prepares a monthly calendar item to prelight when the mouse goes over the days. If it is called + * on a month item that had already been prepared, it updates the internal color buffers -- you need + * to do this if you re-mark the month item, or if you change the global color configuration. The + * specified function is used to query the prelight colors; it must return a color spec. + */ + +typedef char * (* GetPrelightColorFunc) (gpointer data); + +void month_item_prepare_prelight (GnomeMonthItem *mitem, GetPrelightColorFunc func, gpointer func_data); + +/* This is the default prelight function you can use for most puposes. You can use NULL as the + * func_data. + */ +char *default_prelight_func (gpointer data); + #endif diff --git a/calendar/gui/month-view.c b/calendar/gui/month-view.c index 4d1a9bf967..d84d7c98cc 100644 --- a/calendar/gui/month-view.c +++ b/calendar/gui/month-view.c @@ -9,6 +9,7 @@ #include #include "month-view.h" #include "main.h" +#include "mark.h" #define SPACING 4 /* Spacing between title and calendar */ @@ -212,6 +213,6 @@ month_view_colors_changed (MonthView *mv) g_return_if_fail (mv != NULL); g_return_if_fail (IS_MONTH_VIEW (mv)); - unmark_month_item (mv->mitem); + unmark_month_item (GNOME_MONTH_ITEM (mv->mitem)); /* FIXME */ } diff --git a/calendar/gui/prop.c b/calendar/gui/prop.c index bdc8c9e937..936170855f 100644 --- a/calendar/gui/prop.c +++ b/calendar/gui/prop.c @@ -1,6 +1,6 @@ -/* - * Calendar properties dialog box - * (C) 1998 the Free Software Foundation +/* Calendar properties dialog box + * + * Copyright (C) 1998 the Free Software Foundation * * Authors: Miguel de Icaza * Federico Mena @@ -9,8 +9,9 @@ #include #include #include "gnome-cal.h" -#include "main.h" #include "gnome-month-item.h" +#include "main.h" +#include "mark.h" /* These specify the page numbers in the preferences notebook */ enum { @@ -344,6 +345,60 @@ color_spec_from_picker (int num) return build_color_spec (r, g, b); } +/* Callback used to query prelight color information for the properties box */ +static char * +fetch_prelight_spec (gpointer data) +{ + return color_spec_from_picker (COLOR_PROP_PRELIGHT_DAY_BG); +} + +/* Marks fake event days in the month item sample */ +static void +fake_mark_days (void) +{ + static int day_nums[] = { 1, 4, 8, 16, 17, 18, 20, 25, 28 }; /* some random days */ + int day_index; + int i; + GnomeCanvasItem *item; + + for (i = 0; i < (sizeof (day_nums) / sizeof (day_nums[0])); i++) { + day_index = gnome_month_item_day2index (GNOME_MONTH_ITEM (month_item), day_nums[i]); + item = gnome_month_item_num2child (GNOME_MONTH_ITEM (month_item), GNOME_MONTH_ITEM_DAY_BOX + day_index); + gnome_canvas_item_set (item, + "fill_color", color_spec_from_picker (COLOR_PROP_MARK_DAY_BG), + NULL); + } +} + +/* Switches the month item to the current date and highlights the current day's number */ +static void +set_current_day (void) +{ + struct tm *tm; + time_t t; + GnomeCanvasItem *item; + int day_index; + + /* Set the date */ + + t = time (NULL); + tm = localtime (&t); + + gnome_canvas_item_set (month_item, + "year", tm->tm_year + 1900, + "month", tm->tm_mon, + NULL); + + /* Highlight current day */ + + day_index = gnome_month_item_day2index (GNOME_MONTH_ITEM (month_item), tm->tm_mday); + item = gnome_month_item_num2child (GNOME_MONTH_ITEM (month_item), GNOME_MONTH_ITEM_DAY_LABEL + day_index); + gnome_canvas_item_set (item, + "fill_color", color_spec_from_picker (COLOR_PROP_CURRENT_DAY_FG), + "font", CURRENT_DAY_FONT, + NULL); +} + /* Sets the colors of the month item to the current prerences */ static void reconfigure_month (void) @@ -360,10 +415,6 @@ reconfigure_month (void) "outline_color", color_spec_from_picker (COLOR_PROP_OUTLINE_COLOR), NULL); - /* FIXME: set the rest of the colors -- simulate marking of the month item, set the - * current day, etc. The following is incorrect. - */ - gnome_canvas_item_set (month_item, "day_box_color", color_spec_from_picker (COLOR_PROP_EMPTY_DAY_BG), NULL); @@ -371,6 +422,17 @@ reconfigure_month (void) gnome_canvas_item_set (month_item, "day_color", color_spec_from_picker (COLOR_PROP_DAY_FG), NULL); + + gnome_canvas_item_set (month_item, + "day_font", NORMAL_DAY_FONT, + NULL); + + fake_mark_days (); + set_current_day (); + + /* Reset prelighting information */ + + month_item_prepare_prelight (GNOME_MONTH_ITEM (month_item), fetch_prelight_spec, NULL); } /* Callback used when a color is changed */ diff --git a/calendar/gui/year-view.c b/calendar/gui/year-view.c index 7458b61500..97795628a4 100644 --- a/calendar/gui/year-view.c +++ b/calendar/gui/year-view.c @@ -154,6 +154,56 @@ need_resize (YearView *yv) yv->idle_id = gtk_idle_add (idle_handler, yv); } +/* Event handler for days in the year's month items */ +static gint +day_event (GnomeCanvasItem *item, GdkEvent *event, gpointer data) +{ + YearView *yv; + GnomeCanvasItem *mitem; + int child_num, day; + + mitem = data; + child_num = gnome_month_item_child2num (GNOME_MONTH_ITEM (mitem), item); + day = gnome_month_item_num2day (GNOME_MONTH_ITEM (mitem), child_num); + + yv = gtk_object_get_user_data (GTK_OBJECT (mitem)); + + switch (event->type) { + case GDK_BUTTON_PRESS: + if ((event->button.button == 1) && (day != 0)) + gnome_calendar_dayjump (yv->calendar, + time_from_day (GNOME_MONTH_ITEM (mitem)->year, + GNOME_MONTH_ITEM (mitem)->month, + day)); + break; + + default: + break; + } + + return FALSE; +} + +/* Sets up the month item with the specified index -- connects signals for handling events, etc. */ +static void +setup_month_item (YearView *yv, int n) +{ + GnomeCanvasItem *mitem; + GnomeCanvasItem *item; + int i; + + mitem = yv->mitems[n]; + + /* Connect signals */ + + for (i = 0; i < 42; i++) { + item = gnome_month_item_num2child (GNOME_MONTH_ITEM (mitem), GNOME_MONTH_ITEM_DAY_GROUP + i); + gtk_signal_connect (GTK_OBJECT (item), "event", + (GtkSignalFunc) day_event, + mitem); + } +} + static void year_view_init (YearView *yv) { @@ -191,10 +241,12 @@ year_view_init (YearView *yv) /* Month item */ yv->mitems[i] = gnome_month_item_new (gnome_canvas_root (GNOME_CANVAS (yv))); + gtk_object_set_user_data (GTK_OBJECT (yv->mitems[i]), yv); gnome_canvas_item_set (yv->mitems[i], "anchor", GTK_ANCHOR_NW, "start_on_monday", week_starts_on_monday, NULL); + setup_month_item (yv, i); } /* We will need to resize the items when we paint for the first time */ @@ -317,10 +369,7 @@ year_view_set (YearView *yv, time_t year) /* Unmark and re-mark all the months */ - for (i = 0; i < 12; i++) { - unmark_month_item (GNOME_MONTH_ITEM (yv->mitems[i])); - mark_month_item (GNOME_MONTH_ITEM (yv->mitems[i]), yv->calendar->cal); - } + year_view_colors_changed (yv); } void @@ -350,5 +399,6 @@ year_view_colors_changed (YearView *yv) for (i = 0; i < 12; i++) { unmark_month_item (GNOME_MONTH_ITEM (yv->mitems[i])); mark_month_item (GNOME_MONTH_ITEM (yv->mitems[i]), yv->calendar->cal); + month_item_prepare_prelight (GNOME_MONTH_ITEM (yv->mitems[i]), default_prelight_func, NULL); } } diff --git a/calendar/main.c b/calendar/main.c index 5ccdeee3ff..462e71a06a 100644 --- a/calendar/main.c +++ b/calendar/main.c @@ -251,22 +251,48 @@ quit_cmd (void) } } +/* Sets a clock cursor for the specified calendar window */ +static void +set_clock_cursor (GnomeCalendar *gcal) +{ + GdkCursor *cursor; + + cursor = gdk_cursor_new (GDK_WATCH); + gdk_window_set_cursor (GTK_WIDGET (gcal)->window, cursor); + gdk_cursor_destroy (cursor); + gdk_flush (); +} + +/* Resets the normal cursor for the specified calendar window */ +static void +set_normal_cursor (GnomeCalendar *gcal) +{ + gdk_window_set_cursor (GTK_WIDGET (gcal)->window, NULL); + gdk_flush (); +} + static void previous_clicked (GtkWidget *widget, GnomeCalendar *gcal) { + set_clock_cursor (gcal); gnome_calendar_previous (gcal); + set_normal_cursor (gcal); } static void next_clicked (GtkWidget *widget, GnomeCalendar *gcal) { + set_clock_cursor (gcal); gnome_calendar_next (gcal); + set_normal_cursor (gcal); } static void today_clicked (GtkWidget *widget, GnomeCalendar *gcal) { + set_clock_cursor (gcal); gnome_calendar_goto_today (gcal); + set_normal_cursor (gcal); } static void diff --git a/calendar/mark.c b/calendar/mark.c index 6aab8b1b74..f3725bb7e5 100644 --- a/calendar/mark.c +++ b/calendar/mark.c @@ -61,6 +61,7 @@ mark_current_day (GnomeMonthItem *mitem) item = gnome_month_item_num2child (mitem, GNOME_MONTH_ITEM_DAY_LABEL + day_index); gnome_canvas_item_set (item, "fill_color", color_spec_from_prop (COLOR_PROP_CURRENT_DAY_FG), + "font", CURRENT_DAY_FONT, NULL); } } @@ -115,4 +116,121 @@ unmark_month_item (GnomeMonthItem *mitem) gnome_canvas_item_set (GNOME_CANVAS_ITEM (mitem), "day_color", color_spec_from_prop (COLOR_PROP_DAY_FG), NULL); + + gnome_canvas_item_set (GNOME_CANVAS_ITEM (mitem), + "day_font", NORMAL_DAY_FONT, + NULL); +} + +/* Frees the prelight information in the month item when it is destroyed */ +static void +free_prelight_info (GtkObject *object, gpointer data) +{ + g_free (gtk_object_get_data (object, "prelight_info")); +} + +/* Handles EnterNotify and LeaveNotify events from the month item's day groups, and performs + * appropriate prelighting. + */ +static gint +day_event (GnomeCanvasItem *item, GdkEvent *event, gpointer data) +{ + GnomeCanvasItem *mitem; + GnomeCanvasItem *box; + int child_num, day; + gulong *day_pixels; + GetPrelightColorFunc func; + gpointer func_data; + char *spec; + GdkColor color; + + mitem = data; + child_num = gnome_month_item_child2num (GNOME_MONTH_ITEM (mitem), item); + day = gnome_month_item_num2day (GNOME_MONTH_ITEM (mitem), child_num); + + if (day == 0) + return FALSE; /* it was a day outside the month's range */ + + child_num -= GNOME_MONTH_ITEM_DAY_GROUP; + box = gnome_month_item_num2child (GNOME_MONTH_ITEM (mitem), GNOME_MONTH_ITEM_DAY_BOX + child_num); + + day_pixels = gtk_object_get_data (GTK_OBJECT (mitem), "prelight_info_pixels"); + func = gtk_object_get_data (GTK_OBJECT (mitem), "prelight_info_func"); + func_data = gtk_object_get_data (GTK_OBJECT (mitem), "prelight_info_data"); + + switch (event->type) { + case GDK_ENTER_NOTIFY: + spec = (* func) (func_data); + gnome_canvas_item_set (box, + "fill_color", spec, + NULL); + break; + + case GDK_LEAVE_NOTIFY: + color.pixel = day_pixels[child_num]; + gnome_canvas_item_set (box, + "fill_color_gdk", &color, + NULL); + break; + + default: + break; + } + + return FALSE; +} + +void +month_item_prepare_prelight (GnomeMonthItem *mitem, GetPrelightColorFunc func, gpointer func_data) +{ + gulong *day_pixels; + GnomeCanvasItem *day_group; + GnomeCanvasItem *box; + GtkArg arg; + GdkColor *color; + int i; + + day_pixels = gtk_object_get_data (GTK_OBJECT (mitem), "prelight_info_pixels"); + + /* Set up the buffer for day background colors and attach it to the month item, if necessary */ + + if (!day_pixels) { + /* Create the buffer and attach it */ + + day_pixels = g_new (gulong, 42); + gtk_object_set_data (GTK_OBJECT (mitem), "prelight_info_pixels", day_pixels); + gtk_object_set_data (GTK_OBJECT (mitem), "prelight_info_func", func); + gtk_object_set_data (GTK_OBJECT (mitem), "prelight_info_data", func_data); + gtk_signal_connect (GTK_OBJECT (mitem), "destroy", + (GtkSignalFunc) free_prelight_info, + NULL); + + /* Connect the appropriate signals to perform prelighting */ + + for (i = 0; i < 42; i++) { + day_group = gnome_month_item_num2child (GNOME_MONTH_ITEM (mitem), GNOME_MONTH_ITEM_DAY_GROUP + i); + gtk_signal_connect (GTK_OBJECT (day_group), "event", + (GtkSignalFunc) day_event, + mitem); + } + } + + /* Fetch the background colors from the day boxes and store them in the prelight info */ + + for (i = 0; i < 42; i++) { + box = gnome_month_item_num2child (mitem, GNOME_MONTH_ITEM_DAY_BOX + i); + + arg.name = "fill_color_gdk"; + gtk_object_getv (GTK_OBJECT (box), 1, &arg); + + color = GTK_VALUE_BOXED (arg); + day_pixels[i] = color->pixel; + g_free (color); + } +} + +char * +default_prelight_func (gpointer data) +{ + return color_spec_from_prop (COLOR_PROP_PRELIGHT_DAY_BG); } diff --git a/calendar/mark.h b/calendar/mark.h index 9ffafe20a7..0b849e96cc 100644 --- a/calendar/mark.h +++ b/calendar/mark.h @@ -12,6 +12,12 @@ #include "gnome-month-item.h" +/* These are the fonts used for the montly calendars */ + +#define NORMAL_DAY_FONT "-adobe-helvetica-medium-r-normal--10-*-72-72-p-*-iso8859-1" +#define CURRENT_DAY_FONT "-adobe-helvetica-bold-r-normal--12-*-72-72-p-*-iso8859-1" + + /* Takes a monthly calendar item and marks the days that have events scheduled for them in the * specified calendar. It also highlights the current day. */ @@ -20,5 +26,20 @@ void mark_month_item (GnomeMonthItem *mitem, Calendar *cal); /* Unmarks all the days in the specified month item */ void unmark_month_item (GnomeMonthItem *mitem); +/* Prepares a monthly calendar item to prelight when the mouse goes over the days. If it is called + * on a month item that had already been prepared, it updates the internal color buffers -- you need + * to do this if you re-mark the month item, or if you change the global color configuration. The + * specified function is used to query the prelight colors; it must return a color spec. + */ + +typedef char * (* GetPrelightColorFunc) (gpointer data); + +void month_item_prepare_prelight (GnomeMonthItem *mitem, GetPrelightColorFunc func, gpointer func_data); + +/* This is the default prelight function you can use for most puposes. You can use NULL as the + * func_data. + */ +char *default_prelight_func (gpointer data); + #endif diff --git a/calendar/month-view.c b/calendar/month-view.c index 4d1a9bf967..d84d7c98cc 100644 --- a/calendar/month-view.c +++ b/calendar/month-view.c @@ -9,6 +9,7 @@ #include #include "month-view.h" #include "main.h" +#include "mark.h" #define SPACING 4 /* Spacing between title and calendar */ @@ -212,6 +213,6 @@ month_view_colors_changed (MonthView *mv) g_return_if_fail (mv != NULL); g_return_if_fail (IS_MONTH_VIEW (mv)); - unmark_month_item (mv->mitem); + unmark_month_item (GNOME_MONTH_ITEM (mv->mitem)); /* FIXME */ } diff --git a/calendar/prop.c b/calendar/prop.c index bdc8c9e937..936170855f 100644 --- a/calendar/prop.c +++ b/calendar/prop.c @@ -1,6 +1,6 @@ -/* - * Calendar properties dialog box - * (C) 1998 the Free Software Foundation +/* Calendar properties dialog box + * + * Copyright (C) 1998 the Free Software Foundation * * Authors: Miguel de Icaza * Federico Mena @@ -9,8 +9,9 @@ #include #include #include "gnome-cal.h" -#include "main.h" #include "gnome-month-item.h" +#include "main.h" +#include "mark.h" /* These specify the page numbers in the preferences notebook */ enum { @@ -344,6 +345,60 @@ color_spec_from_picker (int num) return build_color_spec (r, g, b); } +/* Callback used to query prelight color information for the properties box */ +static char * +fetch_prelight_spec (gpointer data) +{ + return color_spec_from_picker (COLOR_PROP_PRELIGHT_DAY_BG); +} + +/* Marks fake event days in the month item sample */ +static void +fake_mark_days (void) +{ + static int day_nums[] = { 1, 4, 8, 16, 17, 18, 20, 25, 28 }; /* some random days */ + int day_index; + int i; + GnomeCanvasItem *item; + + for (i = 0; i < (sizeof (day_nums) / sizeof (day_nums[0])); i++) { + day_index = gnome_month_item_day2index (GNOME_MONTH_ITEM (month_item), day_nums[i]); + item = gnome_month_item_num2child (GNOME_MONTH_ITEM (month_item), GNOME_MONTH_ITEM_DAY_BOX + day_index); + gnome_canvas_item_set (item, + "fill_color", color_spec_from_picker (COLOR_PROP_MARK_DAY_BG), + NULL); + } +} + +/* Switches the month item to the current date and highlights the current day's number */ +static void +set_current_day (void) +{ + struct tm *tm; + time_t t; + GnomeCanvasItem *item; + int day_index; + + /* Set the date */ + + t = time (NULL); + tm = localtime (&t); + + gnome_canvas_item_set (month_item, + "year", tm->tm_year + 1900, + "month", tm->tm_mon, + NULL); + + /* Highlight current day */ + + day_index = gnome_month_item_day2index (GNOME_MONTH_ITEM (month_item), tm->tm_mday); + item = gnome_month_item_num2child (GNOME_MONTH_ITEM (month_item), GNOME_MONTH_ITEM_DAY_LABEL + day_index); + gnome_canvas_item_set (item, + "fill_color", color_spec_from_picker (COLOR_PROP_CURRENT_DAY_FG), + "font", CURRENT_DAY_FONT, + NULL); +} + /* Sets the colors of the month item to the current prerences */ static void reconfigure_month (void) @@ -360,10 +415,6 @@ reconfigure_month (void) "outline_color", color_spec_from_picker (COLOR_PROP_OUTLINE_COLOR), NULL); - /* FIXME: set the rest of the colors -- simulate marking of the month item, set the - * current day, etc. The following is incorrect. - */ - gnome_canvas_item_set (month_item, "day_box_color", color_spec_from_picker (COLOR_PROP_EMPTY_DAY_BG), NULL); @@ -371,6 +422,17 @@ reconfigure_month (void) gnome_canvas_item_set (month_item, "day_color", color_spec_from_picker (COLOR_PROP_DAY_FG), NULL); + + gnome_canvas_item_set (month_item, + "day_font", NORMAL_DAY_FONT, + NULL); + + fake_mark_days (); + set_current_day (); + + /* Reset prelighting information */ + + month_item_prepare_prelight (GNOME_MONTH_ITEM (month_item), fetch_prelight_spec, NULL); } /* Callback used when a color is changed */ diff --git a/calendar/year-view.c b/calendar/year-view.c index 7458b61500..97795628a4 100644 --- a/calendar/year-view.c +++ b/calendar/year-view.c @@ -154,6 +154,56 @@ need_resize (YearView *yv) yv->idle_id = gtk_idle_add (idle_handler, yv); } +/* Event handler for days in the year's month items */ +static gint +day_event (GnomeCanvasItem *item, GdkEvent *event, gpointer data) +{ + YearView *yv; + GnomeCanvasItem *mitem; + int child_num, day; + + mitem = data; + child_num = gnome_month_item_child2num (GNOME_MONTH_ITEM (mitem), item); + day = gnome_month_item_num2day (GNOME_MONTH_ITEM (mitem), child_num); + + yv = gtk_object_get_user_data (GTK_OBJECT (mitem)); + + switch (event->type) { + case GDK_BUTTON_PRESS: + if ((event->button.button == 1) && (day != 0)) + gnome_calendar_dayjump (yv->calendar, + time_from_day (GNOME_MONTH_ITEM (mitem)->year, + GNOME_MONTH_ITEM (mitem)->month, + day)); + break; + + default: + break; + } + + return FALSE; +} + +/* Sets up the month item with the specified index -- connects signals for handling events, etc. */ +static void +setup_month_item (YearView *yv, int n) +{ + GnomeCanvasItem *mitem; + GnomeCanvasItem *item; + int i; + + mitem = yv->mitems[n]; + + /* Connect signals */ + + for (i = 0; i < 42; i++) { + item = gnome_month_item_num2child (GNOME_MONTH_ITEM (mitem), GNOME_MONTH_ITEM_DAY_GROUP + i); + gtk_signal_connect (GTK_OBJECT (item), "event", + (GtkSignalFunc) day_event, + mitem); + } +} + static void year_view_init (YearView *yv) { @@ -191,10 +241,12 @@ year_view_init (YearView *yv) /* Month item */ yv->mitems[i] = gnome_month_item_new (gnome_canvas_root (GNOME_CANVAS (yv))); + gtk_object_set_user_data (GTK_OBJECT (yv->mitems[i]), yv); gnome_canvas_item_set (yv->mitems[i], "anchor", GTK_ANCHOR_NW, "start_on_monday", week_starts_on_monday, NULL); + setup_month_item (yv, i); } /* We will need to resize the items when we paint for the first time */ @@ -317,10 +369,7 @@ year_view_set (YearView *yv, time_t year) /* Unmark and re-mark all the months */ - for (i = 0; i < 12; i++) { - unmark_month_item (GNOME_MONTH_ITEM (yv->mitems[i])); - mark_month_item (GNOME_MONTH_ITEM (yv->mitems[i]), yv->calendar->cal); - } + year_view_colors_changed (yv); } void @@ -350,5 +399,6 @@ year_view_colors_changed (YearView *yv) for (i = 0; i < 12; i++) { unmark_month_item (GNOME_MONTH_ITEM (yv->mitems[i])); mark_month_item (GNOME_MONTH_ITEM (yv->mitems[i]), yv->calendar->cal); + month_item_prepare_prelight (GNOME_MONTH_ITEM (yv->mitems[i]), default_prelight_func, NULL); } } -- cgit