Stuff that I forgot to commit yesterday.

Stuff that I forgot to commit yesterday.

Now the year view has a nifty pop-up view you can activate if you click on
a day with mouse button 1.  It will display a quick view of the appointments
in that day.  Also, reworked the marking and coloring code for month items
so that the year view is not glacially slow anymore when switching years.

It still is slow when first mapping or realizing the year view, I'm not sure why.
I will look into that.

1998-09-29  Federico Mena Quintero  <federico@nuclecu.unam.mx>

	* prop.c (fetch_color_spec): Changed name from fetch_prelight_spec
	and made it conform to the new prelighting mechanism.
	(fake_mark_days): Set the proper day attributes.
	(reconfigure_month): Use colorify_month_item().
	(fake_mark_days): Use mark_month_item_index().

	* mark.c (colorify_month_item): New public function to reset the
	colors in a month item.
	(get_attributes): New internal function that creates an array of
	attributes for the days in a month item.  This is the basis of all
	the new optimizations to month item marking.
	(unmark_month_item): Now it uses the attributes array to unmark
	only the days that need unmarking.
	(mark_event_in_month): Update the day attributes array.
	(month_item_prepare_prelight): Changed the definition of the
	prelight color query function.  Use the new function.
	(day_event): Do color changes based on the day attributes array.
	(mark_month_item_index): New public function to mark a single day
	by index.
	(mark_event_in_month): Use mark_month_item_index().

	* gnome-month-item.c (gnome_month_item_num2child): Now takes an
	int, not a GnomeMonthItemChild.
	(gnome_month_item_child2num): Now returns an int, not a
	GnomeMonthItemChild.
	(gnome_month_item_num2day): Now takes an int, not a
	GnomeMonthItemChild.

	* goto.c (goto_dialog): Create the days before the year spin
	button, because the year_changed callback expects the month item
	to be created.  The new semantics of the spin button cause it to
	emit a value_changed signal on the adjustment upon creation -- is
	this the behavior we want from it?
	(goto_dialog): Use gtk_window_set_modal() instead of the
	deprectaed gnome_dialog_set_modal().

	* quick-view.c (quick_view_new): Make it look not as crappy by
	putting the title inside the frame.
	(quick_view_do_popup): Fixed the pointer grab and added a cursor.
	(create_items_for_event): Query the text width/height from the
	text item using the new object arguments, so that the size of the
	popup window can be set properly.

	* year-view.c (do_quick_view_popup): Calculate a nice date string
	for the popup window.

svn path=/trunk/; revision=415
This commit is contained in:
Federico Mena Quintero
1998-09-30 16:44:14 +00:00
committed by Arturo Espinosa
parent 9e927267cd
commit e6ffe37f19
24 changed files with 646 additions and 400 deletions

View File

@ -1,3 +1,51 @@
1998-09-29 Federico Mena Quintero <federico@nuclecu.unam.mx>
* prop.c (fetch_color_spec): Changed name from fetch_prelight_spec
and made it conform to the new prelighting mechanism.
(fake_mark_days): Set the proper day attributes.
(reconfigure_month): Use colorify_month_item().
(fake_mark_days): Use mark_month_item_index().
* mark.c (colorify_month_item): New public function to reset the
colors in a month item.
(get_attributes): New internal function that creates an array of
attributes for the days in a month item. This is the basis of all
the new optimizations to month item marking.
(unmark_month_item): Now it uses the attributes array to unmark
only the days that need unmarking.
(mark_event_in_month): Update the day attributes array.
(month_item_prepare_prelight): Changed the definition of the
prelight color query function. Use the new function.
(day_event): Do color changes based on the day attributes array.
(mark_month_item_index): New public function to mark a single day
by index.
(mark_event_in_month): Use mark_month_item_index().
* gnome-month-item.c (gnome_month_item_num2child): Now takes an
int, not a GnomeMonthItemChild.
(gnome_month_item_child2num): Now returns an int, not a
GnomeMonthItemChild.
(gnome_month_item_num2day): Now takes an int, not a
GnomeMonthItemChild.
* goto.c (goto_dialog): Create the days before the year spin
button, because the year_changed callback expects the month item
to be created. The new semantics of the spin button cause it to
emit a value_changed signal on the adjustment upon creation -- is
this the behavior we want from it?
(goto_dialog): Use gtk_window_set_modal() instead of the
deprectaed gnome_dialog_set_modal().
* quick-view.c (quick_view_new): Make it look not as crappy by
putting the title inside the frame.
(quick_view_do_popup): Fixed the pointer grab and added a cursor.
(create_items_for_event): Query the text width/height from the
text item using the new object arguments, so that the size of the
popup window can be set properly.
* year-view.c (do_quick_view_popup): Calculate a nice date string
for the popup window.
1998-09-28 Federico Mena Quintero <federico@nuclecu.unam.mx>
* quick-view.[ch]: New file that presents a quick view of the

View File

@ -5,10 +5,6 @@ BUGS:
Year view:
- When you press mouse button 1 on a day, have a temporary window pop
up. Display the date and the summaries of the day's appointments.
When you release the mouse button, the window should go away.
- See why it is so fucking slow.
Month view:

View File

@ -12,7 +12,6 @@
#include <gtk/gtkscrolledwindow.h>
#include <gtk/gtktable.h>
#include <libgnome/gnome-defs.h>
#include <libgnomeui/gtkcalendar.h>
#include "gnome-cal.h"
#include "gncal-full-day.h"
#include "gncal-todo.h"

View File

@ -13,7 +13,6 @@
#include <gtk/gtktable.h>
#include <gtk/gtkvbox.h>
#include <libgnome/gnome-defs.h>
#include <libgnomeui/gtkcalendar.h>
#include "gnome-cal.h"
#include "gncal-day-view.h"

View File

