Re: "Lazy" GtkToggleButtons
- From: David Nečas (Yeti) <yeti physics muni cz>
- To: gtk-app-devel-list gnome org
- Subject: Re: "Lazy" GtkToggleButtons
- Date: Fri, 2 Feb 2007 21:31:18 +0100
On Fri, Feb 02, 2007 at 07:30:24PM +0100, Stefan Weber lawo de 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;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]