Updated.
2000-08-30 Damon Chaplin <damon@helixcode.com> * e-calendar-item.[hc]: * e-calendar.[hc]: Updated. svn path=/trunk/; revision=5120
This commit is contained in:
committed by
Damon Chaplin
parent
e9fd9ec066
commit
c03e143c6c
@ -1,3 +1,8 @@
|
||||
2000-08-30 Damon Chaplin <damon@helixcode.com>
|
||||
|
||||
* e-calendar-item.[hc]:
|
||||
* e-calendar.[hc]: Updated.
|
||||
|
||||
2000-08-10 Christopher James Lahey <clahey@helixcode.com>
|
||||
|
||||
* e-calendar-item.c, e-calendar.c: Fixed some warnings.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -34,18 +34,42 @@ extern "C" {
|
||||
* ECalendarItem - canvas item displaying a calendar.
|
||||
*/
|
||||
|
||||
#define E_CALENDAR_ITEM_YPAD1 1
|
||||
#define E_CALENDAR_ITEM_YPAD2 1
|
||||
#define E_CALENDAR_ITEM_YPAD_ABOVE_MONTH_NAME 1
|
||||
#define E_CALENDAR_ITEM_YPAD_BELOW_MONTH_NAME 1
|
||||
|
||||
/* Used to mark days as bold in e_calendar_item_mark_day(). */
|
||||
#define E_CALENDAR_ITEM_MARK_BOLD 1
|
||||
|
||||
|
||||
/* These index our colors array. */
|
||||
typedef enum
|
||||
{
|
||||
E_CALENDAR_COLOR_SELECTION,
|
||||
E_CALENDAR_COLOR_HIGHLIGHT,
|
||||
E_CALENDAR_COLOR_TODAY,
|
||||
E_CALENDAR_ITEM_COLOR_TODAY_BOX,
|
||||
E_CALENDAR_ITEM_COLOR_SELECTION_FG,
|
||||
E_CALENDAR_ITEM_COLOR_SELECTION_BG,
|
||||
E_CALENDAR_ITEM_COLOR_PREV_OR_NEXT_MONTH_FG,
|
||||
|
||||
E_CALENDAR_COLOR_LAST
|
||||
} ECalendarColors;
|
||||
E_CALENDAR_ITEM_COLOR_LAST
|
||||
} ECalendarItemColors;
|
||||
|
||||
typedef struct _ECalendarItem ECalendarItem;
|
||||
typedef struct _ECalendarItemClass ECalendarItemClass;
|
||||
|
||||
typedef void (*ECalendarItemStyleCallback) (ECalendarItem *calitem,
|
||||
gint year,
|
||||
gint month,
|
||||
gint day,
|
||||
gint day_style,
|
||||
gboolean today,
|
||||
gboolean prev_or_next_month,
|
||||
gboolean selected,
|
||||
gboolean has_focus,
|
||||
gboolean drop_target,
|
||||
GdkColor **bg_color,
|
||||
GdkColor **fg_color,
|
||||
GdkColor **box_color,
|
||||
gboolean *bold,
|
||||
gpointer data);
|
||||
|
||||
|
||||
#define E_CALENDAR_ITEM(obj) (GTK_CHECK_CAST((obj), \
|
||||
@ -55,23 +79,34 @@ typedef enum
|
||||
#define E_IS_CALENDAR_ITEM(o) (GTK_CHECK_TYPE((o), \
|
||||
e_calendar_item_get_type ()))
|
||||
|
||||
typedef struct {
|
||||
struct _ECalendarItem
|
||||
{
|
||||
GnomeCanvasItem canvas_item;
|
||||
|
||||
/* The year & month of the first calendar being displayed. */
|
||||
gint year;
|
||||
gint month; /* 0 to 11 */
|
||||
|
||||
/* Bounds of item. */
|
||||
gdouble x1, y1, x2, y2;
|
||||
/* Points to an array of styles, one char for each day. We use 32
|
||||
chars for each month, with n + 2 months, where n is the number of
|
||||
complete months shown (since we show some days before the first
|
||||
month and after the last month grayes out).
|
||||
A value of 0 is the default, and 1 is bold. */
|
||||
guint8 *styles;
|
||||
|
||||
/* The minimum & maximum number of rows & columns of months. */
|
||||
/*
|
||||
* Options.
|
||||
*/
|
||||
|
||||
/* The minimum & maximum number of rows & columns of months.
|
||||
If the maximum values are -1 then there is no maximum.
|
||||
The minimum valies default to 1. The maximum values to -1. */
|
||||
gint min_rows;
|
||||
gint min_cols;
|
||||
gint max_rows;
|
||||
gint max_cols;
|
||||
|
||||
/* The number of rows & columns of months. */
|
||||
/* The actual number of rows & columns of months. */
|
||||
gint rows;
|
||||
gint cols;
|
||||
|
||||
@ -84,6 +119,27 @@ typedef struct {
|
||||
/* Whether the cells expand to fill extra space. */
|
||||
gboolean expand;
|
||||
|
||||
/* The maximum number of days that can be selected. Defaults to 1. */
|
||||
gint max_days_selected;
|
||||
|
||||
/* The number of days selected before we switch to selecting whole
|
||||
weeks, or -1 if we never switch. Defaults to -1. */
|
||||
gint days_to_start_week_selection;
|
||||
|
||||
/* Whether the selection is rounded down to the nearest week when we
|
||||
move back/forward one month. Used for the week view. */
|
||||
gboolean round_selection_when_moving;
|
||||
|
||||
/* The space to leave at the bottom for the Today & None buttons. */
|
||||
gdouble buttons_space;
|
||||
|
||||
/*
|
||||
* Internal stuff.
|
||||
*/
|
||||
|
||||
/* Bounds of item. */
|
||||
gdouble x1, y1, x2, y2;
|
||||
|
||||
/* The minimum size of each month, based on the fonts used. */
|
||||
gint min_month_width;
|
||||
gint min_month_height;
|
||||
@ -103,16 +159,18 @@ typedef struct {
|
||||
gint cell_width;
|
||||
gint cell_height;
|
||||
|
||||
|
||||
/* The current selection. The month offsets are from 0, which is the
|
||||
top-left calendar month view. The day offsets are from 0, which is
|
||||
the top-left cell in the month view (which may be empty). */
|
||||
gint selection_start_month_offset;
|
||||
gint selection_start_day_offset;
|
||||
gint selection_end_month_offset;
|
||||
gint selection_end_day_offset;
|
||||
top-left calendar month view. Note that -1 is used for the last days
|
||||
from the previous month. The days are real month days. */
|
||||
gboolean selecting;
|
||||
gboolean selection_dragging_end;
|
||||
gboolean selection_from_full_week;
|
||||
gint selection_start_month_offset;
|
||||
gint selection_start_day;
|
||||
gint selection_end_month_offset;
|
||||
gint selection_end_day;
|
||||
gint selection_real_start_month_offset;
|
||||
gint selection_real_start_day;
|
||||
|
||||
/* The first character of each day of the week, e.g. 'MTWTFSS'. */
|
||||
gchar *days;
|
||||
@ -131,18 +189,87 @@ typedef struct {
|
||||
GdkFont *font, *old_font;
|
||||
GdkFont *week_number_font, *old_week_number_font;
|
||||
|
||||
/* Colors for drawing. */
|
||||
GdkColor colors[E_CALENDAR_COLOR_LAST];
|
||||
} ECalendarItem;
|
||||
ECalendarItemStyleCallback style_callback;
|
||||
gpointer style_callback_data;
|
||||
GtkDestroyNotify style_callback_destroy;
|
||||
|
||||
typedef struct {
|
||||
/* Colors for drawing. */
|
||||
GdkColor colors[E_CALENDAR_ITEM_COLOR_LAST];
|
||||
|
||||
/* Our idle handler for emitting signals. */
|
||||
gint signal_emission_idle_id;
|
||||
|
||||
/* A flag to indicate that the selection or date range has changed.
|
||||
When set the idle function will emit the signal and reset it to
|
||||
FALSE. This is so we don't emit it several times when args are set
|
||||
etc. */
|
||||
gboolean selection_changed;
|
||||
gboolean date_range_changed;
|
||||
};
|
||||
|
||||
struct _ECalendarItemClass
|
||||
{
|
||||
GnomeCanvasItemClass parent_class;
|
||||
|
||||
} ECalendarItemClass;
|
||||
void (* date_range_changed) (ECalendarItem *calitem);
|
||||
void (* selection_changed) (ECalendarItem *calitem);
|
||||
};
|
||||
|
||||
|
||||
GtkType e_calendar_item_get_type (void);
|
||||
GtkType e_calendar_item_get_type (void);
|
||||
|
||||
void e_calendar_item_get_first_month (ECalendarItem *calitem,
|
||||
gint *year,
|
||||
gint *month);
|
||||
void e_calendar_item_set_first_month (ECalendarItem *calitem,
|
||||
gint year,
|
||||
gint month);
|
||||
|
||||
/* Returns the range of dates actually shown. Months are 0 to 11.
|
||||
This also includes the last days of the previous month and the first days
|
||||
of the following month, which are normally shown in gray. */
|
||||
void e_calendar_item_get_date_range (ECalendarItem *calitem,
|
||||
gint *start_year,
|
||||
gint *start_month,
|
||||
gint *start_day,
|
||||
gint *end_year,
|
||||
gint *end_month,
|
||||
gint *end_day);
|
||||
|
||||
gboolean e_calendar_item_get_selection (ECalendarItem *calitem,
|
||||
GDate *start_date,
|
||||
GDate *end_date);
|
||||
void e_calendar_item_set_selection (ECalendarItem *calitem,
|
||||
GDate *start_date,
|
||||
GDate *end_date);
|
||||
|
||||
/* Marks a particular day. Passing E_CALENDAR_ITEM_MARK_BOLD as the day style
|
||||
will result in the day being shown as bold by default. The style callback
|
||||
could support more day_styles, or the style callback could determine the
|
||||
colors itself, without needing to mark days. */
|
||||
void e_calendar_item_clear_marks (ECalendarItem *calitem);
|
||||
void e_calendar_item_mark_day (ECalendarItem *calitem,
|
||||
gint year,
|
||||
gint month,
|
||||
gint day,
|
||||
guint8 day_style);
|
||||
|
||||
/* Mark a range of days. Any days outside the currently shown range are
|
||||
ignored. */
|
||||
void e_calendar_item_mark_days (ECalendarItem *calitem,
|
||||
gint start_year,
|
||||
gint start_month,
|
||||
gint start_day,
|
||||
gint end_year,
|
||||
gint end_month,
|
||||
gint end_day,
|
||||
guint8 day_style);
|
||||
|
||||
/* Sets the function to call to get the colors to use for a particular day. */
|
||||
void e_calendar_item_set_style_callback (ECalendarItem *calitem,
|
||||
ECalendarItemStyleCallback cb,
|
||||
gpointer data,
|
||||
GtkDestroyNotify destroy);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@ -39,8 +39,24 @@
|
||||
#define E_CALENDAR_SMALL_FONT_FALLBACK \
|
||||
"-adobe-helvetica-medium-r-normal-*-*-80-*-*-p-*-iso8859-*"
|
||||
|
||||
#define E_CALENDAR_BUTTON_X_PAD 2
|
||||
#define E_CALENDAR_BUTTON_Y_PAD 0
|
||||
/* The space between the arrow buttons and the edge of the widget. */
|
||||
#define E_CALENDAR_ARROW_BUTTON_X_PAD 2
|
||||
#define E_CALENDAR_ARROW_BUTTON_Y_PAD 0
|
||||
|
||||
/* Vertical padding. The padding above the button includes the space for the
|
||||
horizontal line. */
|
||||
#define E_CALENDAR_YPAD_ABOVE_LOWER_BUTTONS 4
|
||||
#define E_CALENDAR_YPAD_BELOW_LOWER_BUTTONS 3
|
||||
|
||||
/* Horizontal padding inside & between buttons. */
|
||||
#define E_CALENDAR_IXPAD_BUTTONS 4
|
||||
#define E_CALENDAR_XPAD_BUTTONS 8
|
||||
|
||||
/* The time between steps when the prev/next buttons is pressed, in 1/1000ths
|
||||
of a second, and the number of timeouts we skip before we start
|
||||
automatically moving back/forward. */
|
||||
#define E_CALENDAR_AUTO_MOVE_TIMEOUT 150
|
||||
#define E_CALENDAR_AUTO_MOVE_TIMEOUT_DELAY 2
|
||||
|
||||
static void e_calendar_class_init (ECalendarClass *class);
|
||||
static void e_calendar_init (ECalendar *cal);
|
||||
@ -52,28 +68,32 @@ static void e_calendar_size_request (GtkWidget *widget,
|
||||
GtkRequisition *requisition);
|
||||
static void e_calendar_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation *allocation);
|
||||
static gint e_calendar_expose (GtkWidget *widget,
|
||||
GdkEventExpose *event);
|
||||
static void e_calendar_draw (GtkWidget *widget,
|
||||
GdkRectangle *area);
|
||||
#if 0
|
||||
static gint e_calendar_button_press (GtkWidget *widget,
|
||||
GdkEventButton *event);
|
||||
static gint e_calendar_button_release (GtkWidget *widget,
|
||||
GdkEventButton *event);
|
||||
#endif
|
||||
static gint e_calendar_focus_in (GtkWidget *widget,
|
||||
GdkEventFocus *event);
|
||||
static gint e_calendar_focus_out (GtkWidget *widget,
|
||||
GdkEventFocus *event);
|
||||
static gint e_calendar_key_press (GtkWidget *widget,
|
||||
GdkEventKey *event);
|
||||
static gint e_calendar_drag_motion (GtkWidget *widget,
|
||||
GdkDragContext *context,
|
||||
gint x,
|
||||
gint y,
|
||||
guint time);
|
||||
static void e_calendar_drag_leave (GtkWidget *widget,
|
||||
GdkDragContext *context,
|
||||
guint time);
|
||||
|
||||
static void e_calendar_paint (ECalendar *cal,
|
||||
GdkRectangle *area);
|
||||
static void e_calendar_on_prev_pressed (ECalendar *cal);
|
||||
static void e_calendar_on_prev_released (ECalendar *cal);
|
||||
static void e_calendar_on_next_pressed (ECalendar *cal);
|
||||
static void e_calendar_on_next_released (ECalendar *cal);
|
||||
|
||||
static void e_calendar_on_prev_clicked (ECalendar *cal);
|
||||
static void e_calendar_on_next_clicked (ECalendar *cal);
|
||||
static void e_calendar_start_auto_move (ECalendar *cal,
|
||||
gboolean moving_forward);
|
||||
static gboolean e_calendar_auto_move_handler (gpointer data);
|
||||
static void e_calendar_stop_auto_move (ECalendar *cal);
|
||||
|
||||
static GnomeCanvasClass *parent_class;
|
||||
static GtkLayoutClass *grandparent_class;
|
||||
@ -100,15 +120,12 @@ e_calendar_class_init (ECalendarClass *class)
|
||||
widget_class->style_set = e_calendar_style_set;
|
||||
widget_class->size_request = e_calendar_size_request;
|
||||
widget_class->size_allocate = e_calendar_size_allocate;
|
||||
widget_class->expose_event = e_calendar_expose;
|
||||
widget_class->draw = e_calendar_draw;
|
||||
#if 0
|
||||
widget_class->button_press_event = e_calendar_button_press;
|
||||
widget_class->button_release_event = e_calendar_button_release;
|
||||
#endif
|
||||
widget_class->focus_in_event = e_calendar_focus_in;
|
||||
widget_class->focus_out_event = e_calendar_focus_out;
|
||||
widget_class->key_press_event = e_calendar_key_press;
|
||||
widget_class->drag_motion = e_calendar_drag_motion;
|
||||
widget_class->drag_leave = e_calendar_drag_leave;
|
||||
}
|
||||
|
||||
|
||||
@ -131,25 +148,39 @@ e_calendar_init (ECalendar *cal)
|
||||
cal->calitem = E_CALENDAR_ITEM (gnome_canvas_item_new (canvas_group,
|
||||
e_calendar_item_get_type (),
|
||||
"week_number_font", small_font,
|
||||
"week_start_day", 6,
|
||||
NULL));
|
||||
|
||||
#if 0
|
||||
"show_week_numbers", TRUE,
|
||||
"minimum_columns", 5,
|
||||
"maximum_columns", 5,
|
||||
#endif
|
||||
|
||||
if (small_font)
|
||||
gdk_font_unref (small_font);
|
||||
|
||||
|
||||
/* Create the 'Today' and 'None' buttons but don't show them. */
|
||||
cal->today_button = gtk_button_new_with_label (_("Today"));
|
||||
cal->today_button_item = gnome_canvas_item_new (canvas_group,
|
||||
gnome_canvas_widget_get_type (),
|
||||
"widget", cal->today_button,
|
||||
NULL);
|
||||
gnome_canvas_item_hide (cal->today_button_item);
|
||||
|
||||
|
||||
cal->none_button = gtk_button_new_with_label (_("None"));
|
||||
cal->none_button_item = gnome_canvas_item_new (canvas_group,
|
||||
gnome_canvas_widget_get_type (),
|
||||
"widget", cal->none_button,
|
||||
NULL);
|
||||
gnome_canvas_item_hide (cal->none_button_item);
|
||||
|
||||
|
||||
/* Create the arrow buttons to move to the previous/next month. */
|
||||
button = gtk_button_new ();
|
||||
/* FIXME: The buttons doesn't display properly if we do this. */
|
||||
/*gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);*/
|
||||
gtk_widget_show (button);
|
||||
gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
|
||||
GTK_SIGNAL_FUNC (e_calendar_on_prev_clicked),
|
||||
gtk_signal_connect_object (GTK_OBJECT (button), "pressed",
|
||||
GTK_SIGNAL_FUNC (e_calendar_on_prev_pressed),
|
||||
GTK_OBJECT (cal));
|
||||
gtk_signal_connect_object (GTK_OBJECT (button), "released",
|
||||
GTK_SIGNAL_FUNC (e_calendar_on_prev_released),
|
||||
GTK_OBJECT (cal));
|
||||
arrow = gtk_arrow_new (GTK_ARROW_LEFT, GTK_SHADOW_OUT);
|
||||
gtk_widget_show (arrow);
|
||||
@ -162,8 +193,11 @@ e_calendar_init (ECalendar *cal)
|
||||
button = gtk_button_new ();
|
||||
/*gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);*/
|
||||
gtk_widget_show (button);
|
||||
gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
|
||||
GTK_SIGNAL_FUNC (e_calendar_on_next_clicked),
|
||||
gtk_signal_connect_object (GTK_OBJECT (button), "pressed",
|
||||
GTK_SIGNAL_FUNC (e_calendar_on_next_pressed),
|
||||
GTK_OBJECT (cal));
|
||||
gtk_signal_connect_object (GTK_OBJECT (button), "released",
|
||||
GTK_SIGNAL_FUNC (e_calendar_on_next_released),
|
||||
GTK_OBJECT (cal));
|
||||
arrow = gtk_arrow_new (GTK_ARROW_RIGHT, GTK_SHADOW_OUT);
|
||||
gtk_widget_show (arrow);
|
||||
@ -177,6 +211,8 @@ e_calendar_init (ECalendar *cal)
|
||||
cal->min_cols = 1;
|
||||
cal->max_rows = -1;
|
||||
cal->max_cols = -1;
|
||||
|
||||
cal->timeout_id = 0;
|
||||
}
|
||||
|
||||
|
||||
@ -207,8 +243,10 @@ e_calendar_destroy (GtkObject *object)
|
||||
|
||||
cal = E_CALENDAR (object);
|
||||
|
||||
|
||||
|
||||
if (cal->timeout_id != 0) {
|
||||
gtk_timeout_remove (cal->timeout_id);
|
||||
cal->timeout_id = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -223,6 +261,10 @@ static void
|
||||
e_calendar_style_set (GtkWidget *widget,
|
||||
GtkStyle *previous_style)
|
||||
{
|
||||
|
||||
if (GTK_WIDGET_CLASS (parent_class)->style_set)
|
||||
(*GTK_WIDGET_CLASS (parent_class)->style_set) (widget,
|
||||
previous_style);
|
||||
}
|
||||
|
||||
|
||||
@ -232,8 +274,13 @@ e_calendar_size_request (GtkWidget *widget,
|
||||
{
|
||||
ECalendar *cal;
|
||||
GtkStyle *style;
|
||||
gdouble col_width, row_height;
|
||||
gint width, height;
|
||||
gint col_width, row_height, width, height;
|
||||
gboolean today_button_shown, none_button_shown;
|
||||
gint buttons_shown = 0, button_height, button_width, buttons_width;
|
||||
GtkRequisition today_button_requisition = { 0 };
|
||||
GtkRequisition none_button_requisition = { 0 };
|
||||
gint today_button_width = 0, today_button_height = 0;
|
||||
gint none_button_width = 0, none_button_height = 0;
|
||||
|
||||
cal = E_CALENDAR (widget);
|
||||
style = GTK_WIDGET (cal)->style;
|
||||
@ -246,7 +293,39 @@ e_calendar_size_request (GtkWidget *widget,
|
||||
height = row_height * cal->min_rows;
|
||||
width = col_width * cal->min_cols;
|
||||
|
||||
/* FIXME: Add on space for line & button if shown. */
|
||||
/* Add on space for line & button if shown. */
|
||||
today_button_shown = GTK_WIDGET_VISIBLE (cal->today_button);
|
||||
none_button_shown = GTK_WIDGET_VISIBLE (cal->none_button);
|
||||
|
||||
if (today_button_shown || none_button_shown) {
|
||||
/* Note that we use the buttons' requisition fields directly
|
||||
since we want the sizes without any usize modification. */
|
||||
if (today_button_shown) {
|
||||
gtk_widget_size_request (cal->today_button,
|
||||
&today_button_requisition);
|
||||
today_button_width = cal->today_button->requisition.width;
|
||||
today_button_height = cal->today_button->requisition.height;
|
||||
buttons_shown++;
|
||||
}
|
||||
if (none_button_shown) {
|
||||
gtk_widget_size_request (cal->none_button,
|
||||
&none_button_requisition);
|
||||
none_button_width = cal->none_button->requisition.width;
|
||||
none_button_height = cal->none_button->requisition.height;
|
||||
buttons_shown++;
|
||||
}
|
||||
|
||||
button_height = MAX (today_button_height, none_button_height);
|
||||
height += E_CALENDAR_YPAD_ABOVE_LOWER_BUTTONS + button_height
|
||||
+ E_CALENDAR_YPAD_BELOW_LOWER_BUTTONS;
|
||||
|
||||
button_width = MAX (today_button_width, none_button_width);
|
||||
button_width += E_CALENDAR_IXPAD_BUTTONS;
|
||||
buttons_width = buttons_shown * button_width
|
||||
+ (buttons_shown - 1) * E_CALENDAR_XPAD_BUTTONS;
|
||||
|
||||
width = MAX (width, buttons_width);
|
||||
}
|
||||
|
||||
requisition->width = width + style->klass->xthickness * 2;
|
||||
requisition->height = height + style->klass->ythickness * 2;
|
||||
@ -260,7 +339,16 @@ e_calendar_size_allocate (GtkWidget *widget,
|
||||
ECalendar *cal;
|
||||
GdkFont *font;
|
||||
gdouble old_x2, old_y2, new_x2, new_y2;
|
||||
gdouble xthickness, ythickness, button_size;
|
||||
gdouble buttons_x1, buttons_y1;
|
||||
gdouble button_width, button_height;
|
||||
gdouble buttons_width = 0, buttons_height = 0;
|
||||
gdouble xthickness, ythickness, arrow_button_size;
|
||||
gboolean today_button_shown, none_button_shown;
|
||||
gint buttons_shown = 0;
|
||||
GtkRequisition today_button_requisition = { 0 };
|
||||
GtkRequisition none_button_requisition = { 0 };
|
||||
gint today_button_width = 0, today_button_height = 0;
|
||||
gint none_button_width = 0, none_button_height = 0;
|
||||
|
||||
cal = E_CALENDAR (widget);
|
||||
font = widget->style->font;
|
||||
@ -278,50 +366,97 @@ e_calendar_size_allocate (GtkWidget *widget,
|
||||
gnome_canvas_set_scroll_region (GNOME_CANVAS (cal),
|
||||
0, 0, new_x2, new_y2);
|
||||
|
||||
/* FIXME: Take off space for line & buttons if shown. */
|
||||
/* Set the positions of the Today & None buttons if shown. */
|
||||
today_button_shown = GTK_WIDGET_VISIBLE (cal->today_button);
|
||||
none_button_shown = GTK_WIDGET_VISIBLE (cal->none_button);
|
||||
|
||||
if (today_button_shown || none_button_shown) {
|
||||
if (today_button_shown) {
|
||||
gtk_widget_size_request (cal->today_button,
|
||||
&today_button_requisition);
|
||||
today_button_width = cal->today_button->requisition.width;
|
||||
today_button_height = cal->today_button->requisition.height;
|
||||
buttons_shown++;
|
||||
}
|
||||
if (none_button_shown) {
|
||||
gtk_widget_size_request (cal->none_button,
|
||||
&none_button_requisition);
|
||||
none_button_width = cal->none_button->requisition.width;
|
||||
none_button_height = cal->none_button->requisition.height;
|
||||
buttons_shown++;
|
||||
}
|
||||
|
||||
button_height = MAX (today_button_height, none_button_height);
|
||||
buttons_height = E_CALENDAR_YPAD_ABOVE_LOWER_BUTTONS
|
||||
+ button_height + E_CALENDAR_YPAD_BELOW_LOWER_BUTTONS;
|
||||
|
||||
button_width = MAX (today_button_width, none_button_width);
|
||||
button_width += E_CALENDAR_IXPAD_BUTTONS;
|
||||
buttons_width = buttons_shown * button_width
|
||||
+ (buttons_shown - 1) * E_CALENDAR_XPAD_BUTTONS;
|
||||
|
||||
buttons_x1 = (new_x2 + 1 - buttons_width) / 2;
|
||||
buttons_x1 = MAX (0, buttons_x1);
|
||||
|
||||
buttons_y1 = new_y2 + 1 - E_CALENDAR_YPAD_BELOW_LOWER_BUTTONS
|
||||
- button_height - ythickness;
|
||||
buttons_y1 = MAX (0, buttons_y1);
|
||||
|
||||
gnome_canvas_item_set (cal->today_button_item,
|
||||
"x", buttons_x1,
|
||||
"y", buttons_y1,
|
||||
"width", (gdouble) button_width,
|
||||
"height", (gdouble) button_height,
|
||||
NULL);
|
||||
|
||||
if (today_button_shown)
|
||||
buttons_x1 += button_width + E_CALENDAR_XPAD_BUTTONS;
|
||||
|
||||
gnome_canvas_item_set (cal->none_button_item,
|
||||
"x", buttons_x1,
|
||||
"y", buttons_y1,
|
||||
"width", (gdouble) button_width,
|
||||
"height", (gdouble) button_height,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/* Take off space for line & buttons if shown. */
|
||||
gnome_canvas_item_set (GNOME_CANVAS_ITEM (cal->calitem),
|
||||
"x1", 0.0,
|
||||
"y1", 0.0,
|
||||
"x2", new_x2,
|
||||
"y2", new_y2,
|
||||
"buttons_space", buttons_height,
|
||||
NULL);
|
||||
|
||||
button_size = font->ascent + font->descent + E_CALENDAR_ITEM_YPAD1
|
||||
+ E_CALENDAR_ITEM_YPAD2 - E_CALENDAR_BUTTON_Y_PAD * 2;
|
||||
|
||||
/* Position the arrow buttons. */
|
||||
arrow_button_size = font->ascent + font->descent
|
||||
+ E_CALENDAR_ITEM_YPAD_ABOVE_MONTH_NAME
|
||||
+ E_CALENDAR_ITEM_YPAD_BELOW_MONTH_NAME
|
||||
- E_CALENDAR_ARROW_BUTTON_Y_PAD * 2;
|
||||
|
||||
gnome_canvas_item_set (cal->prev_item,
|
||||
"x", xthickness * 2 + E_CALENDAR_BUTTON_X_PAD,
|
||||
"y", ythickness * 2 + E_CALENDAR_BUTTON_Y_PAD,
|
||||
"width", button_size,
|
||||
"height", button_size,
|
||||
"x", xthickness * 2
|
||||
+ E_CALENDAR_ARROW_BUTTON_X_PAD,
|
||||
"y", ythickness * 2
|
||||
+ E_CALENDAR_ARROW_BUTTON_Y_PAD,
|
||||
"width", arrow_button_size,
|
||||
"height", arrow_button_size,
|
||||
NULL);
|
||||
|
||||
gnome_canvas_item_set (cal->next_item,
|
||||
"x", new_x2 + 1 - xthickness * 2
|
||||
- E_CALENDAR_BUTTON_X_PAD - button_size,
|
||||
"y", ythickness * 2 + E_CALENDAR_BUTTON_Y_PAD,
|
||||
"width", button_size,
|
||||
"height", button_size,
|
||||
- E_CALENDAR_ARROW_BUTTON_X_PAD
|
||||
- arrow_button_size,
|
||||
"y", ythickness * 2
|
||||
+ E_CALENDAR_ARROW_BUTTON_Y_PAD,
|
||||
"width", arrow_button_size,
|
||||
"height", arrow_button_size,
|
||||
NULL);
|
||||
}
|
||||
|
||||
|
||||
static gint
|
||||
e_calendar_expose (GtkWidget *widget,
|
||||
GdkEventExpose *event)
|
||||
{
|
||||
ECalendar *cal;
|
||||
|
||||
cal = E_CALENDAR (widget);
|
||||
|
||||
(*GTK_WIDGET_CLASS (parent_class)->expose_event) (widget, event);
|
||||
|
||||
e_calendar_paint (cal, &event->area);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
e_calendar_draw (GtkWidget *widget,
|
||||
GdkRectangle *area)
|
||||
@ -332,51 +467,13 @@ e_calendar_draw (GtkWidget *widget,
|
||||
|
||||
(*GTK_WIDGET_CLASS (parent_class)->draw) (widget, area);
|
||||
|
||||
/* GnomeCanvas bug workaround to draw the GnomeCanvasWidgets. */
|
||||
#if 0
|
||||
(*GTK_WIDGET_CLASS (grandparent_class)->draw) (widget, area);
|
||||
|
||||
e_calendar_paint (cal, area);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
e_calendar_paint (ECalendar *cal,
|
||||
GdkRectangle *area)
|
||||
{
|
||||
#if 0
|
||||
g_print ("In e_calendar_paint: %i,%i %ix%i\n", area->x, area->y,
|
||||
area->width, area->height);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* FIXME These aren't used? */
|
||||
|
||||
#if 0
|
||||
static gint
|
||||
e_calendar_button_press (GtkWidget *widget,
|
||||
GdkEventButton *event)
|
||||
{
|
||||
ECalendar *cal;
|
||||
|
||||
cal = E_CALENDAR (widget);
|
||||
|
||||
g_print ("In e_calendar_button_press\n");
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
static gint
|
||||
e_calendar_button_release (GtkWidget *widget,
|
||||
GdkEventButton *event)
|
||||
{
|
||||
g_print ("In e_calendar_button_release\n");
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static gint
|
||||
e_calendar_focus_in (GtkWidget *widget,
|
||||
GdkEventFocus *event)
|
||||
@ -439,48 +536,175 @@ e_calendar_set_maximum_size (ECalendar *cal,
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
e_calendar_on_prev_clicked (ECalendar *cal)
|
||||
/* Returns the border size on each side of the month displays. */
|
||||
void
|
||||
e_calendar_get_border_size (ECalendar *cal,
|
||||
gint *top,
|
||||
gint *bottom,
|
||||
gint *left,
|
||||
gint *right)
|
||||
{
|
||||
gint year, month;
|
||||
GtkStyle *style;
|
||||
|
||||
gtk_object_get (GTK_OBJECT (cal->calitem),
|
||||
"year", &year,
|
||||
"month", &month,
|
||||
NULL);
|
||||
g_return_if_fail (E_IS_CALENDAR (cal));
|
||||
|
||||
month--;
|
||||
if (month == -1) {
|
||||
year--;
|
||||
month = 11;
|
||||
style = GTK_WIDGET (cal)->style;
|
||||
|
||||
if (style) {
|
||||
*top = style->klass->ythickness;
|
||||
*bottom = style->klass->ythickness
|
||||
+ cal->calitem->buttons_space;
|
||||
*left = style->klass->xthickness;
|
||||
*right = style->klass->xthickness;
|
||||
} else {
|
||||
*top = *bottom = *left = *right = 0;
|
||||
}
|
||||
|
||||
gnome_canvas_item_set (GNOME_CANVAS_ITEM (cal->calitem),
|
||||
"year", year,
|
||||
"month", month,
|
||||
NULL);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
e_calendar_on_next_clicked (ECalendar *cal)
|
||||
e_calendar_on_prev_pressed (ECalendar *cal)
|
||||
{
|
||||
gint year, month;
|
||||
|
||||
gtk_object_get (GTK_OBJECT (cal->calitem),
|
||||
"year", &year,
|
||||
"month", &month,
|
||||
NULL);
|
||||
|
||||
month++;
|
||||
if (month == 12) {
|
||||
year++;
|
||||
month = 0;
|
||||
}
|
||||
|
||||
gnome_canvas_item_set (GNOME_CANVAS_ITEM (cal->calitem),
|
||||
"year", year,
|
||||
"month", month,
|
||||
NULL);
|
||||
e_calendar_start_auto_move (cal, FALSE);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
e_calendar_on_next_pressed (ECalendar *cal)
|
||||
{
|
||||
e_calendar_start_auto_move (cal, TRUE);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
e_calendar_start_auto_move (ECalendar *cal,
|
||||
gboolean moving_forward)
|
||||
{
|
||||
ECalendarItem *calitem;
|
||||
gint offset;
|
||||
|
||||
if (cal->timeout_id == 0) {
|
||||
cal->timeout_id = g_timeout_add (E_CALENDAR_AUTO_MOVE_TIMEOUT,
|
||||
e_calendar_auto_move_handler,
|
||||
cal);
|
||||
}
|
||||
cal->timeout_delay = E_CALENDAR_AUTO_MOVE_TIMEOUT_DELAY;
|
||||
cal->moving_forward = moving_forward;
|
||||
|
||||
calitem = cal->calitem;
|
||||
offset = cal->moving_forward ? 1 : -1;
|
||||
e_calendar_item_set_first_month (calitem, calitem->year,
|
||||
calitem->month + offset);
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
e_calendar_auto_move_handler (gpointer data)
|
||||
{
|
||||
ECalendar *cal;
|
||||
ECalendarItem *calitem;
|
||||
gint offset;
|
||||
|
||||
g_return_val_if_fail (E_IS_CALENDAR (data), FALSE);
|
||||
|
||||
cal = E_CALENDAR (data);
|
||||
calitem = cal->calitem;
|
||||
|
||||
GDK_THREADS_ENTER ();
|
||||
|
||||
if (cal->timeout_delay > 0) {
|
||||
cal->timeout_delay--;
|
||||
} else {
|
||||
offset = cal->moving_forward ? 1 : -1;
|
||||
e_calendar_item_set_first_month (calitem, calitem->year,
|
||||
calitem->month + offset);
|
||||
}
|
||||
|
||||
GDK_THREADS_LEAVE ();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
e_calendar_on_prev_released (ECalendar *cal)
|
||||
{
|
||||
e_calendar_stop_auto_move (cal);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
e_calendar_on_next_released (ECalendar *cal)
|
||||
{
|
||||
e_calendar_stop_auto_move (cal);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
e_calendar_stop_auto_move (ECalendar *cal)
|
||||
{
|
||||
if (cal->timeout_id != 0) {
|
||||
gtk_timeout_remove (cal->timeout_id);
|
||||
cal->timeout_id = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Set which, if any, of the buttons to show beneath the month displays.
|
||||
You must connect to the button's clicked signal and perform the
|
||||
required action yourself. */
|
||||
void
|
||||
e_calendar_set_buttons (ECalendar *cal,
|
||||
gboolean show_today_button,
|
||||
gboolean show_none_button)
|
||||
{
|
||||
if (show_today_button) {
|
||||
gtk_widget_show (cal->today_button);
|
||||
gnome_canvas_item_show (cal->today_button_item);
|
||||
} else {
|
||||
gtk_widget_hide (cal->today_button);
|
||||
gnome_canvas_item_hide (cal->today_button_item);
|
||||
}
|
||||
|
||||
if (show_none_button) {
|
||||
gtk_widget_show (cal->none_button);
|
||||
gnome_canvas_item_show (cal->none_button_item);
|
||||
} else {
|
||||
gtk_widget_hide (cal->none_button);
|
||||
gnome_canvas_item_hide (cal->none_button_item);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static gint
|
||||
e_calendar_drag_motion (GtkWidget *widget,
|
||||
GdkDragContext *context,
|
||||
gint x,
|
||||
gint y,
|
||||
guint time)
|
||||
{
|
||||
ECalendar *cal;
|
||||
|
||||
g_return_val_if_fail (E_IS_CALENDAR (widget), FALSE);
|
||||
|
||||
cal = E_CALENDAR (widget);
|
||||
|
||||
g_print ("In e_calendar_drag_motion\n");
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
e_calendar_drag_leave (GtkWidget *widget,
|
||||
GdkDragContext *context,
|
||||
guint time)
|
||||
{
|
||||
ECalendar *cal;
|
||||
|
||||
g_return_if_fail (E_IS_CALENDAR (widget));
|
||||
|
||||
cal = E_CALENDAR (widget);
|
||||
|
||||
g_print ("In e_calendar_drag_leave\n");
|
||||
}
|
||||
|
||||
|
||||
@ -54,13 +54,27 @@ struct _ECalendar
|
||||
|
||||
ECalendarItem *calitem;
|
||||
|
||||
GnomeCanvasItem *prev_item, *next_item;
|
||||
GtkWidget *today_button;
|
||||
GtkWidget *none_button;
|
||||
|
||||
GnomeCanvasItem *today_button_item;
|
||||
GnomeCanvasItem *none_button_item;
|
||||
|
||||
GnomeCanvasItem *prev_item;
|
||||
GnomeCanvasItem *next_item;
|
||||
|
||||
gint min_rows;
|
||||
gint min_cols;
|
||||
|
||||
gint max_rows;
|
||||
gint max_cols;
|
||||
|
||||
/* These are all used when the prev/next buttons are held down.
|
||||
moving_forward is TRUE if we are moving forward in time, i.e. the
|
||||
next button is pressed. */
|
||||
gint timeout_id;
|
||||
gint timeout_delay;
|
||||
gboolean moving_forward;
|
||||
};
|
||||
|
||||
struct _ECalendarClass
|
||||
@ -79,6 +93,19 @@ void e_calendar_set_maximum_size (ECalendar *cal,
|
||||
gint rows,
|
||||
gint cols);
|
||||
|
||||
/* Returns the border size on each side of the month displays. */
|
||||
void e_calendar_get_border_size (ECalendar *cal,
|
||||
gint *top,
|
||||
gint *bottom,
|
||||
gint *left,
|
||||
gint *right);
|
||||
|
||||
/* Set which, if any, of the buttons to show beneath the month displays.
|
||||
You must connect to the button's clicked signal and perform the
|
||||
required action yourself. */
|
||||
void e_calendar_set_buttons (ECalendar *cal,
|
||||
gboolean show_today_button,
|
||||
gboolean show_none_button);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@ -34,6 +34,34 @@
|
||||
|
||||
#include "e-calendar.h"
|
||||
|
||||
/* Drag and Drop stuff. */
|
||||
enum {
|
||||
TARGET_SHORTCUT
|
||||
};
|
||||
static GtkTargetEntry target_table[] = {
|
||||
{ "E-SHORTCUT", 0, TARGET_SHORTCUT }
|
||||
};
|
||||
static guint n_targets = sizeof(target_table) / sizeof(target_table[0]);
|
||||
|
||||
|
||||
static void on_date_range_changed (ECalendarItem *calitem);
|
||||
static void on_selection_changed (ECalendarItem *calitem);
|
||||
static void get_day_style (ECalendarItem *calitem,
|
||||
gint year,
|
||||
gint month,
|
||||
gint day,
|
||||
gint day_style,
|
||||
gboolean today,
|
||||
gboolean prev_or_next_month,
|
||||
gboolean selected,
|
||||
gboolean has_focus,
|
||||
gboolean drop_target,
|
||||
GdkColor **bg_color,
|
||||
GdkColor **fg_color,
|
||||
GdkColor **box_color,
|
||||
gboolean *bold,
|
||||
gpointer data);
|
||||
|
||||
static void
|
||||
delete_event_cb (GtkWidget *widget,
|
||||
GdkEventAny *event,
|
||||
@ -48,18 +76,39 @@ main (int argc, char **argv)
|
||||
GtkWidget *app;
|
||||
GtkWidget *cal;
|
||||
GtkWidget *vbox;
|
||||
ECalendarItem *calitem;
|
||||
|
||||
gnome_init ("test-calendar", "0.0", argc, argv);
|
||||
|
||||
app = gnome_app_new ("Test", "Test");
|
||||
gtk_window_set_default_size (GTK_WINDOW (app), 400, 400);
|
||||
gtk_window_set_policy (GTK_WINDOW (app), FALSE, TRUE, FALSE);
|
||||
gtk_container_set_border_width (GTK_CONTAINER (app), 8);
|
||||
|
||||
gtk_signal_connect (GTK_OBJECT (app), "delete_event",
|
||||
GTK_SIGNAL_FUNC (delete_event_cb), NULL);
|
||||
|
||||
cal = e_calendar_new ();
|
||||
#if 1
|
||||
e_calendar_set_buttons (E_CALENDAR (cal), TRUE, TRUE);
|
||||
#endif
|
||||
e_calendar_set_minimum_size (E_CALENDAR (cal), 1, 1);
|
||||
calitem = E_CALENDAR (cal)->calitem;
|
||||
gtk_widget_show (cal);
|
||||
e_calendar_item_set_style_callback (calitem, get_day_style,
|
||||
NULL, NULL);
|
||||
|
||||
gtk_signal_connect (GTK_OBJECT (calitem), "date_range_changed",
|
||||
GTK_SIGNAL_FUNC (on_date_range_changed), NULL);
|
||||
gtk_signal_connect (GTK_OBJECT (calitem), "selection_changed",
|
||||
GTK_SIGNAL_FUNC (on_selection_changed), NULL);
|
||||
|
||||
|
||||
gtk_drag_dest_set (cal,
|
||||
GTK_DEST_DEFAULT_ALL,
|
||||
target_table, n_targets,
|
||||
GDK_ACTION_COPY | GDK_ACTION_MOVE);
|
||||
|
||||
|
||||
vbox = gtk_vbox_new (FALSE, 0);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), cal, TRUE, TRUE, 0);
|
||||
@ -72,3 +121,100 @@ main (int argc, char **argv)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
on_date_range_changed (ECalendarItem *calitem)
|
||||
{
|
||||
gint start_year, start_month, start_day;
|
||||
gint end_year, end_month, end_day;
|
||||
|
||||
e_calendar_item_get_date_range (calitem,
|
||||
&start_year, &start_month, &start_day,
|
||||
&end_year, &end_month, &end_day);
|
||||
|
||||
g_print ("Date range changed (D/M/Y): %i/%i/%i - %i/%i/%i\n",
|
||||
start_day, start_month + 1, start_year,
|
||||
end_day, end_month + 1, end_year);
|
||||
|
||||
/* These days should appear bold. Remember month is 0 to 11. */
|
||||
e_calendar_item_mark_day (calitem, 2000, 7, 26, /* 26th Aug 2000. */
|
||||
E_CALENDAR_ITEM_MARK_BOLD);
|
||||
e_calendar_item_mark_day (calitem, 2000, 8, 13, /* 13th Sep 2000. */
|
||||
E_CALENDAR_ITEM_MARK_BOLD);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
on_selection_changed (ECalendarItem *calitem)
|
||||
{
|
||||
GDate start_date, end_date;
|
||||
|
||||
e_calendar_item_get_selection (calitem, &start_date, &end_date);
|
||||
|
||||
g_print ("Selection changed (D/M/Y): %i/%i/%i - %i/%i/%i\n",
|
||||
g_date_day (&start_date),
|
||||
g_date_month (&start_date),
|
||||
g_date_year (&start_date),
|
||||
g_date_day (&end_date),
|
||||
g_date_month (&end_date),
|
||||
g_date_year (&end_date));
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
get_day_style (ECalendarItem *calitem,
|
||||
gint year,
|
||||
gint month,
|
||||
gint day,
|
||||
gint day_style,
|
||||
gboolean today,
|
||||
gboolean prev_or_next_month,
|
||||
gboolean selected,
|
||||
gboolean has_focus,
|
||||
gboolean drop_target,
|
||||
GdkColor **bg_color,
|
||||
GdkColor **fg_color,
|
||||
GdkColor **box_color,
|
||||
gboolean *bold,
|
||||
gpointer data)
|
||||
{
|
||||
*bg_color = NULL;
|
||||
*fg_color = NULL;
|
||||
*box_color = NULL;
|
||||
*bold = FALSE;
|
||||
|
||||
#if 1
|
||||
|
||||
if (day_style == 1)
|
||||
*bold = TRUE;
|
||||
|
||||
if (today)
|
||||
*box_color = &calitem->colors[E_CALENDAR_ITEM_COLOR_TODAY_BOX];
|
||||
|
||||
if (prev_or_next_month)
|
||||
*fg_color = &calitem->colors[E_CALENDAR_ITEM_COLOR_PREV_OR_NEXT_MONTH_FG];
|
||||
|
||||
if (selected) {
|
||||
*fg_color = &calitem->colors[E_CALENDAR_ITEM_COLOR_SELECTION_FG];
|
||||
*bg_color = &calitem->colors[E_CALENDAR_ITEM_COLOR_SELECTION_BG];
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
if (day_style == 1)
|
||||
*bold = TRUE;
|
||||
|
||||
if (today)
|
||||
*box_color = &calitem->colors[E_CALENDAR_ITEM_COLOR_PREV_OR_NEXT_MONTH_FG];
|
||||
|
||||
if (prev_or_next_month)
|
||||
*fg_color = &calitem->colors[E_CALENDAR_ITEM_COLOR_TODAY_BOX];
|
||||
|
||||
if (selected) {
|
||||
*fg_color = &calitem->colors[E_CALENDAR_ITEM_COLOR_SELECTION_FG];
|
||||
*bg_color = &calitem->colors[E_CALENDAR_ITEM_COLOR_PREV_OR_NEXT_MONTH_FG];
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user