@ -1061,7 +1061,7 @@ gnome_month_item_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
}
GnomeCanvasItem *
gnome_month_item_num2child (GnomeMonthItem *mitem, GnomeMonthItemChild child_num)
gnome_month_item_num2child (GnomeMonthItem *mitem, int child_num)
{
g_return_val_if_fail (mitem != NULL, NULL);
g_return_val_if_fail (GNOME_IS_MONTH_ITEM (mitem), NULL);
@ -1069,7 +1069,7 @@ gnome_month_item_num2child (GnomeMonthItem *mitem, GnomeMonthItemChild child_num
return mitem->items[child_num];
}
GnomeMonthItemChild
int
gnome_month_item_child2num (GnomeMonthItem *mitem, GnomeCanvasItem *child)
{
int i;
@ -1087,7 +1087,7 @@ gnome_month_item_child2num (GnomeMonthItem *mitem, GnomeCanvasItem *child)
}
int
gnome_month_item_num2day (GnomeMonthItem *mitem, GnomeMonthItemChild child_num)
gnome_month_item_num2day (GnomeMonthItem *mitem, int child_num)
{
g_return_val_if_fail (mitem != NULL, 0);
g_return_val_if_fail (GNOME_IS_MONTH_ITEM (mitem), 0);

View File

@ -140,17 +140,17 @@ void gnome_month_item_construct (GnomeMonthItem *mitem);
/* Returns the child item defined by the child number (as specified on the GnomeMonthItemChild
* enumeration above).
*/
GnomeCanvasItem *gnome_month_item_num2child (GnomeMonthItem *mitem, GnomeMonthItemChild child_num);
GnomeCanvasItem *gnome_month_item_num2child (GnomeMonthItem *mitem, int child_num);
/* Returns the number of the specified child item, as defined on the GnomeMonthItemChild enumeration
* above. If the specified object is not found, it returns -1.
*/
GnomeMonthItemChild gnome_month_item_child2num (GnomeMonthItem *mitem, GnomeCanvasItem *child);
int gnome_month_item_child2num (GnomeMonthItem *mitem, GnomeCanvasItem *child);
/* Returns the number of the day relevant to the specified child item. Day numbers are 1-based. If
* the specified child is outside the range of displayed days, then it returns 0.
*/
int gnome_month_item_num2day (GnomeMonthItem *mitem, GnomeMonthItemChild child_num);
int gnome_month_item_num2day (GnomeMonthItem *mitem, int child_num);
/* Returns the index (0-41) of the specified date within the table of days. If the day number is
* invalid for the current monthly calendar, then -1 is returned.

View File

@ -26,7 +26,7 @@ update (void)
{
unmark_month_item (GNOME_MONTH_ITEM (month_item));
mark_month_item (GNOME_MONTH_ITEM (month_item), gnome_calendar->cal);
month_item_prepare_prelight (GNOME_MONTH_ITEM (month_item), default_prelight_func, NULL);
month_item_prepare_prelight (GNOME_MONTH_ITEM (month_item), default_color_func, NULL);
}
/* Callback used when the year adjustment is changed */
@ -222,6 +222,7 @@ goto_dialog (GnomeCalendar *gcal)
GtkWidget *vbox;
GtkWidget *hbox;
GtkWidget *w;
GtkWidget *days;
struct tm *tm;
gnome_calendar = gcal;
@ -244,6 +245,12 @@ goto_dialog (GnomeCalendar *gcal)
gtk_box_pack_start (GTK_BOX (vbox), w, FALSE, FALSE, 0);
gtk_widget_show (w);
/* Create month item before creating the year controls, since the latter ones need the
* month_item to be created.
*/
days = create_days (tm->tm_mday, tm->tm_mon, tm->tm_year + 1900);
/* Year */
w = create_year (tm->tm_year + 1900);
@ -258,9 +265,8 @@ goto_dialog (GnomeCalendar *gcal)
/* Days (canvas with month item) */
w = create_days (tm->tm_mday, tm->tm_mon, tm->tm_year + 1900);
gtk_box_pack_start (GTK_BOX (vbox), w, TRUE, TRUE, 0);
gtk_widget_show (w);
gtk_box_pack_start (GTK_BOX (vbox), days, TRUE, TRUE, 0);
gtk_widget_show (days);
/* Today button */
@ -277,7 +283,7 @@ goto_dialog (GnomeCalendar *gcal)
/* Run! */
gnome_dialog_set_modal (GNOME_DIALOG (goto_win));
gtk_window_set_modal (GTK_WINDOW (goto_win), TRUE);
gnome_dialog_set_close (GNOME_DIALOG (goto_win), TRUE);
gnome_dialog_set_parent (GNOME_DIALOG (goto_win), GTK_WINDOW (gnome_calendar));
gtk_widget_show (goto_win);

View File

@ -12,7 +12,6 @@
#include <gtk/gtkscrolledwindow.h>
#include <gtk/gtktable.h>
#include <libgnome/gnome-defs.h>
#include <libgnomeui/gtkcalendar.h>
#include "gnome-cal.h"
#include "gncal-full-day.h"
#include "gncal-todo.h"

View File

@ -13,7 +13,6 @@
#include <gtk/gtktable.h>
#include <gtk/gtkvbox.h>
#include <libgnome/gnome-defs.h>
#include <libgnomeui/gtkcalendar.h>
#include "gnome-cal.h"
#include "gncal-day-view.h"

View File

@ -1061,7 +1061,7 @@ gnome_month_item_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
}
GnomeCanvasItem *
gnome_month_item_num2child (GnomeMonthItem *mitem, GnomeMonthItemChild child_num)
gnome_month_item_num2child (GnomeMonthItem *mitem, int child_num)
{
g_return_val_if_fail (mitem != NULL, NULL);
g_return_val_if_fail (GNOME_IS_MONTH_ITEM (mitem), NULL);
@ -1069,7 +1069,7 @@ gnome_month_item_num2child (GnomeMonthItem *mitem, GnomeMonthItemChild child_num
return mitem->items[child_num];
}
GnomeMonthItemChild
int
gnome_month_item_child2num (GnomeMonthItem *mitem, GnomeCanvasItem *child)
{
int i;
@ -1087,7 +1087,7 @@ gnome_month_item_child2num (GnomeMonthItem *mitem, GnomeCanvasItem *child)
}
int
gnome_month_item_num2day (GnomeMonthItem *mitem, GnomeMonthItemChild child_num)
gnome_month_item_num2day (GnomeMonthItem *mitem, int child_num)
{
g_return_val_if_fail (mitem != NULL, 0);
g_return_val_if_fail (GNOME_IS_MONTH_ITEM (mitem), 0);

View File

@ -140,17 +140,17 @@ void gnome_month_item_construct (GnomeMonthItem *mitem);
/* Returns the child item defined by the child number (as specified on the GnomeMonthItemChild
* enumeration above).
*/
GnomeCanvasItem *gnome_month_item_num2child (GnomeMonthItem *mitem, GnomeMonthItemChild child_num);
GnomeCanvasItem *gnome_month_item_num2child (GnomeMonthItem *mitem, int child_num);
/* Returns the number of the specified child item, as defined on the GnomeMonthItemChild enumeration
* above. If the specified object is not found, it returns -1.
*/
GnomeMonthItemChild gnome_month_item_child2num (GnomeMonthItem *mitem, GnomeCanvasItem *child);
int gnome_month_item_child2num (GnomeMonthItem *mitem, GnomeCanvasItem *child);
/* Returns the number of the day relevant to the specified child item. Day numbers are 1-based. If
* the specified child is outside the range of displayed days, then it returns 0.
*/
int gnome_month_item_num2day (GnomeMonthItem *mitem, GnomeMonthItemChild child_num);
int gnome_month_item_num2day (GnomeMonthItem *mitem, int child_num);
/* Returns the index (0-41) of the specified date within the table of days. If the day number is
* invalid for the current monthly calendar, then -1 is returned.

View File

@ -26,7 +26,7 @@ update (void)
{
unmark_month_item (GNOME_MONTH_ITEM (month_item));
mark_month_item (GNOME_MONTH_ITEM (month_item), gnome_calendar->cal);
month_item_prepare_prelight (GNOME_MONTH_ITEM (month_item), default_prelight_func, NULL);
month_item_prepare_prelight (GNOME_MONTH_ITEM (month_item), default_color_func, NULL);
}
/* Callback used when the year adjustment is changed */
@ -222,6 +222,7 @@ goto_dialog (GnomeCalendar *gcal)
GtkWidget *vbox;
GtkWidget *hbox;
GtkWidget *w;
GtkWidget *days;
struct tm *tm;
gnome_calendar = gcal;
@ -244,6 +245,12 @@ goto_dialog (GnomeCalendar *gcal)
gtk_box_pack_start (GTK_BOX (vbox), w, FALSE, FALSE, 0);
gtk_widget_show (w);
/* Create month item before creating the year controls, since the latter ones need the
* month_item to be created.
*/
days = create_days (tm->tm_mday, tm->tm_mon, tm->tm_year + 1900);
/* Year */
w = create_year (tm->tm_year + 1900);
@ -258,9 +265,8 @@ goto_dialog (GnomeCalendar *gcal)
/* Days (canvas with month item) */
w = create_days (tm->tm_mday, tm->tm_mon, tm->tm_year + 1900);
gtk_box_pack_start (GTK_BOX (vbox), w, TRUE, TRUE, 0);
gtk_widget_show (w);
gtk_box_pack_start (GTK_BOX (vbox), days, TRUE, TRUE, 0);
gtk_widget_show (days);
/* Today button */
@ -277,7 +283,7 @@ goto_dialog (GnomeCalendar *gcal)
/* Run! */
gnome_dialog_set_modal (GNOME_DIALOG (goto_win));
gtk_window_set_modal (GTK_WINDOW (goto_win), TRUE);
gnome_dialog_set_close (GNOME_DIALOG (goto_win), TRUE);
gnome_dialog_set_parent (GNOME_DIALOG (goto_win), GTK_WINDOW (gnome_calendar));
gtk_widget_show (goto_win);

View File

@ -10,7 +10,7 @@ extern int week_starts_on_monday;
/* This enum and the following array define the color preferences */
enum {
typedef enum {
COLOR_PROP_OUTLINE_COLOR, /* Color of calendar outline */
COLOR_PROP_HEADING_COLOR, /* Color for headings */
COLOR_PROP_EMPTY_DAY_BG, /* Background color for empty days */
@ -19,7 +19,7 @@ enum {
COLOR_PROP_DAY_FG, /* Color for day numbers */
COLOR_PROP_CURRENT_DAY_FG, /* Color for current day's number */
COLOR_PROP_LAST /* Number of color properties */
};
} ColorProp;
struct color_prop {
int r; /* Values are in [0, 65535] */
@ -54,7 +54,7 @@ char *build_color_spec (int r, int g, int b);
void parse_color_spec (char *spec, int *r, int *g, int *b);
/* Calls build_color_spec() for the color in the specified property number */
char *color_spec_from_prop (int propnum);
char *color_spec_from_prop (ColorProp propnum);
#endif

View File

@ -12,14 +12,72 @@
#include "timeutil.h"
/* Frees the specified data when an object is destroyed */
static void
free_data (GtkObject *object, gpointer data)
{
g_free (data);
}
/* If the array of "marked" attributes for the days in a a month item has not been created yet, this
* function creates the array and clears it. Otherwise, it just returns the existing array.
*/
static char *
get_attributes (GnomeMonthItem *mitem)
{
char *attrs;
attrs = gtk_object_get_data (GTK_OBJECT (mitem), "day_mark_attributes");
if (!attrs) {
attrs = g_new0 (char, 42);
gtk_object_set_data (GTK_OBJECT (mitem), "day_mark_attributes", attrs);
gtk_signal_connect (GTK_OBJECT (mitem), "destroy",
(GtkSignalFunc) free_data,
attrs);
}
return attrs;
}
void
colorify_month_item (GnomeMonthItem *mitem, GetColorFunc func, gpointer func_data)
{
g_return_if_fail (mitem != NULL);
g_return_if_fail (GNOME_IS_MONTH_ITEM (mitem));
g_return_if_fail (func != NULL);
unmark_month_item (mitem);
/* We have to do this in several calls to gnome_canvas_item_set(), as color_spec_from_prop()
* returns a pointer to a static string -- and we need several values.
*/
gnome_canvas_item_set (GNOME_CANVAS_ITEM (mitem),
"heading_color", (* func) (COLOR_PROP_HEADING_COLOR, func_data),
NULL);
gnome_canvas_item_set (GNOME_CANVAS_ITEM (mitem),
"outline_color", (* func) (COLOR_PROP_OUTLINE_COLOR, func_data),
NULL);
gnome_canvas_item_set (GNOME_CANVAS_ITEM (mitem),
"day_box_color", (* func) (COLOR_PROP_EMPTY_DAY_BG, func_data),
NULL);
gnome_canvas_item_set (GNOME_CANVAS_ITEM (mitem),
"day_color", (* func) (COLOR_PROP_DAY_FG, func_data),
NULL);
}
/* In the month item, marks all the days that are touched by the specified time span. Assumes that
* the time span is completely contained within the month.
* the time span is completely contained within the month. The array of day attributes is modified
* accordingly.
*/
static void
mark_event_in_month (GnomeMonthItem *mitem, time_t start, time_t end)
{
struct tm tm;
GnomeCanvasItem *item;
int day_index;
tm = *localtime (&start);
@ -34,10 +92,7 @@ mark_event_in_month (GnomeMonthItem *mitem, time_t start, time_t end)
/* Mark the day box */
item = gnome_month_item_num2child (mitem, GNOME_MONTH_ITEM_DAY_BOX + day_index);
gnome_canvas_item_set (item,
"fill_color", color_spec_from_prop (COLOR_PROP_MARK_DAY_BG),
NULL);
mark_month_item_index (mitem, day_index, default_color_func, NULL);
/* Next day */
@ -73,6 +128,10 @@ mark_month_item (GnomeMonthItem *mitem, Calendar *cal)
GList *list, *l;
CalendarObject *co;
g_return_if_fail (mitem != NULL);
g_return_if_fail (GNOME_IS_MONTH_ITEM (mitem));
g_return_if_fail (cal != NULL);
month_begin = time_month_begin (time_from_day (mitem->year, mitem->month, 1));
month_end = time_month_end (month_begin);
@ -87,47 +146,54 @@ mark_month_item (GnomeMonthItem *mitem, Calendar *cal)
}
calendar_destroy_event_list (list);
}
mark_current_day (mitem);
void
mark_month_item_index (GnomeMonthItem *mitem, int index, GetColorFunc func, gpointer func_data)
{
char *attrs;
GnomeCanvasItem *item;
g_return_if_fail (mitem != NULL);
g_return_if_fail (GNOME_IS_MONTH_ITEM (mitem));
g_return_if_fail ((index >= 0) && (index < 42));
g_return_if_fail (func != NULL);
attrs = get_attributes (mitem);
attrs[index] = TRUE;
item = gnome_month_item_num2child (mitem, GNOME_MONTH_ITEM_DAY_BOX + index);
gnome_canvas_item_set (item,
"fill_color", (* func) (COLOR_PROP_MARK_DAY_BG, func_data),
NULL);
}
void
unmark_month_item (GnomeMonthItem *mitem)
{
int i;
char *attrs;
GnomeCanvasItem *item;
g_return_if_fail (mitem != NULL);
g_return_if_fail (GNOME_IS_MONTH_ITEM (mitem));
/* We have to do this in several calls to gnome_canvas_item_set(), as color_spec_from_prop()
* returns a pointer to a static string -- and we need several values.
attrs = get_attributes (mitem);
/* Find marked days and unmark them by turning off their marked attribute flag and changing
* the color.
*/
gnome_canvas_item_set (GNOME_CANVAS_ITEM (mitem),
"heading_color", color_spec_from_prop (COLOR_PROP_HEADING_COLOR),
NULL);
for (i = 0; i < 42; i++)
if (attrs[i]) {
attrs[i] = FALSE;
gnome_canvas_item_set (GNOME_CANVAS_ITEM (mitem),
"outline_color", color_spec_from_prop (COLOR_PROP_OUTLINE_COLOR),
NULL);
gnome_canvas_item_set (GNOME_CANVAS_ITEM (mitem),
"day_box_color", color_spec_from_prop (COLOR_PROP_EMPTY_DAY_BG),
NULL);
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"));
item = gnome_month_item_num2child (mitem, GNOME_MONTH_ITEM_DAY_BOX + i);
gnome_canvas_item_set (item,
"fill_color", color_spec_from_prop (COLOR_PROP_EMPTY_DAY_BG),
NULL);
}
}
/* Handles EnterNotify and LeaveNotify events from the month item's day groups, and performs
@ -136,102 +202,89 @@ free_prelight_info (GtkObject *object, gpointer data)
static gint
day_event (GnomeCanvasItem *item, GdkEvent *event, gpointer data)
{
GnomeCanvasItem *mitem;
GnomeMonthItem *mitem;
GnomeCanvasItem *box;
int child_num, day;
gulong *day_pixels;
GetPrelightColorFunc func;
GetColorFunc func;
gpointer func_data;
char *spec;
GdkColor color;
char *color;
char *attrs;
mitem = data;
child_num = gnome_month_item_child2num (GNOME_MONTH_ITEM (mitem), item);
day = gnome_month_item_num2day (GNOME_MONTH_ITEM (mitem), child_num);
/* We only accept enters and leaves */
if (!((event->type == GDK_ENTER_NOTIFY) || (event->type == GDK_LEAVE_NOTIFY)))
return FALSE;
/* Get index information */
mitem = GNOME_MONTH_ITEM (data);
child_num = gnome_month_item_child2num (mitem, item);
day = gnome_month_item_num2day (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);
box = gnome_month_item_num2child (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");
/* Get colors */
func = gtk_object_get_data (GTK_OBJECT (mitem), "prelight_color_func");
func_data = gtk_object_get_data (GTK_OBJECT (mitem), "prelight_color_data");
/* Now actually set the proper color in the item */
switch (event->type) {
case GDK_ENTER_NOTIFY:
spec = (* func) (func_data);
color = (* func) (COLOR_PROP_PRELIGHT_DAY_BG, func_data);
gnome_canvas_item_set (box,
"fill_color", spec,
"fill_color", color,
NULL);
break;
case GDK_LEAVE_NOTIFY:
color.pixel = day_pixels[child_num];
attrs = get_attributes (mitem);
color = (* func) (attrs[child_num] ? COLOR_PROP_MARK_DAY_BG : COLOR_PROP_EMPTY_DAY_BG,
func_data);
gnome_canvas_item_set (box,
"fill_color_gdk", &color,
"fill_color", color,
NULL);
break;
default:
break;
g_assert_not_reached ();
}
return FALSE;
return TRUE;
}
void
month_item_prepare_prelight (GnomeMonthItem *mitem, GetPrelightColorFunc func, gpointer func_data)
month_item_prepare_prelight (GnomeMonthItem *mitem, GetColorFunc 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");
g_return_if_fail (mitem != NULL);
g_return_if_fail (GNOME_IS_MONTH_ITEM (mitem));
g_return_if_fail (func != NULL);
/* Set up the buffer for day background colors and attach it to the month item, if necessary */
/* Store the function in the object data */
if (!day_pixels) {
/* Create the buffer and attach it */
gtk_object_set_data (GTK_OBJECT (mitem), "prelight_color_func", func);
gtk_object_set_data (GTK_OBJECT (mitem), "prelight_color_data", func_data);
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 */
/* Connect the appropriate signals to perform prelighting */
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);
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);
}
}
char *
default_prelight_func (gpointer data)
default_color_func (ColorProp propnum, gpointer data)
{
return color_spec_from_prop (COLOR_PROP_PRELIGHT_DAY_BG);
return color_spec_from_prop (propnum);
}

View File

@ -18,28 +18,34 @@
#define CURRENT_DAY_FONT "-adobe-helvetica-bold-r-normal--12-*-72-72-p-*-iso8859-1"
/* Functions of this type are used by the marking functions to fetch color specifications. Such
* a function must return a color spec based on the property passed to it.
*/
typedef char * (* GetColorFunc) (ColorProp propnum, gpointer data);
/* Sets the user-configured colors and font for a month item. It also tags the days as unmarked. */
void colorify_month_item (GnomeMonthItem *month, GetColorFunc func, gpointer func_data);
/* 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.
*/
void mark_month_item (GnomeMonthItem *mitem, Calendar *cal);
/* Marks a day specified by index, not by day number */
void mark_month_item_index (GnomeMonthItem *mitem, int index, GetColorFunc func, gpointer func_data);
/* 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.
*/
/* Prepares a monthly calendar item to prelight when the mouse goes over the days. */
typedef char * (* GetPrelightColorFunc) (gpointer data);
void month_item_prepare_prelight (GnomeMonthItem *mitem, GetPrelightColorFunc func, gpointer func_data);
void month_item_prepare_prelight (GnomeMonthItem *mitem, GetColorFunc 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);
char *default_color_func (ColorProp prop_num, gpointer data);
#endif

View File

@ -345,11 +345,11 @@ color_spec_from_picker (int num)
return build_color_spec (r, g, b);
}
/* Callback used to query prelight color information for the properties box */
/* Callback used to query color information for the properties box */
static char *
fetch_prelight_spec (gpointer data)
fetch_color_spec (ColorProp propnum, gpointer data)
{
return color_spec_from_picker (COLOR_PROP_PRELIGHT_DAY_BG);
return color_spec_from_picker (propnum);
}
/* Marks fake event days in the month item sample */
@ -357,17 +357,14 @@ 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 first_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);
}
first_day_index = gnome_month_item_day2index (GNOME_MONTH_ITEM (month_item), 1);
for (i = 0; i < (sizeof (day_nums) / sizeof (day_nums[0])); i++)
mark_month_item_index (GNOME_MONTH_ITEM (month_item), first_day_index + day_nums[i] - 1,
fetch_color_spec, NULL);
}
/* Switches the month item to the current date and highlights the current day's number */
@ -399,40 +396,24 @@ set_current_day (void)
NULL);
}
/* This is the version of a color spec query function that is appropriate for the preferences dialog */
static char *
prop_color_func (ColorProp propnum, gpointer data)
{
return color_spec_from_picker (propnum);
}
/* Sets the colors of the month item to the current prerences */
static void
reconfigure_month (void)
{
/* We have to do this in two calls to gnome_canvas_item_set(), as color_spec_from_picker()
* returns a pointer to a static string -- and we need two values.
*/
gnome_canvas_item_set (month_item,
"heading_color", color_spec_from_picker (COLOR_PROP_HEADING_COLOR),
NULL);
gnome_canvas_item_set (month_item,
"outline_color", color_spec_from_picker (COLOR_PROP_OUTLINE_COLOR),
NULL);
gnome_canvas_item_set (month_item,
"day_box_color", color_spec_from_picker (COLOR_PROP_EMPTY_DAY_BG),
NULL);
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);
colorify_month_item (GNOME_MONTH_ITEM (month_item), prop_color_func, NULL);
fake_mark_days ();
set_current_day ();
/* Reset prelighting information */
month_item_prepare_prelight (GNOME_MONTH_ITEM (month_item), fetch_prelight_spec, NULL);
month_item_prepare_prelight (GNOME_MONTH_ITEM (month_item), fetch_color_spec, NULL);
}
/* Callback used when a color is changed */
@ -560,7 +541,7 @@ parse_color_spec (char *spec, int *r, int *g, int *b)
}
char *
color_spec_from_prop (int propnum)
color_spec_from_prop (ColorProp propnum)
{
return build_color_spec (color_props[propnum].r, color_props[propnum].g, color_props[propnum].b);
}

