diff options
-rw-r--r-- | calendar/ChangeLog | 14 | ||||
-rw-r--r-- | calendar/gui/weekday-picker.c | 122 |
2 files changed, 118 insertions, 18 deletions
diff --git a/calendar/ChangeLog b/calendar/ChangeLog index a943ae3d9a..e31c1fd223 100644 --- a/calendar/ChangeLog +++ b/calendar/ChangeLog @@ -1,3 +1,17 @@ +2003-12-10 Harry Lu <harry.lu@sun.com> + + Fix for bugzilla bug #51628. + + * gui/weekday-picker.c: (weekday_picker_class_init): setup focus + handler. + (day_clicked): new function to set day_mask when mouse clicked + or keyboard input of space/enter. + (handle_key_press_event): new function to handle key press event. + (day_event_cb): handle key press event too. + (weekday_picker_init): set widget can be focused. + (colorize_items): change the box's outline if it is focused. + (weekday_picker_focus): new function to handler focus event. + 2003-12-09 Andrew Wu <Yang.Wu@sun.com> * gui/e-week-view-main-item.c (e_week_view_main_item_class_init): init a11y. diff --git a/calendar/gui/weekday-picker.c b/calendar/gui/weekday-picker.c index 87438fd62d..3e49119528 100644 --- a/calendar/gui/weekday-picker.c +++ b/calendar/gui/weekday-picker.c @@ -24,6 +24,7 @@ #include <string.h> #include <gtk/gtksignal.h> +#include <gdk/gdkkeysyms.h> #include <libgnome/gnome-i18n.h> #include <libgnomecanvas/gnome-canvas-rect-ellipse.h> #include <libgnomecanvas/gnome-canvas-text.h> @@ -45,6 +46,9 @@ struct _WeekdayPickerPrivate { /* Day that defines the start of the week; 0 = Sunday, ..., 6 = Saturday */ int week_start_day; + /* Current keyboard focus day */ + int focus_day; + /* Metrics */ int font_ascent, font_descent; int max_letter_width; @@ -70,6 +74,8 @@ static void weekday_picker_realize (GtkWidget *widget); static void weekday_picker_size_request (GtkWidget *widget, GtkRequisition *requisition); static void weekday_picker_size_allocate (GtkWidget *widget, GtkAllocation *allocation); static void weekday_picker_style_set (GtkWidget *widget, GtkStyle *previous_style); +static gboolean weekday_picker_focus (GtkWidget *widget, GtkDirectionType direction); +static void colorize_items (WeekdayPicker *wp); static GnomeCanvasClass *parent_class; @@ -106,10 +112,64 @@ weekday_picker_class_init (WeekdayPickerClass *class) widget_class->size_request = weekday_picker_size_request; widget_class->size_allocate = weekday_picker_size_allocate; widget_class->style_set = weekday_picker_style_set; + widget_class->focus = weekday_picker_focus; class->changed = NULL; } +static void +day_clicked (WeekdayPicker *wp, int index) +{ + WeekdayPickerPrivate *priv = wp->priv; + guint8 day_mask; + + if (priv->blocked_day_mask & (0x1 << index)) + return; + + if (priv->day_mask & (0x1 << index)) + day_mask = priv->day_mask & ~(0x1 << index); + else + day_mask = priv->day_mask | (0x1 << index); + + weekday_picker_set_days (wp, day_mask); +} + +static gint +handle_key_press_event (WeekdayPicker *wp, GdkEvent *event) +{ + WeekdayPickerPrivate *priv = wp->priv; + guint keyval = event->key.keyval; + + if (priv->focus_day == -1) + priv->focus_day = priv->week_start_day; + + switch (keyval) { + case GDK_Up: + case GDK_Right: + priv->focus_day += 1; + break; + case GDK_Down: + case GDK_Left: + priv->focus_day -= 1; + break; + case GDK_space: + case GDK_Return: + day_clicked (wp, priv->focus_day); + return TRUE; + default: + return FALSE; + } + + if (priv->focus_day > 6) + priv->focus_day = 0; + if (priv->focus_day < 0) + priv->focus_day = 6; + + colorize_items (wp); + gnome_canvas_item_grab_focus (priv->boxes[priv->focus_day]); + return TRUE; +} + /* Event handler for the day items */ static gint day_event_cb (GnomeCanvasItem *item, GdkEvent *event, gpointer data) @@ -117,11 +177,13 @@ day_event_cb (GnomeCanvasItem *item, GdkEvent *event, gpointer data) WeekdayPicker *wp; WeekdayPickerPrivate *priv; int i; - guint8 day_mask; wp = WEEKDAY_PICKER (data); priv = wp->priv; + if (event->type == GDK_KEY_PRESS) + return handle_key_press_event(wp, event); + if (!(event->type == GDK_BUTTON_PRESS && event->button.button == 1)) return FALSE; @@ -133,22 +195,13 @@ day_event_cb (GnomeCanvasItem *item, GdkEvent *event, gpointer data) g_assert (i != 7); - /* Turn on that day */ - i += priv->week_start_day; if (i >= 7) i -= 7; - if (priv->blocked_day_mask & (0x1 << i)) - return TRUE; - - if (priv->day_mask & (0x1 << i)) - day_mask = priv->day_mask & ~(0x1 << i); - else - day_mask = priv->day_mask | (0x1 << i); - - weekday_picker_set_days (wp, day_mask); - + priv->focus_day = i; + gnome_canvas_item_grab_focus (priv->boxes[i]); + day_clicked (wp, i); return TRUE; } @@ -186,13 +239,12 @@ weekday_picker_init (WeekdayPicker *wp) { WeekdayPickerPrivate *priv; - GTK_WIDGET_UNSET_FLAGS (wp, GTK_CAN_FOCUS); - priv = g_new0 (WeekdayPickerPrivate, 1); wp->priv = priv; create_items (wp); + priv->focus_day = -1; } /* Finalize handler for the weekday picker */ @@ -219,7 +271,7 @@ static void colorize_items (WeekdayPicker *wp) { WeekdayPickerPrivate *priv; - GdkColor *outline; + GdkColor *outline, *focus_outline; GdkColor *fill, *sel_fill; GdkColor *text_fill, *sel_text_fill; int i; @@ -227,6 +279,7 @@ colorize_items (WeekdayPicker *wp) priv = wp->priv; outline = >K_WIDGET (wp)->style->fg[GTK_WIDGET_STATE (wp)]; + focus_outline = >K_WIDGET (wp)->style->bg[GTK_WIDGET_STATE (wp)]; fill = >K_WIDGET (wp)->style->base[GTK_WIDGET_STATE (wp)]; text_fill = >K_WIDGET (wp)->style->fg[GTK_WIDGET_STATE (wp)]; @@ -236,7 +289,7 @@ colorize_items (WeekdayPicker *wp) for (i = 0; i < 7; i++) { int day; - GdkColor *f, *t; + GdkColor *f, *t, *o; day = i + priv->week_start_day; if (day >= 7) @@ -250,9 +303,14 @@ colorize_items (WeekdayPicker *wp) t = text_fill; } + if (day == priv->focus_day) + o = focus_outline; + else + o = outline; + gnome_canvas_item_set (priv->boxes[i], "fill_color_gdk", f, - "outline_color_gdk", outline, + "outline_color_gdk", o, NULL); gnome_canvas_item_set (priv->labels[i], @@ -570,3 +628,31 @@ weekday_picker_get_week_start_day (WeekdayPicker *wp) priv = wp->priv; return priv->week_start_day; } + +/* focus handler for weekday picker */ +static gboolean +weekday_picker_focus (GtkWidget *widget, GtkDirectionType direction) +{ + WeekdayPicker *wp; + WeekdayPickerPrivate *priv; + + g_return_val_if_fail (widget != NULL, FALSE); + g_return_val_if_fail (IS_WEEKDAY_PICKER (widget), FALSE); + wp = WEEKDAY_PICKER (widget); + priv = wp->priv; + + if (!GTK_WIDGET_CAN_FOCUS (widget)) + return FALSE; + + if (GTK_WIDGET_HAS_FOCUS (widget)) { + priv->focus_day = -1; + colorize_items (wp); + return FALSE; + } + + priv->focus_day = priv->week_start_day; + gnome_canvas_item_grab_focus (priv->boxes[priv->focus_day]); + colorize_items (wp); + + return TRUE; +} |