diff options
author | Bolian Yin <bolian.yin@sun.com> | 2003-09-22 11:19:00 +0800 |
---|---|---|
committer | Bolian Yin <byin@src.gnome.org> | 2003-09-22 11:19:00 +0800 |
commit | 88d4fd5eac6bf7bcfd845f548efabc9801199cd2 (patch) | |
tree | 315ccd29c815a961e66ac9db129f960d10339d1b /widgets/misc/e-calendar.c | |
parent | 939c8a4b8284418ad379cdbd990353b9941b551a (diff) | |
download | gsoc2013-evolution-88d4fd5eac6bf7bcfd845f548efabc9801199cd2.tar gsoc2013-evolution-88d4fd5eac6bf7bcfd845f548efabc9801199cd2.tar.gz gsoc2013-evolution-88d4fd5eac6bf7bcfd845f548efabc9801199cd2.tar.bz2 gsoc2013-evolution-88d4fd5eac6bf7bcfd845f548efabc9801199cd2.tar.lz gsoc2013-evolution-88d4fd5eac6bf7bcfd845f548efabc9801199cd2.tar.xz gsoc2013-evolution-88d4fd5eac6bf7bcfd845f548efabc9801199cd2.tar.zst gsoc2013-evolution-88d4fd5eac6bf7bcfd845f548efabc9801199cd2.zip |
Fixes #1245. ECalendar should be usable with the keyboard
2003-09-19 Bolian Yin <bolian.yin@sun.com>
Fixes #1245. ECalendar should be usable with the keyboard
*misc/e-calendar-item.c (e_calendar_item_focus): new func, focus handler.
(e_calendar_item_key_press_event): new func, key press event handler
(e_calendar_item_selection_add_days, e_calendar_item_stop_selecting): helpers.
(e_calendar_item_ensure_days_visible, e_calendar_item_set_selection_if_emission):
add the flag to control if we should emit e-calendar signals.
(e_calendar_item_class_init): register focus handler.
(e_calendar_item_event): add code for GDK_FOCUS_CHANGE and GDK_KEY_PRESS.
*misc/e-calendar.c (e_calendar_focus): new func, focus handler
(e_calendar_button_has_focus): new func, if prev/next button has focus.
(e_calendar_on_next_clicked, e_calendar_on_prev_clicked): click signal handler
for prev/next buttons.
(e_calendar_set_focusable): set if the e-calendar is focusable
*misc/e-dateedit.c (e_date_edit_show_date_popup, hide_date_popup): grab/ungrab gdk keyboard.
svn path=/trunk/; revision=22632
Diffstat (limited to 'widgets/misc/e-calendar.c')
-rw-r--r-- | widgets/misc/e-calendar.c | 125 |
1 files changed, 121 insertions, 4 deletions
diff --git a/widgets/misc/e-calendar.c b/widgets/misc/e-calendar.c index ec720e9047..b2eb17cf2e 100644 --- a/widgets/misc/e-calendar.c +++ b/widgets/misc/e-calendar.c @@ -3,6 +3,7 @@ /* * Author : * Damon Chaplin <damon@ximian.com> + * Bolian Yin <bolian.yin@sun.com> * * Copyright 2000, Ximian, Inc. * @@ -86,11 +87,16 @@ static gint e_calendar_drag_motion (GtkWidget *widget, static void e_calendar_drag_leave (GtkWidget *widget, GdkDragContext *context, guint time); +static gboolean e_calendar_button_has_focus (ECalendar *cal); +static gboolean e_calendar_focus (GtkWidget *widget, + GtkDirectionType direction); static void e_calendar_on_prev_pressed (ECalendar *cal); static void e_calendar_on_prev_released (ECalendar *cal); +static void e_calendar_on_prev_clicked (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_next_clicked (ECalendar *cal); static void e_calendar_start_auto_move (ECalendar *cal, gboolean moving_forward); @@ -124,6 +130,7 @@ e_calendar_class_init (ECalendarClass *class) widget_class->size_allocate = e_calendar_size_allocate; widget_class->drag_motion = e_calendar_drag_motion; widget_class->drag_leave = e_calendar_drag_leave; + widget_class->focus = e_calendar_focus; } @@ -134,8 +141,6 @@ e_calendar_init (ECalendar *cal) PangoFontDescription *small_font_desc; GtkWidget *button, *pixmap; - GTK_WIDGET_UNSET_FLAGS (cal, GTK_CAN_FOCUS); - /* Create the small font. */ small_font_desc = @@ -154,7 +159,6 @@ e_calendar_init (ECalendar *cal) /* Create the arrow buttons to move to the previous/next month. */ button = gtk_button_new (); - GTK_WIDGET_UNSET_FLAGS (button, GTK_CAN_FOCUS); gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE); gtk_widget_show (button); gtk_signal_connect_object (GTK_OBJECT (button), "pressed", @@ -163,6 +167,9 @@ e_calendar_init (ECalendar *cal) gtk_signal_connect_object (GTK_OBJECT (button), "released", G_CALLBACK (e_calendar_on_prev_released), GTK_OBJECT (cal)); + gtk_signal_connect_object (GTK_OBJECT (button), "clicked", + G_CALLBACK (e_calendar_on_prev_clicked), + GTK_OBJECT (cal)); pixmap = gtk_arrow_new (GTK_ARROW_LEFT, GTK_SHADOW_NONE); gtk_widget_show (pixmap); @@ -174,7 +181,6 @@ e_calendar_init (ECalendar *cal) NULL); button = gtk_button_new (); - GTK_WIDGET_UNSET_FLAGS (button, GTK_CAN_FOCUS); gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE); gtk_widget_show (button); gtk_signal_connect_object (GTK_OBJECT (button), "pressed", @@ -183,6 +189,9 @@ e_calendar_init (ECalendar *cal) gtk_signal_connect_object (GTK_OBJECT (button), "released", G_CALLBACK (e_calendar_on_next_released), GTK_OBJECT (cal)); + gtk_signal_connect_object (GTK_OBJECT (button), "clicked", + G_CALLBACK (e_calendar_on_next_clicked), + GTK_OBJECT (cal)); pixmap = gtk_arrow_new (GTK_ARROW_RIGHT, GTK_SHADOW_NONE); gtk_widget_show (pixmap); @@ -431,6 +440,12 @@ e_calendar_on_prev_pressed (ECalendar *cal) e_calendar_start_auto_move (cal, FALSE); } +static void +e_calendar_on_prev_clicked (ECalendar *cal) +{ + e_calendar_item_set_first_month (cal->calitem, cal->calitem->year, + cal->calitem->month - 1); +} static void e_calendar_on_next_pressed (ECalendar *cal) @@ -438,6 +453,12 @@ e_calendar_on_next_pressed (ECalendar *cal) e_calendar_start_auto_move (cal, TRUE); } +static void +e_calendar_on_next_clicked (ECalendar *cal) +{ + e_calendar_item_set_first_month (cal->calitem, cal->calitem->year, + cal->calitem->month + 1); +} static void e_calendar_start_auto_move (ECalendar *cal, @@ -549,3 +570,99 @@ e_calendar_drag_leave (GtkWidget *widget, #endif } +static gboolean +e_calendar_button_has_focus (ECalendar *cal) +{ + GtkWidget *prev_widget, *next_widget; + gboolean ret_val; + + g_return_val_if_fail (E_IS_CALENDAR (cal), FALSE); + + prev_widget = GNOME_CANVAS_WIDGET(cal->prev_item)->widget; + next_widget = GNOME_CANVAS_WIDGET(cal->next_item)->widget; + ret_val = GTK_WIDGET_HAS_FOCUS (prev_widget) || + GTK_WIDGET_HAS_FOCUS (next_widget); + return ret_val; +} + +static gboolean +e_calendar_focus (GtkWidget *widget, GtkDirectionType direction) +{ +#define E_CALENDAR_FOCUS_CHILDREN_NUM 3 + ECalendar *cal; + GnomeCanvas *canvas; + GnomeCanvasItem *children[E_CALENDAR_FOCUS_CHILDREN_NUM]; + gint focused_index = -1; + gint index; + + g_return_val_if_fail (widget != NULL, FALSE); + g_return_val_if_fail (E_IS_CALENDAR (widget), FALSE); + cal = E_CALENDAR (widget); + canvas = GNOME_CANVAS (widget); + + if (!GTK_WIDGET_CAN_FOCUS (widget)) + return FALSE; + + children[0] = GNOME_CANVAS_ITEM (cal->calitem); + children[1] = cal->prev_item; + children[2] = cal->next_item; + + /* get current focused item, if e-calendar has had focus */ + if (GTK_WIDGET_HAS_FOCUS (widget) || e_calendar_button_has_focus (cal)) + for (index = 0; canvas->focused_item && index < E_CALENDAR_FOCUS_CHILDREN_NUM; ++index) { + if (children[index] == canvas->focused_item) { + focused_index = index; + break; + } + } + + if (focused_index == -1) + if (direction == GTK_DIR_TAB_FORWARD) + focused_index = 0; + else + focused_index = E_CALENDAR_FOCUS_CHILDREN_NUM - 1; + else + if (direction == GTK_DIR_TAB_FORWARD) + ++focused_index; + else + --focused_index; + + if (focused_index < 0 || + focused_index >= E_CALENDAR_FOCUS_CHILDREN_NUM) + /* move out of e-calendar */ + return FALSE; + gnome_canvas_item_grab_focus (children[focused_index]); + if (GNOME_IS_CANVAS_WIDGET (children[focused_index])) { + GtkWidget *widget; + widget = GNOME_CANVAS_WIDGET (children[focused_index])->widget; + gtk_widget_grab_focus (widget); + } + return TRUE; +} + +void +e_calendar_set_focusable (ECalendar *cal, gboolean focusable) +{ + GtkWidget *prev_widget, *next_widget; + + g_return_if_fail (E_IS_CALENDAR (cal)); + + prev_widget = GNOME_CANVAS_WIDGET(cal->prev_item)->widget; + next_widget = GNOME_CANVAS_WIDGET(cal->next_item)->widget; + + if (focusable) { + GTK_WIDGET_SET_FLAGS (cal, GTK_CAN_FOCUS); + GTK_WIDGET_SET_FLAGS (prev_widget, GTK_CAN_FOCUS); + GTK_WIDGET_SET_FLAGS (next_widget, GTK_CAN_FOCUS); + } + else { + if (GTK_WIDGET_HAS_FOCUS (cal) || e_calendar_button_has_focus (cal)) { + GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (cal)); + if (toplevel) + gtk_widget_grab_focus (toplevel); + } + GTK_WIDGET_UNSET_FLAGS (cal, GTK_CAN_FOCUS); + GTK_WIDGET_UNSET_FLAGS (prev_widget, GTK_CAN_FOCUS); + GTK_WIDGET_UNSET_FLAGS (next_widget, GTK_CAN_FOCUS); + } +} |