View File

@ -10,6 +10,9 @@
#include "main.h"
#define QUICK_VIEW_FONT "-adobe-helvetica-medium-r-normal--10-*-*-*-p-*-*-*"
static void quick_view_class_init (QuickViewClass *class);
static void quick_view_init (QuickView *qv);
@ -63,7 +66,7 @@ button_release (GtkWidget *widget, GdkEventButton *event, gpointer data)
return FALSE;
gdk_pointer_ungrab (event->time);
gtk_grab_remove (GTK_WIDGET (qv));
gtk_grab_remove (GTK_WIDGET (qv->canvas));
gtk_widget_hide (GTK_WIDGET (qv));
gtk_main_quit (); /* End modality */
@ -72,15 +75,18 @@ button_release (GtkWidget *widget, GdkEventButton *event, gpointer data)
/* Creates the items corresponding to a single calendar object. Takes in the y position of the
* items to create and returns the y position of the next item to create.
* items to create and returns the y position of the next item to create. Also takes in the current
* maximum width for items and returns the new maximum width.
*/
double
create_items_for_event (QuickView *qv, CalendarObject *co, double y)
void
create_items_for_event (QuickView *qv, CalendarObject *co, double *y, double *max_width)
{
GnomeCanvas *canvas;
GnomeCanvasItem *item;
char start[100], end[100];
struct tm start_tm, end_tm;
char *str;
GtkArg args[2];
/* FIXME: make this nice */
@ -99,17 +105,27 @@ create_items_for_event (QuickView *qv, CalendarObject *co, double y)
str = g_copy_strings (start, " - ", end, " ", co->ico->summary, NULL);
gnome_canvas_item_new (gnome_canvas_root (canvas),
gnome_canvas_text_get_type (),
"x", 0.0,
"y", y,
"anchor", GTK_ANCHOR_NW,
"text", str,
NULL);
item = gnome_canvas_item_new (gnome_canvas_root (canvas),
gnome_canvas_text_get_type (),
"x", 0.0,
"y", *y,
"anchor", GTK_ANCHOR_NW,
"text", str,
"font", QUICK_VIEW_FONT,
NULL);
g_free (str);
return (y + 16); /* FIXME */
/* Measure the text and return the proper size values */
args[0].name = "text_width";
args[1].name = "text_height";
gtk_object_getv (GTK_OBJECT (item), 2, args);
if (GTK_VALUE_DOUBLE (args[0]) > *max_width)
*max_width = GTK_VALUE_DOUBLE (args[0]);
*y += GTK_VALUE_DOUBLE (args[1]);
}
/* Creates the canvas items corresponding to the events in the list */
@ -117,43 +133,56 @@ static void
setup_event_list (QuickView *qv, GList *event_list)
{
CalendarObject *co;
double y;
GnomeCanvasItem *item;
GtkArg args[2];
double y, max_width;
/* If there are no events, then just put a simple label */
if (!event_list) {
gnome_canvas_item_new (gnome_canvas_root (GNOME_CANVAS (qv->canvas)),
gnome_canvas_text_get_type (),
"x", 0.0,
"y", 0.0,
"anchor", GTK_ANCHOR_NW,
"text", _("No appointments scheduled for this day"),
NULL);
return;
}
item = gnome_canvas_item_new (gnome_canvas_root (GNOME_CANVAS (qv->canvas)),
gnome_canvas_text_get_type (),
"x", 0.0,
"y", 0.0,
"anchor", GTK_ANCHOR_NW,
"text", _("No appointments for this day"),
"font", QUICK_VIEW_FONT,
NULL);
/* Create the items for all the events in the list */
/* Measure the text and set the proper sizes */
y = 0.0;
args[0].name = "text_width";
args[1].name = "text_height";
gtk_object_getv (GTK_OBJECT (item), 2, args);
for (; event_list; event_list = event_list->next) {
co = event_list->data;
y = create_items_for_event (qv, co, y);
y = GTK_VALUE_DOUBLE (args[1]);
max_width = GTK_VALUE_DOUBLE (args[0]);
} else {
/* Create the items for all the events in the list */
y = 0.0;
max_width = 0.0;
for (; event_list; event_list = event_list->next) {
co = event_list->data;
create_items_for_event (qv, co, &y, &max_width);
}
}
/* Set the scrolling region to fit all the items */
gnome_canvas_set_scroll_region (GNOME_CANVAS (qv->canvas),
0.0, 0.0,
300.0, y); /* FIXME: figure out reasonable sizes */
max_width, y);
gnome_canvas_set_size (GNOME_CANVAS (qv->canvas), 300, y);
gnome_canvas_set_size (GNOME_CANVAS (qv->canvas), max_width, y);
}
GtkWidget *
quick_view_new (GnomeCalendar *calendar, char *title, GList *event_list)
{
QuickView *qv;
GtkWidget *vbox;
GtkWidget *w;
g_return_val_if_fail (calendar != NULL, NULL);
@ -164,9 +193,22 @@ quick_view_new (GnomeCalendar *calendar, char *title, GList *event_list)
/* Create base widgets for the popup window */
w = gtk_frame_new (title);
w = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (w), GTK_SHADOW_OUT);
gtk_container_add (GTK_CONTAINER (qv), w);
gtk_widget_show (w);
vbox = gtk_vbox_new (FALSE, 0);
gtk_container_add (GTK_CONTAINER (w), vbox);
w = gtk_label_new (title);
gtk_box_pack_start (GTK_BOX (vbox), w, FALSE, FALSE, 0);
w = gtk_hseparator_new ();
gtk_box_pack_start (GTK_BOX (vbox), w, FALSE, FALSE, 0);
w = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
gtk_container_border_width (GTK_CONTAINER (w), GNOME_PAD_SMALL);
gtk_box_pack_start (GTK_BOX (vbox), w, TRUE, TRUE, 0);
gtk_widget_push_visual (gdk_imlib_get_visual ());
gtk_widget_push_colormap (gdk_imlib_get_colormap ());
@ -181,7 +223,6 @@ quick_view_new (GnomeCalendar *calendar, char *title, GList *event_list)
qv);
gtk_container_add (GTK_CONTAINER (w), qv->canvas);
gtk_widget_show (qv->canvas);
/* Set up the event list */
@ -193,21 +234,27 @@ quick_view_new (GnomeCalendar *calendar, char *title, GList *event_list)
void
quick_view_do_popup (QuickView *qv, GdkEventButton *event)
{
GdkCursor *cursor;
g_return_if_fail (qv != NULL);
g_return_if_fail (IS_QUICK_VIEW (qv));
g_return_if_fail (event != NULL);
/* Pop up the window */
gtk_widget_show (GTK_WIDGET (qv));
gtk_grab_add (GTK_WIDGET (qv));
gtk_widget_show_all (GTK_WIDGET (qv));
gtk_grab_add (qv->canvas);
gdk_pointer_grab (GTK_WIDGET (qv)->window,
TRUE,
GDK_BUTTON_RELEASE_MASK,
NULL,
NULL,
event->time);
cursor = gdk_cursor_new (GDK_ARROW);
while (gdk_pointer_grab (GTK_LAYOUT (qv->canvas)->bin_window,
TRUE,
GDK_BUTTON_RELEASE_MASK,
NULL,
cursor,
event->time) != 0); /* wait for success */
gdk_cursor_destroy (cursor);
qv->button = event->button;

View File

@ -313,13 +313,15 @@ do_quick_view_popup (YearView *yv, GdkEventButton *event, int year, int month, i
time_t day_start, day_end;
GList *list;
GtkWidget *qv;
char date_str[256];
day_start = time_from_day (year, month, day);
day_end = time_end_of_day (day_start);
list = calendar_get_events_in_range (yv->calendar->cal, day_start, day_end);
qv = quick_view_new (yv->calendar, "Put the date here", list);
strftime (date_str, sizeof (date_str), "%a %b %d %Y", localtime (&day_start));
qv = quick_view_new (yv->calendar, date_str, list);
quick_view_do_popup (QUICK_VIEW (qv), event);
@ -425,6 +427,10 @@ setup_month_item (YearView *yv, int n)
gtk_signal_connect (GTK_OBJECT (mitem), "event",
(GtkSignalFunc) month_event,
NULL);
/* Prepare for prelighting */
month_item_prepare_prelight (GNOME_MONTH_ITEM (mitem), default_color_func, NULL);
}
static void
@ -507,6 +513,7 @@ year_view_new (GnomeCalendar *calendar, time_t year)
yv = gtk_type_new (year_view_get_type ());
yv->calendar = calendar;
year_view_colors_changed (yv);
year_view_set (yv, year);
return GTK_WIDGET (yv);
}
@ -591,7 +598,10 @@ year_view_set (YearView *yv, time_t year)
/* Unmark and re-mark all the months */
year_view_colors_changed (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);
}
}
void
@ -618,9 +628,9 @@ year_view_colors_changed (YearView *yv)
g_return_if_fail (yv != NULL);
g_return_if_fail (IS_YEAR_VIEW (yv));
for (i = 0; i < 12; i++) {
unmark_month_item (GNOME_MONTH_ITEM (yv->mitems[i]));
colorify_month_item (GNOME_MONTH_ITEM (yv->mitems[i]), default_color_func, NULL);
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);
}
}

