From 10d0e730eccccf34fc53dc8c1d6145fca1f52f57 Mon Sep 17 00:00:00 2001 From: Jon Trowbridge Date: Tue, 6 Mar 2001 09:47:08 +0000 Subject: Added. This is part of a change of sematics that makes things much nicer 2001-03-06 Jon Trowbridge * gal/e-text/e-entry.c (e_entry_text_keypress): Added. This is part of a change of sematics that makes things much nicer for the user --- auto-activate the completion popup only on keypresses than also change the entry. (e_entry_proxy_changed): Record that the underlying EText has changed, and set up a timeout to clear the changed_since_keypress flag in a very short amount of time. (e_entry_init): Connect to the EText's "keypress" signal". (e_entry_destroy): If our completion_delay_tag timeout is still floating around out there when we are winding things down, remove it. * gal/e-text/e-text.c (e_text_class_init): Added keypress signal. (e_text_text_model_reposition): Removed some old cruft. (e_text_event): Emit our keypress signal after handling events of type GDK_KEY_PRESS. svn path=/trunk/; revision=8566 --- widgets/text/e-completion-test.c | 2 +- widgets/text/e-entry.c | 59 +++++++++++++++++++++++++++++++++------- widgets/text/e-text.c | 28 +++++++++---------- widgets/text/e-text.h | 7 +++-- 4 files changed, 68 insertions(+), 28 deletions(-) diff --git a/widgets/text/e-completion-test.c b/widgets/text/e-completion-test.c index f01389363a..626842cb51 100644 --- a/widgets/text/e-completion-test.c +++ b/widgets/text/e-completion-test.c @@ -175,7 +175,7 @@ main (int argc, gchar **argv) win = gtk_window_new (GTK_WINDOW_TOPLEVEL); entry = e_entry_new (); - e_entry_enable_completion_full (E_ENTRY (entry), complete, -1, NULL); + e_entry_enable_completion_full (E_ENTRY (entry), complete, 0, NULL); e_entry_set_editable (E_ENTRY (entry), TRUE); gtk_signal_connect (GTK_OBJECT (entry), diff --git a/widgets/text/e-entry.c b/widgets/text/e-entry.c index 8c0682e370..64255c435e 100644 --- a/widgets/text/e-entry.c +++ b/widgets/text/e-entry.c @@ -119,6 +119,9 @@ struct _EEntryPrivate { gint completion_delay; guint completion_delay_tag; gboolean ptr_grab; + gboolean changed_since_keypress; + guint changed_since_keypress_tag; + gint last_completion_pos; guint draw_borders : 1; }; @@ -197,16 +200,43 @@ canvas_focus_in_event (GtkWidget *widget, GdkEventFocus *focus, EEntry *entry) } static void -e_entry_proxy_changed (EText *text, EEntry *entry) +e_entry_text_keypress (EText *text, guint keyval, guint state, EEntry *entry) +{ + if (entry->priv->changed_since_keypress_tag) { + gtk_timeout_remove (entry->priv->changed_since_keypress_tag); + entry->priv->changed_since_keypress_tag = 0; + } + + if (entry->priv->changed_since_keypress + || (entry->priv->popup_is_visible && e_entry_get_position (entry) != entry->priv->last_completion_pos)) { + if (e_entry_is_empty (entry)) { + e_entry_cancel_delayed_completion (entry); + e_entry_show_popup (entry, FALSE); + } else if (entry->priv->popup_is_visible) { + e_entry_start_delayed_completion (entry, 1); + } else if (entry->priv->completion) + e_entry_start_delayed_completion (entry, entry->priv->completion_delay); + } + entry->priv->changed_since_keypress = FALSE; +} + +static gint +changed_since_keypress_timeout_fn (gpointer user_data) { - if (e_entry_is_empty (entry)) { - e_entry_cancel_delayed_completion (entry); - e_entry_show_popup (entry, FALSE); - } else if (entry->priv->popup_is_visible) - e_entry_start_delayed_completion (entry, 1); - else if (entry->priv->completion) - e_entry_start_delayed_completion (entry, entry->priv->completion_delay); + EEntry *entry = E_ENTRY (user_data); + entry->priv->changed_since_keypress = FALSE; + entry->priv->changed_since_keypress_tag = 0; + return FALSE; +} +static void +e_entry_proxy_changed (EText *text, EEntry *entry) +{ + if (entry->priv->changed_since_keypress_tag) + gtk_timeout_remove (entry->priv->changed_since_keypress_tag); + entry->priv->changed_since_keypress = TRUE; + entry->priv->changed_since_keypress_tag = gtk_timeout_add (20, changed_since_keypress_timeout_fn, entry); + gtk_signal_emit (GTK_OBJECT (entry), e_entry_signals [E_ENTRY_CHANGED]); } @@ -260,6 +290,11 @@ e_entry_init (GtkObject *object) "editable", TRUE, NULL)); + gtk_signal_connect (GTK_OBJECT (entry->priv->item), + "keypress", + GTK_SIGNAL_FUNC (e_entry_text_keypress), + entry); + entry->priv->justification = GTK_JUSTIFY_LEFT; gtk_table_attach (gtk_table, GTK_WIDGET (entry->priv->canvas), 0, 1, 0, 1, @@ -458,6 +493,8 @@ e_entry_show_popup (EEntry *entry, gboolean visible) entry->priv->ptr_grab = FALSE; + entry->priv->last_completion_pos = -1; + } @@ -485,7 +522,7 @@ e_entry_start_completion (EEntry *entry) e_completion_begin_search (entry->priv->completion, e_entry_get_text (entry), - e_entry_get_position (entry), + entry->priv->last_completion_pos = e_entry_get_position (entry), 0); /* No limit. Probably a bad idea. */ } @@ -695,7 +732,6 @@ e_entry_enable_completion_full (EEntry *entry, ECompletion *completion, gint del e_completion_view_connect_keys (E_COMPLETION_VIEW (entry->priv->completion_view), GTK_WIDGET (entry->priv->canvas)); } - /** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **/ static void @@ -1002,6 +1038,9 @@ e_entry_destroy (GtkObject *object) gtk_widget_destroy (entry->priv->completion_view_popup); g_free (entry->priv->pre_browse_text); + if (entry->priv->changed_since_keypress_tag) + gtk_timeout_remove (entry->priv->changed_since_keypress_tag); + if (entry->priv->ptr_grab) gdk_pointer_ungrab (GDK_CURRENT_TIME); diff --git a/widgets/text/e-text.c b/widgets/text/e-text.c index 2f2e968394..e6e11750eb 100644 --- a/widgets/text/e-text.c +++ b/widgets/text/e-text.c @@ -38,6 +38,7 @@ enum { E_TEXT_CHANGED, E_TEXT_ACTIVATE, + E_TEXT_KEYPRESS, E_TEXT_POPUP, E_TEXT_LAST_SIGNAL }; @@ -227,6 +228,14 @@ e_text_class_init (ETextClass *klass) gtk_marshal_NONE__NONE, GTK_TYPE_NONE, 0); + e_text_signals[E_TEXT_KEYPRESS] = + gtk_signal_new ("keypress", + GTK_RUN_LAST, + object_class->type, + GTK_SIGNAL_OFFSET (ETextClass, keypress), + gtk_marshal_NONE__INT_INT, + GTK_TYPE_NONE, 2, GTK_TYPE_UINT, GTK_TYPE_UINT); + e_text_signals[E_TEXT_POPUP] = gtk_signal_new ("popup", GTK_RUN_LAST, @@ -498,9 +507,6 @@ static void e_text_text_model_reposition (ETextModel *model, ETextModelReposFn fn, gpointer repos_data, gpointer user_data) { EText *text = E_TEXT (user_data); -#if 0 - gint org_start = text->selection_start, org_end = text->selection_end; -#endif gint model_len = e_text_model_get_text_length (model); text->selection_start = fn (text->selection_start, repos_data); @@ -516,17 +522,6 @@ e_text_text_model_reposition (ETextModel *model, ETextModelReposFn fn, gpointer text->selection_start = text->selection_end; text->selection_end = tmp; } - -#if 0 - if (org_start != text->selection_start || org_end != text->selection_end) { - /* - In general we shouldn't need to do anything to refresh the - canvas to redraw the (moved) selection, since "reposition" events - will only be generated in association with ETextModel-changing - activities. - */ - } -#endif } static void @@ -2961,6 +2956,10 @@ e_text_event (GnomeCanvasItem *item, GdkEvent *event) if (e_tep_event.key.string) g_free (e_tep_event.key.string); + if (event->type == GDK_KEY_PRESS) + gtk_signal_emit (GTK_OBJECT (text), e_text_signals[E_TEXT_KEYPRESS], + e_tep_event.key.keyval, e_tep_event.key.state); + return ret; } else @@ -3402,6 +3401,7 @@ e_text_command(ETextEventProcessor *tep, ETextEventProcessorCommand *command, gp if (text->timer) { g_timer_reset(text->timer); } + break; case E_TEP_SELECT: text->selection_start = e_text_model_validate_position (text->model, text->selection_start); /* paranoia */ diff --git a/widgets/text/e-text.h b/widgets/text/e-text.h index b42ea06663..eae84af102 100644 --- a/widgets/text/e-text.h +++ b/widgets/text/e-text.h @@ -217,9 +217,10 @@ struct _EText { struct _ETextClass { GnomeCanvasItemClass parent_class; - void (* changed) (EText *text); - void (* activate) (EText *text); - void (* popup) (EText *text, GdkEventButton *ev, gint pos); + void (* changed) (EText *text); + void (* activate) (EText *text); + void (* keypress) (EText *text, guint keyval, guint state); + void (* popup) (EText *text, GdkEventButton *ev, gint pos); }; -- cgit