On Fri, Feb 02, 2007 at 07:30:24PM +0100, [EMAIL PROTECTED] wrote: > I frequently have the need for GtkToggleButtons that emit a > "toggled"-signal but do not switch state. The signal handler then should > send a toggle request to a server via network. After receiving a > confirmation from the server, I wish to toggle the button from code. I > have not found a way to do so yet. Activating/Deactivating the button in > the toggled-signal-handler leads to endless recursion. Has anybody else > found a way accomplish that?
See the enclosed example. Note if you want to use other signals of the button than "toggled", things can get hairy and I would think about creation of a new widget. Yeti -- Whatever. ============================================================================= #include <gtk/gtk.h> typedef enum { TOGGLE_USER = 0, TOGGLE_EVADE, TOGGLE_FINISH } ToggleType; static GQuark toggle_type_quark = 0; static GQuark timeout_id_quark = 0; static gboolean lazy_button_finish_toggle(gpointer data) { GtkWidget *button = (GtkWidget*)data; g_object_set_qdata(G_OBJECT(button), timeout_id_quark, NULL); g_object_set_qdata(G_OBJECT(button), toggle_type_quark, GUINT_TO_POINTER(TOGGLE_FINISH)); gtk_toggle_button_toggled(GTK_TOGGLE_BUTTON(data)); return FALSE; } static void lazy_button_toggled(GtkWidget *button, gpointer data) { guint id; switch (GPOINTER_TO_UINT(g_object_get_qdata(G_OBJECT(button), toggle_type_quark))) { case TOGGLE_EVADE: g_signal_stop_emission_by_name(button, "toggled"); return; case TOGGLE_USER: gtk_widget_set_sensitive(button, FALSE); g_object_set_qdata(G_OBJECT(button), toggle_type_quark, GUINT_TO_POINTER(TOGGLE_EVADE)); id = g_timeout_add(GPOINTER_TO_INT(data), lazy_button_finish_toggle, button); g_object_set_qdata(G_OBJECT(button), timeout_id_quark, GUINT_TO_POINTER(id)); gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(button), TRUE); g_signal_stop_emission_by_name(button, "toggled"); break; case TOGGLE_FINISH: gtk_widget_set_sensitive(button, TRUE); gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(button), FALSE); g_object_set_qdata(G_OBJECT(button), toggle_type_quark, GUINT_TO_POINTER(TOGGLE_USER)); /* Work around Gtk+ bug */ gtk_widget_hide(button); gtk_widget_show(button); } } static void lazy_button_destroy(GtkWidget *button) { guint id; if ((id = GPOINTER_TO_UINT(g_object_get_qdata(G_OBJECT(button), timeout_id_quark)))) g_source_remove(id); } static GtkWidget* lazy_button_new_with_mnemonic(const gchar *label, gint laziness) { GtkWidget *button; if (!toggle_type_quark) toggle_type_quark = g_quark_from_static_string("toggle type"); if (!timeout_id_quark) timeout_id_quark = g_quark_from_static_string("timeout id"); button = gtk_toggle_button_new_with_label(label); g_signal_connect(button, "toggled", G_CALLBACK(lazy_button_toggled), GINT_TO_POINTER(laziness)); g_signal_connect(button, "destroy", G_CALLBACK(lazy_button_destroy), NULL); return button; } static void application_toggled_callback(GtkWidget *button) { g_printerr("Button %p toggled, state is: %d\n", button, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button))); } int main(int argc, char *argv[]) { GtkWidget *window, *button; gtk_init(&argc, &argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL); button = lazy_button_new_with_mnemonic("I'm so bloody lazy", 2000); gtk_container_add(GTK_CONTAINER(window), button); g_signal_connect(button, "toggled", G_CALLBACK(application_toggled_callback), NULL); gtk_widget_show_all(window); gtk_main(); return 0; } _______________________________________________ gtk-app-devel-list mailing list gtk-app-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-app-devel-list