View File

@ -10,7 +10,7 @@ extern int week_starts_on_monday;
/* This enum and the following array define the color preferences */
enum {
typedef enum {
COLOR_PROP_OUTLINE_COLOR, /* Color of calendar outline */
COLOR_PROP_HEADING_COLOR, /* Color for headings */
COLOR_PROP_EMPTY_DAY_BG, /* Background color for empty days */
@ -19,7 +19,7 @@ enum {
COLOR_PROP_DAY_FG, /* Color for day numbers */
COLOR_PROP_CURRENT_DAY_FG, /* Color for current day's number */
COLOR_PROP_LAST /* Number of color properties */
};
} ColorProp;
struct color_prop {
int r; /* Values are in [0, 65535] */
@ -54,7 +54,7 @@ char *build_color_spec (int r, int g, int b);
void parse_color_spec (char *spec, int *r, int *g, int *b);
/* Calls build_color_spec() for the color in the specified property number */
char *color_spec_from_prop (int propnum);
char *color_spec_from_prop (ColorProp propnum);
#endif

View File

@ -12,14 +12,72 @@
#include "timeutil.h"
/* Frees the specified data when an object is destroyed */
static void
free_data (GtkObject *object, gpointer data)
{
g_free (data);
}
/* If the array of "marked" attributes for the days in a a month item has not been created yet, this
* function creates the array and clears it. Otherwise, it just returns the existing array.
*/
static char *
get_attributes (GnomeMonthItem *mitem)
{
char *attrs;
attrs = gtk_object_get_data (GTK_OBJECT (mitem), "day_mark_attributes");
if (!attrs) {
attrs = g_new0 (char, 42);
gtk_object_set_data (GTK_OBJECT (mitem), "day_mark_attributes", attrs);
gtk_signal_connect (GTK_OBJECT (mitem), "destroy",
(GtkSignalFunc) free_data,
attrs);
}
return attrs;
}
void
colorify_month_item (GnomeMonthItem *mitem, GetColorFunc func, gpointer func_data)
{
g_return_if_fail (mitem != NULL);
g_return_if_fail (GNOME_IS_MONTH_ITEM (mitem));
g_return_if_fail (func != NULL);
unmark_month_item (mitem);
/* We have to do this in several calls to gnome_canvas_item_set(), as color_spec_from_prop()
* returns a pointer to a static string -- and we need several values.
*/
gnome_canvas_item_set (GNOME_CANVAS_ITEM (mitem),
"heading_color", (* func) (COLOR_PROP_HEADING_COLOR, func_data),
NULL);
gnome_canvas_item_set (GNOME_CANVAS_ITEM (mitem),
"outline_color", (* func) (COLOR_PROP_OUTLINE_COLOR, func_data),
NULL);
gnome_canvas_item_set (GNOME_CANVAS_ITEM (mitem),
"day_box_color", (* func) (COLOR_PROP_EMPTY_DAY_BG, func_data),
NULL);
gnome_canvas_item_set (GNOME_CANVAS_ITEM (mitem),
"day_color", (* func) (COLOR_PROP_DAY_FG, func_data),
NULL);
}
/* In the month item, marks all the days that are touched by the specified time span. Assumes that
* the time span is completely contained within the month.
* the time span is completely contained within the month. The array of day attributes is modified
* accordingly.
*/
static void
mark_event_in_month (GnomeMonthItem *mitem, time_t start, time_t end)
{
struct tm tm;
GnomeCanvasItem *item;
int day_index;
tm = *localtime (&start);
@ -34,10 +92,7 @@ mark_event_in_month (GnomeMonthItem *mitem, time_t start, time_t end)
/* Mark the day box */
item = gnome_month_item_num2child (mitem, GNOME_MONTH_ITEM_DAY_BOX + day_index);
gnome_canvas_item_set (item,
"fill_color", color_spec_from_prop (COLOR_PROP_MARK_DAY_BG),
NULL);
mark_month_item_index (mitem, day_index, default_color_func, NULL);
/* Next day */
@ -73,6 +128,10 @@ mark_month_item (GnomeMonthItem *mitem, Calendar *cal)
GList *list, *l;
CalendarObject *co;
g_return_if_fail (mitem != NULL);
g_return_if_fail (GNOME_IS_MONTH_ITEM (mitem));
g_return_if_fail (cal != NULL);
month_begin = time_month_begin (time_from_day (mitem->year, mitem->month, 1));
month_end = time_month_end (month_begin);
@ -87,47 +146,54 @@ mark_month_item (GnomeMonthItem *mitem, Calendar *cal)
}
calendar_destroy_event_list (list);
}
mark_current_day (mitem);
void
mark_month_item_index (GnomeMonthItem *mitem, int index, GetColorFunc func, gpointer func_data)
{
char *attrs;
GnomeCanvasItem *item;
g_return_if_fail (mitem != NULL);
g_return_if_fail (GNOME_IS_MONTH_ITEM (mitem));
g_return_if_fail ((index >= 0) && (index < 42));
g_return_if_fail (func != NULL);
attrs = get_attributes (mitem);
attrs[index] = TRUE;
item = gnome_month_item_num2child (mitem, GNOME_MONTH_ITEM_DAY_BOX + index);
gnome_canvas_item_set (item,
"fill_color", (* func) (COLOR_PROP_MARK_DAY_BG, func_data),
NULL);
}
void
unmark_month_item (GnomeMonthItem *mitem)
{
int i;
char *attrs;
GnomeCanvasItem *item;
g_return_if_fail (mitem != NULL);
g_return_if_fail (GNOME_IS_MONTH_ITEM (mitem));
/* We have to do this in several calls to gnome_canvas_item_set(), as color_spec_from_prop()
* returns a pointer to a static string -- and we need several values.
attrs = get_attributes (mitem);
/* Find marked days and unmark them by turning off their marked attribute flag and changing
* the color.
*/
gnome_canvas_item_set (GNOME_CANVAS_ITEM (mitem),
"heading_color", color_spec_from_prop (COLOR_PROP_HEADING_COLOR),
NULL);
for (i = 0; i < 42; i++)
if (attrs[i]) {
attrs[i] = FALSE;
gnome_canvas_item_set (GNOME_CANVAS_ITEM (mitem),
"outline_color", color_spec_from_prop (COLOR_PROP_OUTLINE_COLOR),
NULL);
gnome_canvas_item_set (GNOME_CANVAS_ITEM (mitem),
"day_box_color", color_spec_from_prop (COLOR_PROP_EMPTY_DAY_BG),
NULL);
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"));
item = gnome_month_item_num2child (mitem, GNOME_MONTH_ITEM_DAY_BOX + i);
gnome_canvas_item_set (item,
"fill_color", color_spec_from_prop (COLOR_PROP_EMPTY_DAY_BG),
NULL);
}
}
/* Handles EnterNotify and LeaveNotify events from the month item's day groups, and performs
@ -136,102 +202,89 @@ free_prelight_info (GtkObject *object, gpointer data)
static gint
day_event (GnomeCanvasItem *item, GdkEvent *event, gpointer data)
{
GnomeCanvasItem *mitem;
GnomeMonthItem *mitem;
GnomeCanvasItem *box;
int child_num, day;
gulong *day_pixels;
GetPrelightColorFunc func;
GetColorFunc func;
gpointer func_data;
char *spec;
GdkColor color;
char *color;
char *attrs;
mitem = data;
child_num = gnome_month_item_child2num (GNOME_MONTH_ITEM (mitem), item);
day = gnome_month_item_num2day (GNOME_MONTH_ITEM (mitem), child_num);
/* We only accept enters and leaves */
if (!((event->type == GDK_ENTER_NOTIFY) || (event->type == GDK_LEAVE_NOTIFY)))
return FALSE;
/* Get index information */
mitem = GNOME_MONTH_ITEM (data);
child_num = gnome_month_item_child2num (mitem, item);
day = gnome_month_item_num2day (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);
box = gnome_month_item_num2child (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");
/* Get colors */
func = gtk_object_get_data (GTK_OBJECT (mitem), "prelight_color_func");
func_data = gtk_object_get_data (GTK_OBJECT (mitem), "prelight_color_data");
/* Now actually set the proper color in the item */
switch (event->type) {
case GDK_ENTER_NOTIFY:
spec = (* func) (func_data);
color = (* func) (COLOR_PROP_PRELIGHT_DAY_BG, func_data);
gnome_canvas_item_set (box,
"fill_color", spec,
"fill_color", color,
NULL);
break;
case GDK_LEAVE_NOTIFY:
color.pixel = day_pixels[child_num];
attrs = get_attributes (mitem);
color = (* func) (attrs[child_num] ? COLOR_PROP_MARK_DAY_BG : COLOR_PROP_EMPTY_DAY_BG,
func_data);
gnome_canvas_item_set (box,
"fill_color_gdk", &color,
"fill_color", color,
NULL);
break;
default:
break;
g_assert_not_reached ();
}
return FALSE;
return TRUE;
}
void
month_item_prepare_prelight (GnomeMonthItem *mitem, GetPrelightColorFunc func, gpointer func_data)
month_item_prepare_prelight (GnomeMonthItem *mitem, GetColorFunc 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");
g_return_if_fail (mitem != NULL);
g_return_if_fail (GNOME_IS_MONTH_ITEM (mitem));
g_return_if_fail (func != NULL);
/* Set up the buffer for day background colors and attach it to the month item, if necessary */
/* Store the function in the object data */
if (!day_pixels) {
/* Create the buffer and attach it */
gtk_object_set_data (GTK_OBJECT (mitem), "prelight_color_func", func);
gtk_object_set_data (GTK_OBJECT (mitem), "prelight_color_data", func_data);
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 */
/* Connect the appropriate signals to perform prelighting */
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);
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);
}
}
char *
default_prelight_func (gpointer data)
default_color_func (ColorProp propnum, gpointer data)
{
return color_spec_from_prop (COLOR_PROP_PRELIGHT_DAY_BG);
return color_spec_from_prop (propnum);
}

