Re: How to redefine button functionality on a GtkTree?
- From: Thomas Mailund Jensen <mailund daimi au dk>
- To: gtk-list redhat com
- Subject: Re: How to redefine button functionality on a GtkTree?
- Date: 20 Jan 1999 13:15:00 +0100
>>>>> "S" == Steven J Hill <sjhill@plutonium.net> writes:
S> I am trying to capture button press events within a
S> GtkTree. However, I notice that if I press the middle mouse button
S> on a GtkTreeItem that has a subtree and is collapsed, it expands
S> the subtree. And if I press the right mouse button, it collapses
S> the subtree. How do I redefine what those events do and how do I
S> parse the events to see if the middle or right button was pressed?
S> I looked at the 'gtk_widget_set_events' method, but I am not quite
S> sure how to make things work yet. Thanks in advance.
As I understand your question, you want to know
1) How to determine which button was pressed
2) How to overwrite a default event handler
Now, the first question is easy. When you get the button_press event,
you also get a GdkEventButton. This guy has an entry called button,
which tells you exactly which button was pressed. So you simply
switch on that one. See the tree_button_press function in the
attached program.
Now, for question two...here you need to know a little more about
signal/event handling. I quote from the tutorial "20.2 Signal
Emission and Propagation":
Signal emission is the process wherby GTK+ runs all handlers for a
specific object and signal.
First, note that the return value from a signal emission is the
return value of the last handler executed. Since event signals are
all of type GTK_RUN_LAST, this will be the default (GTK+ supplied)
default handler, unless you connect with gtk_signal_connect_after().
The way an event (say GTK_BUTTON_PRESS) is handled, is:
* Start with the widget where the event occured.
* Emit the generic "event" signal. If that signal handler returns a
value of TRUE, stop all processing.
* Otherwise, emit a specific, "button_press_event" signal. If that
returns TRUE, stop all processing. Otherwise, go to the widget's
parent, and repeat the above steps.
* Contimue until some signal handler returns TRUE, or until the
top-level widget is reached.
Some consequences of the above are:
* Your handler's return value will have no effect if there is a
default handler, unless you connect with
gtk_signal_connect_after().
* To prevent the default handler from being run, you need to
connect with gtk_signal_connect() and use
gtk_signal_emit_stop_by_name() - the return value only affects
whether the signal is propagated, not the current emission.
Now, we want to catch the button_press event, but we *don't* want
default handler to get its hands on it. ('cause we don't want all that
expand/collaps stuff).
So we must intall an event handler with gtk_signal_connect, (or
gtk_signal_connect_object) so _we_ get the signal before the default
handler.
Then we must stop futher emission of the signal by calling some
variant of gtk_signal_emit_stop. Try the attached program with and
without emit_stop.
If you want to propagate the event to the parent widget you return
FALSE, otherwise you return TRUE. You can try both in
tree_button_press in the test program. Notice however that since the
default button_press handler stops propagation you will only see the
effect of returning FALSE if you also call emit_stop.
Hope this answers your questions
/mailund
===File ~/tmp/bar.c=========================================
#include <gtk/gtk.h>
static gint
tree_button_press (GtkWidget *tree,
GdkEventButton *event)
{
g_return_if_fail (tree != NULL);
g_return_if_fail (GTK_IS_TREE (tree));
switch (event->button) {
case 1:
g_print ("button 1 was pressed\n");
/* here we just want the usual behaviour */
return FALSE; /* we're not done with the signal */
case 2:
g_print ("button 2 was pressed\n");
break;
case 3:
g_print ("button 3 was pressed\n");
break;
}
/* stop further event processing */
gtk_signal_emit_stop_by_name (GTK_OBJECT (tree), "button_press_event");
return TRUE; /* we're done... */
}
static gint
win_button_press (GtkWidget *w)
{
g_print ("window: button pressed\n");
return FALSE; /* not done */
}
int
main (int argc, char *argv[])
{
GtkWidget *window;
GtkWidget *tree;
GtkWidget *sub_tree;
GtkWidget *tree_item;
gint event_mask;
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
tree = gtk_tree_new ();
gtk_widget_set_usize (tree, 200, 200); /* just so I can see it */
gtk_container_add (GTK_CONTAINER (window), tree);
/* make a small tree... */
tree_item = gtk_tree_item_new_with_label ("foo");
gtk_tree_append (GTK_TREE (tree), tree_item);
sub_tree = gtk_tree_new ();
gtk_tree_item_set_subtree (GTK_TREE_ITEM (tree_item), sub_tree);
tree_item = gtk_tree_item_new_with_label ("bar");
gtk_widget_show (tree_item); /* 'cause show_all wont */
gtk_tree_append (GTK_TREE (sub_tree), tree_item);
tree_item = gtk_tree_item_new_with_label ("baz");
gtk_widget_show (tree_item); /* 'cause show_all wont */
gtk_tree_append (GTK_TREE (sub_tree), tree_item);
gtk_signal_connect (GTK_OBJECT (tree), "button_press_event",
GTK_SIGNAL_FUNC (tree_button_press), NULL);
gtk_signal_connect (GTK_OBJECT (sub_tree), "button_press_event",
GTK_SIGNAL_FUNC (tree_button_press), NULL);
event_mask = gtk_widget_get_events (window) | GDK_BUTTON_PRESS_MASK;
gtk_widget_set_events (window, event_mask);
gtk_signal_connect (GTK_OBJECT (window), "button_press_event",
GTK_SIGNAL_FUNC (win_button_press), NULL);
gtk_widget_show_all (window);
gtk_main ();
return 0;
}
============================================================
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]