diff options
author | Claudio Saavedra <csaavedra@igalia.com> | 2009-11-04 17:21:08 +0200 |
---|---|---|
committer | Claudio Saavedra <csaavedra@igalia.com> | 2009-11-16 09:53:02 +0200 |
commit | 68b6d1740c32eb18103c62544db55a2044628457 (patch) | |
tree | 35169d4bcaf8c4f383a46316b016e9996f75dc69 /hildon/hildon-live-search.c | |
parent | f12c43f0a623cfaa8db972f41c56bf44166099b0 (diff) |
Major clean-up of the HildonLiveSearch event handling
Based on work by Xavier Claessens <xavier.claessens@collabora.co.uk>
Diffstat (limited to 'hildon/hildon-live-search.c')
-rw-r--r-- | hildon/hildon-live-search.c | 389 |
1 files changed, 24 insertions, 365 deletions
diff --git a/hildon/hildon-live-search.c b/hildon/hildon-live-search.c index cec918a..3d29b6d 100644 --- a/hildon/hildon-live-search.c +++ b/hildon/hildon-live-search.c @@ -51,15 +51,7 @@ struct _HildonLiveSearchPrivate GtkWidget *event_widget; GHashTable *selection_map; - GtkIMContext *im_context; - gulong key_press_id; - gulong key_release_id; - gulong realize_id; - gulong unrealize_id; - gulong focus_in_event_id; - gulong focus_out_event_id; - gulong on_entry_changed_id; gulong destroy_id; gchar *prefix; @@ -79,12 +71,6 @@ enum PROP_TEXT_COLUMN }; -static void -hildon_live_search_real_show (GtkWidget *widget); - -static void -hildon_live_search_real_hide (GtkWidget *widget); - static gboolean visible_func (GtkTreeModel *model, GtkTreeIter *iter, @@ -92,15 +78,6 @@ visible_func (GtkTreeModel *model, /* Private implementation */ -static void -grab_treeview_focus (HildonLiveSearchPrivate *priv) -{ - if (GTK_WIDGET_HAS_FOCUS (GTK_WIDGET (priv->treeview))) - gtk_im_context_focus_in (priv->im_context); - - gtk_widget_grab_focus (GTK_WIDGET (priv->treeview)); -} - static guint hash_func (gconstpointer key) { @@ -262,12 +239,6 @@ selection_map_update_selection_from_map (HildonLiveSearchPrivate *priv) } } -/* - * Entry changed handler, called when the text entry is changed directly - * (if it is focused) or indirectly (via #on_key_press_event which - * captures key presses on the source widget). This will update the - * filter as required. - */ static void on_entry_changed (GtkEntry *entry, gpointer user_data) @@ -300,35 +271,14 @@ on_entry_changed (GtkEntry *entry, if (len < 1) { selection_map_destroy (priv); + gtk_widget_hide (GTK_WIDGET (user_data)); + } else { + gtk_widget_show (GTK_WIDGET (user_data)); } g_free (old_prefix); } -static void -adj_changed_cb (GtkAdjustment *adj, gpointer user_data) -{ - GtkTreePath *path = NULL; - GtkTreeView *view = user_data; - - gtk_tree_view_get_cursor (view, &path, NULL); - if (path) { - gtk_tree_view_scroll_to_cell (view, path, NULL, FALSE, 0.0f, 0.0f); - } - gtk_tree_path_free (path); - - g_object_disconnect (adj, "any_signal::changed", G_CALLBACK (adj_changed_cb), user_data, NULL); -} - -static void -scroll_to_focus (GtkTreeView *treeview) -{ - GtkAdjustment *adj; - - adj = gtk_tree_view_get_vadjustment (treeview); - g_signal_connect (G_OBJECT (adj), "changed", G_CALLBACK (adj_changed_cb), treeview); -} - /** * hildon_live_search_append_text: * @livesearch: An #HildonLiveSearch widget @@ -349,16 +299,6 @@ hildon_live_search_append_text (HildonLiveSearch *livesearch, priv = GET_PRIVATE (livesearch); - if (FALSE == GTK_WIDGET_MAPPED (livesearch)) { - gunichar c; - - c = g_utf8_get_char_validated (utf8, strlen (utf8)); - if (g_unichar_isgraph (c)) - gtk_widget_show (GTK_WIDGET (livesearch)); - else - return; - } - editable = GTK_EDITABLE (priv->entry); if (gtk_editable_get_selection_bounds (editable, @@ -394,30 +334,12 @@ hildon_live_search_get_text (HildonLiveSearch *livesearch) } /* - * IM commit handler. This receives the finalized utf8 input based on the - * previous source widget key event(s) and manipules the entry. This - * manipulation then calls #on_entry_changed. - */ -static void -on_im_context_commit (GtkIMContext *imcontext, - gchar *utf8, - gpointer user_data) -{ - HildonLiveSearch *live_search; - - g_return_if_fail (HILDON_IS_LIVE_SEARCH (user_data)); - - live_search = HILDON_LIVE_SEARCH (user_data); - hildon_live_search_append_text (live_search, utf8); -} - -/* * Key press handler. This takes key presses from the source widget and * manipulate the entry. This manipulation then calls #on_entry_changed. */ static gboolean on_key_press_event (GtkWidget *widget, - GdkEventKey *key, + GdkEventKey *event, HildonLiveSearch *live_search) { HildonLiveSearchPrivate *priv; @@ -425,153 +347,31 @@ on_key_press_event (GtkWidget *widget, g_return_val_if_fail (HILDON_IS_LIVE_SEARCH (live_search), FALSE); priv = GET_PRIVATE (live_search); - /* Don't intercept control- presses. - * Make an exception for ctr-space because it is the keyboard layout - * switch */ - if (key->state & GDK_CONTROL_MASK && - key->keyval != GDK_space) - return FALSE; - - /* Are we already visible, yet ? */ - if (GTK_WIDGET_MAPPED (live_search)) { - - /* Eat escape */ - if (key->keyval == GDK_Escape) - return TRUE; - - /* Don't eat returns */ - if (key->keyval == GDK_Return) - return FALSE; - if (key->keyval == GDK_BackSpace) { - GtkEditable *editable; - int start, end; - - editable = GTK_EDITABLE (priv->entry); - if (gtk_editable_get_selection_bounds (editable, - &start, - &end)) { - gtk_editable_delete_text (editable, start, end); - } else { - int pos; - pos = gtk_editable_get_position (editable); - if (pos < 1) - return TRUE; - gtk_editable_delete_text (editable, pos - 1, pos); - } - scroll_to_focus (priv->treeview); - - return TRUE; - } - /* Does the entry have focus? */ - if (GTK_WIDGET_HAS_FOCUS (priv->entry)) - return FALSE; - - /* Run the key through the IM context filter to get the value */ - return gtk_im_context_filter_keypress (priv->im_context, key); - } - - /* If the treeview is not visible, then don't bother */ - if (FALSE == GTK_WIDGET_MAPPED (priv->treeview)) - return FALSE; - - /* Return and space do not start searching. But ctr-space must still be - * sent to switch the keyboard layout */ - if (key->keyval == GDK_Return || - (key->keyval == GDK_space && - !(key->state & GDK_CONTROL_MASK))) - return FALSE; - - /* Run the key through the IM context filter to get the value */ - gtk_im_context_filter_keypress (priv->im_context, key); + /* If the entry is realized and has focus, it is enough to catch events. + * This assume that the toolbar is a child of the hook widget. */ + gtk_widget_realize (priv->entry); + gtk_widget_grab_focus (priv->entry); return FALSE; } -static gboolean -on_key_release_event (GtkWidget *widget, - GdkEventKey *key, - HildonLiveSearch *live_search) +static void +on_hide_cb (GtkWidget *widget, + HildonLiveSearch *live_search) { HildonLiveSearchPrivate *priv; - g_return_val_if_fail (HILDON_IS_LIVE_SEARCH (live_search), FALSE); priv = GET_PRIVATE (live_search); - /* Don't intercept control- presses */ - if (key->state & GDK_CONTROL_MASK) - return FALSE; - /* Are we already visible, yet ? */ - if (GTK_WIDGET_MAPPED (live_search)) { - if (key->keyval == GDK_Escape) { - gtk_widget_hide (GTK_WIDGET (live_search)); - return TRUE; - } - - if (key->keyval == GDK_BackSpace) { - const gchar *text = gtk_entry_get_text - (GTK_ENTRY (priv->entry)); - glong len = g_utf8_strlen (text, -1); - - if (len <= 0) { - gtk_widget_hide (GTK_WIDGET (live_search)); - return TRUE; - } - } - - /* Does the entry have focus? */ - if (GTK_WIDGET_HAS_FOCUS (priv->entry)) - return FALSE; - - /* Run the key through the IM context filter to get the - value */ - return gtk_im_context_filter_keypress (priv->im_context, key); + if (priv->prefix) { + g_free (priv->prefix); + priv->prefix = NULL; } - /* If the treeview is not visible, then don't bother */ - if (FALSE == GTK_WIDGET_MAPPED (priv->treeview)) - return FALSE; - - /* Don't pop up fkb or the preview bar */ - if (key->keyval == GDK_Return || - key->keyval == GDK_space) - return FALSE; - /* Run the key through the IM context filter to get the value */ - gtk_im_context_filter_keypress (priv->im_context, key); - - return FALSE; -} - -static void -on_unmap (GtkWidget *widget, - gpointer user_data) -{ - HildonLiveSearchPrivate *priv; - - priv = GET_PRIVATE (user_data); - - hildon_gtk_im_context_hide (priv->im_context); -} - -static void -on_hook_widget_realize (GtkWidget *hook_widget, - gpointer user_data) -{ - HildonLiveSearchPrivate *priv; - - priv = GET_PRIVATE (user_data); - gtk_im_context_set_client_window (priv->im_context, - hook_widget->window); -} - -static void -on_hook_widget_unrealize (GtkWidget *hook_widget, - gpointer user_data) -{ - HildonLiveSearchPrivate *priv; - - priv = GET_PRIVATE (user_data); - gtk_im_context_set_client_window (priv->im_context, - NULL); + /* Remove text from the entry without calling on_entry_changed */ + g_signal_handlers_block_by_func (priv->entry, on_entry_changed, live_search); + gtk_entry_set_text (GTK_ENTRY (priv->entry), ""); + g_signal_handlers_unblock_by_func (priv->entry, on_entry_changed, live_search); } /* GObject methods */ @@ -624,12 +424,6 @@ hildon_live_search_dispose (GObject *object) { HildonLiveSearchPrivate *priv = GET_PRIVATE (object); - if (priv->on_entry_changed_id) { - g_signal_handler_disconnect (priv->entry, - priv->on_entry_changed_id); - priv->on_entry_changed_id = 0; - } - hildon_live_search_widget_unhook (HILDON_LIVE_SEARCH (object)); if (priv->filter) { @@ -648,11 +442,6 @@ hildon_live_search_dispose (GObject *object) priv->visible_destroy = NULL; } - if (priv->im_context) { - g_object_unref (priv->im_context); - priv->im_context = NULL; - } - G_OBJECT_CLASS (hildon_live_search_parent_class)->dispose (object); } @@ -660,7 +449,6 @@ static void hildon_live_search_class_init (HildonLiveSearchClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); - GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); g_type_class_add_private (klass, sizeof (HildonLiveSearchPrivate)); @@ -668,9 +456,6 @@ hildon_live_search_class_init (HildonLiveSearchClass *klass) object_class->set_property = hildon_live_search_set_property; object_class->dispose = hildon_live_search_dispose; - widget_class->show = hildon_live_search_real_show; - widget_class->hide = hildon_live_search_real_hide; - g_object_class_install_property (object_class, PROP_FILTER, g_param_spec_object ("filter", @@ -772,28 +557,14 @@ hildon_live_search_init (HildonLiveSearch *self) gtk_toolbar_insert (GTK_TOOLBAR (self), close_button_container, -1); - priv->on_entry_changed_id = - g_signal_connect (G_OBJECT (priv->entry), "changed", - G_CALLBACK (on_entry_changed), self); - - priv->im_context = gtk_im_multicontext_new(); - - g_object_get (priv->im_context, - "hildon-input-mode", &imode, - NULL); - g_object_set (priv->im_context, - "hildon-input-mode", filter_input_mode (imode), - NULL); - - g_signal_connect (G_OBJECT (priv->im_context), "commit", - G_CALLBACK (on_im_context_commit), self); + g_signal_connect (G_OBJECT (close_button), "clicked", + G_CALLBACK (close_button_clicked_cb), self); - g_signal_connect (G_OBJECT (self), "unmap", - G_CALLBACK (on_unmap), self); + g_signal_connect (G_OBJECT (priv->entry), "changed", + G_CALLBACK (on_entry_changed), self); - g_signal_connect (G_OBJECT (close_button), "clicked", - G_CALLBACK (close_button_clicked_cb), - self); + g_signal_connect (self, "hide", + G_CALLBACK (on_hide_cb), self); gtk_widget_show_all (GTK_WIDGET (self)); gtk_widget_set_no_show_all (GTK_WIDGET (self), TRUE); @@ -814,42 +585,6 @@ hildon_live_search_new (void) return g_object_new (HILDON_TYPE_LIVE_SEARCH, NULL); } -static void -hildon_live_search_real_show (GtkWidget *widget) -{ - HildonLiveSearch *livesearch; - HildonLiveSearchPrivate *priv; - - livesearch = HILDON_LIVE_SEARCH (widget); - priv = GET_PRIVATE (livesearch); - - GTK_WIDGET_CLASS (hildon_live_search_parent_class)->show (widget); - - if (priv->treeview != NULL) - grab_treeview_focus (priv); -} - -static void -hildon_live_search_real_hide (GtkWidget *widget) -{ - HildonLiveSearch *livesearch; - HildonLiveSearchPrivate *priv; - - livesearch = HILDON_LIVE_SEARCH (widget); - priv = GET_PRIVATE (livesearch); - - gtk_editable_delete_text (GTK_EDITABLE (priv->entry), 0, -1); - - GTK_WIDGET_CLASS (hildon_live_search_parent_class)->hide (widget); - - if (priv->treeview != NULL) { - if (GTK_WIDGET_MAPPED (priv->treeview)) - scroll_to_focus (priv->treeview); - - grab_treeview_focus (priv); - } -} - static gboolean visible_func (GtkTreeModel *model, GtkTreeIter *iter, @@ -952,23 +687,6 @@ hildon_live_search_set_text_column (HildonLiveSearch *livesearch, gtk_tree_model_filter_refilter (priv->filter); } -static gboolean -on_hook_widget_focus_in_out_event (GtkWidget *widget, - GdkEventFocus *focus, - gpointer user_data) -{ - HildonLiveSearchPrivate *priv; - - priv = GET_PRIVATE (user_data); - - if (focus->in) { - gtk_im_context_focus_in (priv->im_context); - } else { - gtk_im_context_focus_out (priv->im_context); - } - return FALSE; -} - static void on_hook_widget_destroy (GtkObject *object, gpointer user_data) @@ -977,12 +695,6 @@ on_hook_widget_destroy (GtkObject *object, priv = GET_PRIVATE (user_data); - priv->key_press_id = 0; - priv->key_release_id = 0; - priv->realize_id = 0; - priv->unrealize_id = 0; - priv->focus_in_event_id = 0; - priv->focus_out_event_id = 0; priv->destroy_id = 0; } @@ -1010,40 +722,11 @@ hildon_live_search_widget_hook (HildonLiveSearch *livesearch, g_return_if_fail (priv->event_widget == NULL); priv->event_widget = hook_widget; - priv->treeview = kb_focus; - if (priv->treeview != NULL) - grab_treeview_focus (priv); priv->key_press_id = g_signal_connect (hook_widget, "key-press-event", G_CALLBACK (on_key_press_event), livesearch); - priv->key_release_id = - g_signal_connect (hook_widget, "key-release-event", - G_CALLBACK (on_key_release_event), livesearch); - if (GTK_WIDGET_REALIZED (hook_widget)) { - gtk_im_context_set_client_window (priv->im_context, - hook_widget->window); - priv->realize_id = 0; - } else { - priv->realize_id = - g_signal_connect (G_OBJECT (hook_widget), "realize", - G_CALLBACK (on_hook_widget_realize), - livesearch); - } - priv->unrealize_id = g_signal_connect (G_OBJECT (hook_widget), "unrealize", - G_CALLBACK (on_hook_widget_unrealize), - livesearch); - - priv->focus_in_event_id = - g_signal_connect (G_OBJECT (hook_widget), "focus-in-event", - G_CALLBACK (on_hook_widget_focus_in_out_event), - livesearch); - - priv->focus_out_event_id = - g_signal_connect (G_OBJECT (hook_widget), "focus-out-event", - G_CALLBACK (on_hook_widget_focus_in_out_event), - livesearch); priv->destroy_id = g_signal_connect (G_OBJECT (hook_widget), "destroy", @@ -1073,35 +756,11 @@ hildon_live_search_widget_unhook (HildonLiveSearch *livesearch) g_signal_handler_disconnect (priv->event_widget, priv->key_press_id); priv->key_press_id = 0; } - if (priv->key_release_id) { - g_signal_handler_disconnect (priv->event_widget, priv->key_release_id); - priv->key_release_id = 0; - } - if (priv->realize_id) { - g_signal_handler_disconnect (priv->event_widget, priv->realize_id); - priv->realize_id = 0; - } - if (priv->unrealize_id) { - g_signal_handler_disconnect (priv->event_widget, priv->unrealize_id); - priv->unrealize_id = 0; - } - if (priv->focus_in_event_id) { - g_signal_handler_disconnect (priv->event_widget, priv->focus_in_event_id); - priv->focus_in_event_id = 0; - } - if (priv->focus_out_event_id) { - g_signal_handler_disconnect (priv->event_widget, priv->focus_out_event_id); - priv->focus_out_event_id = 0; - } - if (priv->destroy_id) { g_signal_handler_disconnect (priv->event_widget, priv->destroy_id); priv->destroy_id = 0; } - gtk_im_context_focus_out (priv->im_context); - gtk_im_context_set_client_window (priv->im_context, NULL); - priv->event_widget = NULL; priv->treeview = NULL; } |