View File

@ -18,28 +18,34 @@
#define CURRENT_DAY_FONT "-adobe-helvetica-bold-r-normal--12-*-72-72-p-*-iso8859-1"
/* Functions of this type are used by the marking functions to fetch color specifications. Such
* a function must return a color spec based on the property passed to it.
*/
typedef char * (* GetColorFunc) (ColorProp propnum, gpointer data);
/* Sets the user-configured colors and font for a month item. It also tags the days as unmarked. */
void colorify_month_item (GnomeMonthItem *month, GetColorFunc func, gpointer func_data);
/* 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.
*/
void mark_month_item (GnomeMonthItem *mitem, Calendar *cal);
/* Marks a day specified by index, not by day number */
void mark_month_item_index (GnomeMonthItem *mitem, int index, GetColorFunc func, gpointer func_data);
/* 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.
*/
/* Prepares a monthly calendar item to prelight when the mouse goes over the days. */
typedef char * (* GetPrelightColorFunc) (gpointer data);
void month_item_prepare_prelight (GnomeMonthItem *mitem, GetPrelightColorFunc func, gpointer func_data);
void month_item_prepare_prelight (GnomeMonthItem *mitem, GetColorFunc 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);
char *default_color_func (ColorProp prop_num, gpointer data);
#endif

