Re: MVC and GTK



>The gtk_signal_handler_{un}block_by_{func,data} are also quite handy as 
>they allow you to forgo storing the handler ID.  If you are writing C++ 
>code on top of GTK, {un}blocking a signal can be as easy as:
>
>gtk_signal_handler_{un}block_by_data(GTK_OBJECT(mWidget), this);
>
>provided, of course, that you passed "this" to gtk_signal_connect.

true, except for 2 things:

1) i write C++, but i use Gtk--, which means i never use gtk_signal_connect()

2) its not MVC-friendly to require specific action to block signal
     emission. the idea is that there are ways to modify the state
     of a widget without *any* signals being emitted because
     the change is in response to some part of the overall
     MVC "loop". i want to be able to do:

     gtk_adjustment_set_value_SILENT (GTK_ADJUSTMENT(w),1.0);
     gtk_toggle_button_set_active_SILENT (GTK_TOGGLE_BUTTON(w), TRUE);

     and many, many others with the precise expectation that all
     i have done is to change the internal state of the widget and
     possibly caused it to be redrawn.

     GTK+'s signal system can't manage a circular/feedback MVC model,
     and so rather than have it try, i'd like to be able to
     turn of signal emission *implicitly* when i need to change
     the state of various widgets. 

     Of course, its more complex than that. Adjustments in particular
     are highly non-MVC friendly, even though at first sight they 
     look like just the right thing. You can have N other objects
     all connect to the value_changed signal for an adjustment,
     and none of them can know the right thing to do in their
     handler without redundant code that ought not be necessary.

In my MVC-friendly C++ objects, I've adopted the convention that all
signals include the identity of the object that initiated the change:

	SigC::Signal1<void,void*> something_changed;
	void set_something (..., void *src) {
	     ...
	     something_changed (src);
        }

This allows the handlers for the something_changed() signal to
check if they were the source of the change, and if so, they ignore
the signal internally:

        void something_else_changed (void *src)
	{
	        .
		.
		.
		set_something (0xfeedface, this);
        }

	void something_changed (void *src)
	{
		if (src == this) {
		   return;
		}

		... do whatever is needed in response to the change ...
        }		

This would obviously be a massive change for GTK+, unfortunately.

--p




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]