Boost version number to 0.5.99.3.

2001-03-01  Jon Trowbridge  <trow@ximian.com>

        * configure.in: Boost version number to 0.5.99.3.

        * gal/e-text/e-entry.c (e_entry_show_popup): Grab pointer when the
        popup is visible, and then hide the popup if any button press
        events occur outside of the popup.  This lets up avoid most of the
        worst "floating popup" cases that would occur if windows are
        moved, desktops changed, etc. with the mouse.  (Doing things like
        changing desktop w/ keybindings can still cause a "floating
        popup", but that is also true of Gtk's own combo box.)  Change
        popup positioning to slightly offset it from the entry, rather
        than just plopping it down directly below.
        (button_press_cb): Determine if a button press occured outside of
        the popup when the pointer was grabbed, and unbrowse accordingly.

        * gal/e-text/e-completion-view.c
        (e_completion_view_key_press_handler): Improve keystroke handling.
        Allow Tabs to pass through (after hiding the pop-up) in order to
        allow focus change requests to work properly.
        (e_completion_view_construct): Disable horizontal scrollbars.

        * gal/e-text/e-completion-test.c (main): Reworked to use signals
        instead of explicit callbacks.

        * gal/e-text/e-completion.h:
        * gal/e-text/e-completion.c: Fix the awkward mix of signals and
        explicitly-specified callbacks by taking out the explicit
        callbacks.  This approach is more gtk-ish, after all.

svn path=/trunk/; revision=8458
This commit is contained in:
Jon Trowbridge
2001-03-01 20:59:42 +00:00
committed by Jon Trowbridge
parent 6f85f0645a
commit fae87e8d3d
5 changed files with 91 additions and 99 deletions

View File

@ -134,7 +134,7 @@ begin_dict_search (ECompletion *complete, const gchar *txt, gint pos, gint limit
}
static void
end_dict_search (ECompletion *complete, gboolean finished, gpointer foo)
end_dict_search (ECompletion *complete, gpointer user_data)
{
if (dict_tag != 0) {
gtk_timeout_remove (dict_tag);
@ -153,11 +153,23 @@ main (int argc, gchar **argv)
read_dict ();
complete = e_completion_new (begin_dict_search, end_dict_search, NULL);
complete = e_completion_new ();
gtk_signal_connect (GTK_OBJECT (complete),
"begin_completion",
GTK_SIGNAL_FUNC (begin_dict_search),
NULL);
gtk_signal_connect (GTK_OBJECT (complete),
"end_completion",
GTK_SIGNAL_FUNC (end_dict_search),
NULL);
gtk_signal_connect (GTK_OBJECT (complete),
"cancel_completion",
GTK_SIGNAL_FUNC (end_dict_search),
NULL);
win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
entry = e_entry_new ();
e_entry_enable_completion_full (E_ENTRY (entry), complete, 100, NULL);
e_entry_enable_completion_full (E_ENTRY (entry), complete, -1, NULL);
e_entry_set_editable (E_ENTRY (entry), TRUE);
gtk_container_add (GTK_CONTAINER (win), entry);

View File

@ -305,6 +305,7 @@ e_completion_view_key_press_handler (GtkWidget *w, GdkEventKey *key_event, gpoin
{
ECompletionView *cv = E_COMPLETION_VIEW (user_data);
gint dir = 0;
gboolean key_handled = TRUE;
/* Start up a completion.*/
if (cv->complete_key && key_event->keyval == cv->complete_key && !cv->editable) {
@ -332,13 +333,18 @@ e_completion_view_key_press_handler (GtkWidget *w, GdkEventKey *key_event, gpoin
case GDK_KP_Up:
dir = -1;
break;
case GDK_Tab:
/* Unbrowse, unhandled. */
cv->selection = -1;
dir = 0;
key_handled = FALSE;
break;
case GDK_Return:
case GDK_KP_Enter:
case GDK_space:
case GDK_KP_Space:
case GDK_Right: /* Lynx-style "forward" */
case GDK_KP_Right:
/* Only handle these key presses if we have an active selection;
otherwise, pass them on. */
if (cv->selection >= 0) {
@ -353,17 +359,6 @@ e_completion_view_key_press_handler (GtkWidget *w, GdkEventKey *key_event, gpoin
dir = 0;
break;
case GDK_Left: /* Lynx-style "back" */
case GDK_KP_Left:
if (cv->selection >= 0) {
/* A hack to "unbrowse" us on these keys if we are browsing. */
cv->selection = -1;
dir = 0;
break;
}
return FALSE;
default:
return FALSE;
}
@ -385,13 +380,14 @@ e_completion_view_key_press_handler (GtkWidget *w, GdkEventKey *key_event, gpoin
gtk_signal_emit (GTK_OBJECT (cv), e_completion_view_signals[E_COMPLETION_VIEW_UNBROWSE]);
stop_emission:
gtk_signal_emit_stop_by_name (GTK_OBJECT (w), "key_press_event");
if (key_handled)
gtk_signal_emit_stop_by_name (GTK_OBJECT (w), "key_press_event");
return TRUE;
return key_handled;
}
static void
begin_completion_cb (ECompletion *completion, gpointer user_data)
begin_completion_cb (ECompletion *completion, const gchar *txt, gint pos, gint limit, gpointer user_data)
{
ECompletionView *cv = E_COMPLETION_VIEW (user_data);
@ -405,7 +401,7 @@ static void
restart_completion_cb (ECompletion *completion, gpointer user_data)
{
/* For now, handle restarts like the beginning of a new completion. */
begin_completion_cb (completion, user_data);
begin_completion_cb (completion, NULL, 0, 0, user_data);
}
static void
@ -557,6 +553,8 @@ e_completion_view_construct (ECompletionView *cv, ECompletion *completion)
cv->table = e_table_scrolled_new (cv->model, NULL, simple_spec, NULL);
e_scroll_frame_set_policy (E_SCROLL_FRAME (cv->table), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
frame = gtk_frame_new (NULL);
gtk_container_add (GTK_CONTAINER (cv), frame);
@ -655,6 +653,7 @@ e_completion_view_set_width (ECompletionView *cv, gint width)
e_table_group_compute_location (e_completion_view_table (cv)->group,
&dummy, &line_height, &r, &dummy);
}
if (line_height >= 1000) {
/* Something went wrong, so we make a (possibly very lame) guess */
line_height = 30;

View File

@ -50,11 +50,6 @@ struct _Match {
};
struct _ECompletionPrivate {
ECompletionBeginFn begin_search;
ECompletionEndFn end_search;
gpointer user_data;
gboolean searching;
gchar *search_text;
gint pos;
@ -115,8 +110,9 @@ e_completion_class_init (ECompletionClass *klass)
GTK_RUN_LAST,
object_class->type,
GTK_SIGNAL_OFFSET (ECompletionClass, begin_completion),
gtk_marshal_NONE__NONE,
GTK_TYPE_NONE, 0);
gtk_marshal_NONE__POINTER_INT_INT,
GTK_TYPE_NONE, 3,
GTK_TYPE_POINTER, GTK_TYPE_INT, GTK_TYPE_INT);
e_completion_signals[E_COMPLETION_COMPLETION] =
gtk_signal_new ("completion",
@ -259,26 +255,17 @@ e_completion_begin_search (ECompletion *complete, const gchar *text, gint pos, g
if (complete->priv->searching)
e_completion_cancel_search (complete);
/* Without one of these, we can't search! */
if (complete->priv->begin_search) {
g_free (complete->priv->search_text);
complete->priv->search_text = g_strdup (text);
g_free (complete->priv->search_text);
complete->priv->search_text = g_strdup (text);
complete->priv->pos = pos;
complete->priv->searching = TRUE;
complete->priv->pos = pos;
e_completion_clear_matches (complete);
complete->priv->searching = TRUE;
complete->priv->limit = limit > 0 ? limit : G_MAXINT;
e_completion_clear_matches (complete);
complete->priv->limit = limit > 0 ? limit : G_MAXINT;
gtk_signal_emit (GTK_OBJECT (complete), e_completion_signals[E_COMPLETION_BEGIN_COMPLETION]);
complete->priv->begin_search (complete, text, pos, limit, complete->priv->user_data);
return;
}
g_warning ("Unable to search for \"%s\" - no virtual method specified.", text);
gtk_signal_emit (GTK_OBJECT (complete), e_completion_signals[E_COMPLETION_BEGIN_COMPLETION], text, pos, limit);
}
void
@ -291,12 +278,9 @@ e_completion_cancel_search (ECompletion *complete)
if (!complete->priv->searching)
return;
if (complete->priv->end_search)
complete->priv->end_search (complete, FALSE, complete->priv->user_data);
gtk_signal_emit (GTK_OBJECT (complete), e_completion_signals[E_COMPLETION_CANCEL_COMPLETION]);
complete->priv->searching = FALSE;
gtk_signal_emit (GTK_OBJECT (complete), e_completion_signals[E_COMPLETION_CANCEL_COMPLETION]);
}
gboolean
@ -369,25 +353,10 @@ e_completion_find_extra_data (ECompletion *complete, const gchar *text)
return NULL;
}
void
e_completion_construct (ECompletion *complete, ECompletionBeginFn begin_fn, ECompletionEndFn end_fn, gpointer user_data)
{
g_return_if_fail (complete != NULL);
g_return_if_fail (E_IS_COMPLETION (complete));
complete->priv->begin_search = begin_fn;
complete->priv->end_search = end_fn;
complete->priv->user_data = user_data;
}
ECompletion *
e_completion_new (ECompletionBeginFn begin_fn, ECompletionEndFn end_fn, gpointer user_data)
e_completion_new (void)
{
ECompletion *complete = E_COMPLETION (gtk_type_new (e_completion_get_type ()));
e_completion_construct (complete, begin_fn, end_fn, user_data);
return complete;
return E_COMPLETION (gtk_type_new (e_completion_get_type ()));
}
static gint
@ -501,11 +470,8 @@ e_completion_end_search (ECompletion *complete)
if (e_completion_sort_by_score (complete))
e_completion_restart (complete);
if (complete->priv->end_search)
complete->priv->end_search (complete, TRUE, complete->priv->user_data);
complete->priv->searching = FALSE;
gtk_signal_emit (GTK_OBJECT (complete), e_completion_signals[E_COMPLETION_END_COMPLETION]);
complete->priv->searching = FALSE;
}

View File

@ -43,8 +43,6 @@ typedef struct _ECompletion ECompletion;
typedef struct _ECompletionClass ECompletionClass;
struct _ECompletionPrivate;
typedef void (*ECompletionBeginFn) (ECompletion *, const gchar *text, gint pos, gint limit, gpointer user_data);
typedef void (*ECompletionEndFn) (ECompletion *, gboolean finished, gpointer user_data);
typedef void (*ECompletionMatchFn) (const gchar *text, double score, gpointer extra_data, gpointer user_data);
struct _ECompletion {
@ -57,8 +55,8 @@ struct _ECompletionClass {
GtkObjectClass parent_class;
/* Signals */
void (*begin_completion) (ECompletion *comp);
void (*completion) (ECompletion *comp, const gchar *text, gpointer extra_data);
void (*begin_completion) (ECompletion *comp, const gchar *search_text, gint pos, gint limit);
void (*completion) (ECompletion *comp, const gchar *match_text, gpointer extra_data);
void (*restart_completion) (ECompletion *comp);
void (*cancel_completion) (ECompletion *comp);
void (*end_completion) (ECompletion *comp);
@ -76,8 +74,7 @@ gint e_completion_match_count (ECompletion *comp);
void e_completion_foreach_match (ECompletion *comp, ECompletionMatchFn fn, gpointer user_data);
gpointer e_completion_find_extra_data (ECompletion *comp, const gchar *text);
void e_completion_construct (ECompletion *comp, ECompletionBeginFn, ECompletionEndFn, gpointer user_data);
ECompletion *e_completion_new (ECompletionBeginFn, ECompletionEndFn, gpointer user_data);
ECompletion *e_completion_new (void);
@ -93,3 +90,4 @@ END_GNOME_DECLS
#endif /* E_COMPLETION_H */

View File

@ -116,6 +116,7 @@ struct _EEntryPrivate {
gchar *pre_browse_text;
gint completion_delay;
guint completion_delay_tag;
gboolean ptr_grab;
guint draw_borders : 1;
};
@ -200,8 +201,8 @@ e_entry_proxy_changed (EText *text, EEntry *entry)
e_entry_cancel_delayed_completion (entry);
e_entry_show_popup (entry, FALSE);
} else if (entry->priv->popup_is_visible)
e_entry_start_completion (entry);
else if (entry->priv->completion && entry->priv->completion_delay >= 0)
e_entry_start_delayed_completion (entry, 1);
else if (entry->priv->completion)
e_entry_start_delayed_completion (entry, entry->priv->completion_delay);
gtk_signal_emit (GTK_OBJECT (entry), e_entry_signals [E_ENTRY_CHANGED]);
@ -261,7 +262,7 @@ e_entry_init (GtkObject *object)
/*
* Proxy functions: we proxy the changed and activate signals
* from the item to outselves
* from the item to ourselves
*/
entry->priv->changed_proxy_tag = gtk_signal_connect (GTK_OBJECT (entry->priv->item),
"changed",
@ -272,7 +273,7 @@ e_entry_init (GtkObject *object)
GTK_SIGNAL_FUNC (e_entry_proxy_activate),
entry);
entry->priv->completion_delay = -1;
entry->priv->completion_delay = 1;
}
/**
@ -406,27 +407,45 @@ e_entry_show_popup (EEntry *entry, gboolean visible)
if (visible) {
GtkAllocation *dim = &(GTK_WIDGET (entry)->allocation);
gint x, y;
gint x, y, fudge;
const GdkEventMask grab_mask = (GdkEventMask)GDK_BUTTON_PRESS_MASK | GDK_BUTTON_MOTION_MASK | GDK_BUTTON_RELEASE_MASK;
/* Figure out where to put our popup. */
gdk_window_get_origin (GTK_WIDGET (entry)->window, &x, &y);
x += dim->x;
y += dim->height + dim->y;
/* Put our popup slightly to the right and up, to try to give a visual cue that this popup
is tied to this entry. Otherwise one-row popups can sort of "blend" with an entry
directly below. */
fudge = MAX (dim->height/10, 3); /* just in case we are using a really big font, etc. */
x += 2*fudge;
y -= fudge;
gtk_widget_set_uposition (pop, x, y);
e_completion_view_set_width (E_COMPLETION_VIEW (entry->priv->completion_view), dim->width);
gtk_widget_show (pop);
gdk_keyboard_grab (GTK_WIDGET (entry)->window, TRUE, GDK_CURRENT_TIME);
gdk_pointer_grab (GTK_WIDGET (entry->priv->completion_view)->window, TRUE,
(GdkEventMask) GDK_BUTTON_PRESS_MASK | GDK_BUTTON_MOTION_MASK | GDK_BUTTON_RELEASE_MASK,
NULL, NULL, GDK_CURRENT_TIME);
if (! entry->priv->ptr_grab) {
entry->priv->ptr_grab = gdk_pointer_grab (GTK_WIDGET (entry->priv->completion_view)->window, TRUE,
grab_mask, NULL, NULL, GDK_CURRENT_TIME);
if (entry->priv->ptr_grab)
gtk_grab_add (GTK_WIDGET (entry->priv->completion_view));
}
} else {
gtk_widget_hide (pop);
gdk_keyboard_ungrab (GDK_CURRENT_TIME);
gdk_pointer_ungrab (GDK_CURRENT_TIME);
if (entry->priv->ptr_grab) {
gdk_pointer_ungrab (GDK_CURRENT_TIME);
gtk_grab_remove (GTK_WIDGET (entry->priv->completion_view));
}
entry->priv->ptr_grab = FALSE;
}
@ -452,11 +471,10 @@ e_entry_start_completion (EEntry *entry)
if (e_entry_is_empty (entry))
return;
if (entry->priv->completion)
e_completion_begin_search (entry->priv->completion,
e_entry_get_text (entry),
e_entry_get_position (entry),
0); /* No limit. Probably a bad idea. */
e_completion_begin_search (entry->priv->completion,
e_entry_get_text (entry),
e_entry_get_position (entry),
0); /* No limit. Probably a bad idea. */
}
static gboolean
@ -475,11 +493,7 @@ e_entry_start_delayed_completion (EEntry *entry, gint delay)
return;
e_entry_cancel_delayed_completion (entry);
if (delay == 0)
e_entry_start_completion (entry);
else
entry->priv->completion_delay_tag = gtk_timeout_add (delay, start_delayed_cb, entry);
entry->priv->completion_delay_tag = gtk_timeout_add (MAX (delay, 1), start_delayed_cb, entry);
}
static void
@ -488,7 +502,6 @@ e_entry_cancel_delayed_completion (EEntry *entry)
if (entry->priv->completion == NULL)
return;
e_completion_cancel_search (entry->priv->completion); /* just to be sure... */
if (entry->priv->completion_delay_tag) {
gtk_timeout_remove (entry->priv->completion_delay_tag);
entry->priv->completion_delay_tag = 0;
@ -599,7 +612,8 @@ button_press_cb (GtkWidget *w, GdkEvent *ev, gpointer user_data)
}
}
e_entry_show_popup (entry, FALSE);
/* Treat this as an unbrowse */
unbrowse_cb (E_COMPLETION_VIEW (w), entry);
}
void
@ -976,6 +990,9 @@ e_entry_destroy (GtkObject *object)
gtk_widget_destroy (entry->priv->completion_view_popup);
g_free (entry->priv->pre_browse_text);
if (entry->priv->ptr_grab)
gdk_pointer_ungrab (GDK_CURRENT_TIME);
g_free (entry->priv);
entry->priv = NULL;
}