View File

@ -345,11 +345,11 @@ color_spec_from_picker (int num)
return build_color_spec (r, g, b);
}
/* Callback used to query prelight color information for the properties box */
/* Callback used to query color information for the properties box */
static char *
fetch_prelight_spec (gpointer data)
fetch_color_spec (ColorProp propnum, gpointer data)
{
return color_spec_from_picker (COLOR_PROP_PRELIGHT_DAY_BG);
return color_spec_from_picker (propnum);
}
/* Marks fake event days in the month item sample */
@ -357,17 +357,14 @@ 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 first_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);
}
first_day_index = gnome_month_item_day2index (GNOME_MONTH_ITEM (month_item), 1);
for (i = 0; i < (sizeof (day_nums) / sizeof (day_nums[0])); i++)
mark_month_item_index (GNOME_MONTH_ITEM (month_item), first_day_index + day_nums[i] - 1,
fetch_color_spec, NULL);
}
/* Switches the month item to the current date and highlights the current day's number */
@ -399,40 +396,24 @@ set_current_day (void)
NULL);
}
/* This is the version of a color spec query function that is appropriate for the preferences dialog */
static char *
prop_color_func (ColorProp propnum, gpointer data)
{
return color_spec_from_picker (propnum);
}
/* Sets the colors of the month item to the current prerences */
static void
reconfigure_month (void)
{
/* We have to do this in two calls to gnome_canvas_item_set(), as color_spec_from_picker()
* returns a pointer to a static string -- and we need two values.
*/
gnome_canvas_item_set (month_item,
"heading_color", color_spec_from_picker (COLOR_PROP_HEADING_COLOR),
NULL);
gnome_canvas_item_set (month_item,
"outline_color", color_spec_from_picker (COLOR_PROP_OUTLINE_COLOR),
NULL);
gnome_canvas_item_set (month_item,
"day_box_color", color_spec_from_picker (COLOR_PROP_EMPTY_DAY_BG),
NULL);
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);
colorify_month_item (GNOME_MONTH_ITEM (month_item), prop_color_func, NULL);
fake_mark_days ();
set_current_day ();
/* Reset prelighting information */
month_item_prepare_prelight (GNOME_MONTH_ITEM (month_item), fetch_prelight_spec, NULL);
month_item_prepare_prelight (GNOME_MONTH_ITEM (month_item), fetch_color_spec, NULL);
}
/* Callback used when a color is changed */
@ -560,7 +541,7 @@ parse_color_spec (char *spec, int *r, int *g, int *b)
}
char *
color_spec_from_prop (int propnum)
color_spec_from_prop (ColorProp propnum)
{
return build_color_spec (color_props[propnum].r, color_props[propnum].g, color_props[propnum].b);
}

