Is it possible to block the "clicked" signal from getting to gtk's built-in handler which toggles the "up/down" state of a pair of gtk radio buttons or gtk toggle buttons?
Background:
I am working on a GTK application (in C, for linux & OS X) which needs to turn a hardware GPIO pin on and off over a network connection. The pin is turned on or off by sending a message (i.e. it is event-driven.) The hardware periodically sends a message back which gives the actual state of the hardware pin and it is important that the true state of the pin is reflected to the user (it might be different from the user's select state for a number of reasons which I won't go into.) I am currently using a pair of gtk radio buttons to turn the pin on and off, I set them up like this:
void create_control_buttons(control_t *item)
{
assert(item != NULL);
// Create grouped Gtk radio buttons.
item->button0 = gtk_radio_button_new_with_label(NULL, "Off");
item->button1 = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(item->button0), "On");
// Make the radio buttons look like normal buttons.
gtk_toggle_button_set_mode(GTK_TOGGLE_BUTTON(item->button0), FALSE);
gtk_toggle_button_set_mode(GTK_TOGGLE_BUTTON(item->button1), FALSE);
g_signal_connect(G_OBJECT(item->button0), "clicked", G_CALLBACK(on_control_clicked), (gpointer)item);
g_signal_connect(G_OBJECT(item->button1), "clicked", G_CALLBACK(on_control_clicked), (gpointer)item);
}
void on_control_clicked(GtkWidget *widget, gpointer user_data)
{
control_t *item = user_data;
assert(item != NULL);
if (widget == item->button0) {
// Send 'off' signal
} else if (widget == item->button1) {
// send 'on' signal
}
}
Another function is called when a periodic status message is received back from the hardware. It updates the button state like this:
if (state == ON) {
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(item->button1), 1);
} else {
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(item->button0), 1);
}
The code works but there are two problems: 1. It sends two messages if the radio buttons change state. 2. The buttons will change state immediately on "click" but will change back again if the hardware pin state is different, resulting in a rather "glitchy" appearance.
I could do this with ordinary gtk buttons and some other type of widget to reflect the remote state but I would really like the on/off buttons to stay pressed "up" or "down" to show the state for aesthetic / ergonomic reasons.
Is there a way of stopping gtk updating the button state internally, so it only gets updated with gtk_toggle_button_set_active() ?
Please forgive my ignorance, I'm quite new to GTK and there's probably a really obvious solution to this but I've spent a load of time Googling and trying different things out to no avail and I really want to avoid having to write a custom widget.
gtk_widget_queue_draw()
. - andlabs