On Sat, 2003-05-10 at 05:41, Paul Davis wrote:
Speaking for GTK+ 2.
here's a question to ask of a toolkit: can i set
the depressed/raised
state of a button programmatically, without implying that the user
clicked it?
Yes
if the answer is yes, then chances are you are using a
toolkit in
which MVC will be fairly easy to implement. if no, then chances are
its going to be a pain.
then ask the same question of value indicator widgets. etc.
Yes
yes, its a widely known moniker, but its not a widely
used practice. i
know that in GTK+, you have to basically be willing to tolerate
feedback loops between the model and the view, so that when one is
changed, the other gets changed, which might change the first one
again, etc. heaven help you if you suffer from rounding issues between
the model and the view, because then you have no way to stop the loop
without a deadful kludge. without rounding issues, you have to do lots
of this sort of thing:
handler_for_some_gui_event (...) {
if (state_of_view != state_of_model) {
change_view ();
}
}
i've rarely seen code that looks like this when i look at open source
software. maybe i'm looking for the wrong thing.
I usually use signal handler blocking. An example of use would be if you
have a menu radio button tied to a toggle button on a toolbar for
instance. From what I have seen GTK+ will often handle this case fairly
transparently, not sure how though (perhaps something to do with
recursive signal invocation, or the value already set to the desired
state like you mentioned).
So if the menu radio button changes we want to update the toggle button
and vice versa. Lets say the user changes the menu radio button, the
loop would occur when in the radio button toggle handler we set the
state of the toolbar toggle button, which then triggers the toolbar
toggle button, which sets the menu toggle button, etc.
The menu radio button toggle handler would look something like this in C
(we are passing the toolbar toggle button to the signal handler using
the user defined pointer):
void
menu_radio_item_toggled_callback (GtkWidget *radio_item,
gpointer user_data)
{
GtkWidget *toolbar_btn = GTK_WIDGET (user_data);
gboolean active;
/* get state of radio menu item */
active = gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (radio_item));
/* block the toolbar button signal handler to prevent loop */
g_signal_handlers_block_by_func (toolbar_btn,
toolbar_btn_toggled_callback,
radio_item);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toolbar_btn),
active);
/* unblock */
g_signal_handlers_unblock_by_func (toolbar_btn,
toolbar_btn_toggled_callback,
radio_item);
}
In this example we blocked by callback function and data (the data is
significant and must match the data when the signal is connected, the
radio button in the case of the toolbar toggle button callback). You can
also save the signal handler ID and use it to block the handler.
--p
I think thats what you were talking about. I wouldn't be surprised if I
rambled on about something completely different though. Cheers.
Josh Green