View File

@ -10,6 +10,9 @@
#include "main.h"
#define QUICK_VIEW_FONT "-adobe-helvetica-medium-r-normal--10-*-*-*-p-*-*-*"
static void quick_view_class_init (QuickViewClass *class);
static void quick_view_init (QuickView *qv);
@ -63,7 +66,7 @@ button_release (GtkWidget *widget, GdkEventButton *event, gpointer data)
return FALSE;
gdk_pointer_ungrab (event->time);
gtk_grab_remove (GTK_WIDGET (qv));
gtk_grab_remove (GTK_WIDGET (qv->canvas));
gtk_widget_hide (GTK_WIDGET (qv));
gtk_main_quit (); /* End modality */
@ -72,15 +75,18 @@ button_release (GtkWidget *widget, GdkEventButton *event, gpointer data)
/* Creates the items corresponding to a single calendar object. Takes in the y position of the
* items to create and returns the y position of the next item to create.
* items to create and returns the y position of the next item to create. Also takes in the current
* maximum width for items and returns the new maximum width.
*/
double
create_items_for_event (QuickView *qv, CalendarObject *co, double y)
void
create_items_for_event (QuickView *qv, CalendarObject *co, double *y, double *max_width)
{
GnomeCanvas *canvas;
GnomeCanvasItem *item;
char start[100], end[100];
struct tm start_tm, end_tm;
char *str;
GtkArg args[2];
/* FIXME: make this nice */
@ -99,17 +105,27 @@ create_items_for_event (QuickView *qv, CalendarObject *co, double y)
str = g_copy_strings (start, " - ", end, " ", co->ico->summary, NULL);
gnome_canvas_item_new (gnome_canvas_root (canvas),
gnome_canvas_text_get_type (),
"x", 0.0,
"y", y,
"anchor", GTK_ANCHOR_NW,
"text", str,
NULL);
item = gnome_canvas_item_new (gnome_canvas_root (canvas),
gnome_canvas_text_get_type (),
"x", 0.0,
"y", *y,
"anchor", GTK_ANCHOR_NW,
"text", str,
"font", QUICK_VIEW_FONT,
NULL);
g_free (str);
return (y + 16); /* FIXME */
/* Measure the text and return the proper size values */
args[0].name = "text_width";
args[1].name = "text_height";
gtk_object_getv (GTK_OBJECT (item), 2, args);
if (GTK_VALUE_DOUBLE (args[0]) > *max_width)
*max_width = GTK_VALUE_DOUBLE (args[0]);
*y += GTK_VALUE_DOUBLE (args[1]);
}
/* Creates the canvas items corresponding to the events in the list */
@ -117,43 +133,56 @@ static void
setup_event_list (QuickView *qv, GList *event_list)
{
CalendarObject *co;
double y;
GnomeCanvasItem *item;
GtkArg args[2];
double y, max_width;
/* If there are no events, then just put a simple label */
if (!event_list) {
gnome_canvas_item_new (gnome_canvas_root (GNOME_CANVAS (qv->canvas)),
gnome_canvas_text_get_type (),
"x", 0.0,
"y", 0.0,
"anchor", GTK_ANCHOR_NW,
"text", _("No appointments scheduled for this day"),
NULL);
return;
}
item = gnome_canvas_item_new (gnome_canvas_root (GNOME_CANVAS (qv->canvas)),
gnome_canvas_text_get_type (),
"x", 0.0,
"y", 0.0,
"anchor", GTK_ANCHOR_NW,
"text", _("No appointments for this day"),
"font", QUICK_VIEW_FONT,
NULL);
/* Create the items for all the events in the list */
/* Measure the text and set the proper sizes */
y = 0.0;
args[0].name = "text_width";
args[1].name = "text_height";
gtk_object_getv (GTK_OBJECT (item), 2, args);
for (; event_list; event_list = event_list->next) {
co = event_list->data;
y = create_items_for_event (qv, co, y);
y = GTK_VALUE_DOUBLE (args[1]);
max_width = GTK_VALUE_DOUBLE (args[0]);
} else {
/* Create the items for all the events in the list */
y = 0.0;
max_width = 0.0;
for (; event_list; event_list = event_list->next) {
co = event_list->data;
create_items_for_event (qv, co, &y, &max_width);
}
}
/* Set the scrolling region to fit all the items */
gnome_canvas_set_scroll_region (GNOME_CANVAS (qv->canvas),
0.0, 0.0,
300.0, y); /* FIXME: figure out reasonable sizes */
max_width, y);
gnome_canvas_set_size (GNOME_CANVAS (qv->canvas), 300, y);
gnome_canvas_set_size (GNOME_CANVAS (qv->canvas), max_width, y);
}
GtkWidget *
quick_view_new (GnomeCalendar *calendar, char *title, GList *event_list)
{
QuickView *qv;
GtkWidget *vbox;
GtkWidget *w;
g_return_val_if_fail (calendar != NULL, NULL);
@ -164,9 +193,22 @@ quick_view_new (GnomeCalendar *calendar, char *title, GList *event_list)
/* Create base widgets for the popup window */
w = gtk_frame_new (title);
w = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (w), GTK_SHADOW_OUT);
gtk_container_add (GTK_CONTAINER (qv), w);
gtk_widget_show (w);
vbox = gtk_vbox_new (FALSE, 0);
gtk_container_add (GTK_CONTAINER (w), vbox);
w = gtk_label_new (title);
gtk_box_pack_start (GTK_BOX (vbox), w, FALSE, FALSE, 0);
w = gtk_hseparator_new ();
gtk_box_pack_start (GTK_BOX (vbox), w, FALSE, FALSE, 0);
w = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
gtk_container_border_width (GTK_CONTAINER (w), GNOME_PAD_SMALL);
gtk_box_pack_start (GTK_BOX (vbox), w, TRUE, TRUE, 0);
gtk_widget_push_visual (gdk_imlib_get_visual ());
gtk_widget_push_colormap (gdk_imlib_get_colormap ());
@ -181,7 +223,6 @@ quick_view_new (GnomeCalendar *calendar, char *title, GList *event_list)
qv);
gtk_container_add (GTK_CONTAINER (w), qv->canvas);
gtk_widget_show (qv->canvas);
/* Set up the event list */
@ -193,21 +234,27 @@ quick_view_new (GnomeCalendar *calendar, char *title, GList *event_list)
void
quick_view_do_popup (QuickView *qv, GdkEventButton *event)
{
GdkCursor *cursor;
g_return_if_fail (qv != NULL);
g_return_if_fail (IS_QUICK_VIEW (qv));
g_return_if_fail (event != NULL);
/* Pop up the window */
gtk_widget_show (GTK_WIDGET (qv));
gtk_grab_add (GTK_WIDGET (qv));
gtk_widget_show_all (GTK_WIDGET (qv));
gtk_grab_add (qv->canvas);
gdk_pointer_grab (GTK_WIDGET (qv)->window,
TRUE,
GDK_BUTTON_RELEASE_MASK,
NULL,
NULL,
event->time);
cursor = gdk_cursor_new (GDK_ARROW);
while (gdk_pointer_grab (GTK_LAYOUT (qv->canvas)->bin_window,
TRUE,
GDK_BUTTON_RELEASE_MASK,
NULL,
cursor,
event->time) != 0); /* wait for success */
gdk_cursor_destroy (cursor);
qv->button = event->button;

View File

@ -313,13 +313,15 @@ do_quick_view_popup (YearView *yv, GdkEventButton *event, int year, int month, i
time_t day_start, day_end;
GList *list;
GtkWidget *qv;
char date_str[256];
day_start = time_from_day (year, month, day);
day_end = time_end_of_day (day_start);
list = calendar_get_events_in_range (yv->calendar->cal, day_start, day_end);
qv = quick_view_new (yv->calendar, "Put the date here", list);
strftime (date_str, sizeof (date_str), "%a %b %d %Y", localtime (&day_start));
qv = quick_view_new (yv->calendar, date_str, list);
quick_view_do_popup (QUICK_VIEW (qv), event);
@ -425,6 +427,10 @@ setup_month_item (YearView *yv, int n)
gtk_signal_connect (GTK_OBJECT (mitem), "event",
(GtkSignalFunc) month_event,
NULL);
/* Prepare for prelighting */
month_item_prepare_prelight (GNOME_MONTH_ITEM (mitem), default_color_func, NULL);
}
static void
@ -507,6 +513,7 @@ year_view_new (GnomeCalendar *calendar, time_t year)
yv = gtk_type_new (year_view_get_type ());
yv->calendar = calendar;
year_view_colors_changed (yv);
year_view_set (yv, year);
return GTK_WIDGET (yv);
}
@ -591,7 +598,10 @@ year_view_set (YearView *yv, time_t year)
/* Unmark and re-mark all the months */
year_view_colors_changed (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);
}
}
void
@ -618,9 +628,9 @@ year_view_colors_changed (YearView *yv)
g_return_if_fail (yv != NULL);
g_return_if_fail (IS_YEAR_VIEW (yv));
for (i = 0; i < 12; i++) {
unmark_month_item (GNOME_MONTH_ITEM (yv->mitems[i]));
colorify_month_item (GNOME_MONTH_ITEM (yv->mitems[i]), default_color_func, NULL);
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);
}
}