Re: Update of GtkRadioMenuItems wihtout emitting any signal
"Mark R. Rubin" <[EMAIL PROTECTED]> writes: > o I (possibly mis-) read Havoc's: > > > if (current_state == gtk_toggle_button_get_active (toggle)) > >return; > FWIW I think I did mean what Paul said, i.e. current_state is the state of the object the toggle button affects. Havoc ___ gtk-list mailing list [EMAIL PROTECTED] http://mail.gnome.org/mailman/listinfo/gtk-list
Re: Update of GtkRadioMenuItems wihtout emitting any signal
Paul Davis <[EMAIL PROTECTED]> writes: > >1) object->state() is an additional requirement on the Model > > object's public interface. Conceptually, what business does a > > View widget have knowing about the Model? It should just be > > told what to display. > > well, it has to have access to whatever parts of the state are > required to display the state. o Or, in my case, not. I have a Model which knows about and tells a View what to display. (I think) you have a View which knows about a Model and queries it for a value. Either way there's a binding. o From http://www.ootips.org/mvc-pattern.html (which I found via an archived thread of yours from over a year ago): > The model, viewport and controller are intimately related and in > constant contact. Therefore, they must reference each other. o The discussion goes on about the strongly- and weakly-typed knowledge the classes have of each other. See below. > >o But for Model-to-View I just directly call the gtkmm methods: > > > >Model::some_method() > >{ > >_state1 = some_computation() ; > >_togglebutton1.set_active(_state1) ; > >} > > that breaks the anonymity principle. a Model should have *zero* > knowledge of the View or Controllers. if you don't do this, you cannot > have multiple Views, Model::some_method() { _state1 = some_computation() ; _togglebutton1.set_active(_state1) ; _reverse_togglebutton2.set_active(!_state1) ; } > for example, and you can't reimplement the View > without reimplementing the Model. having the Model drive the View > directly is not really MVC, and in my experience, not very good OOP either. o Nomenclature, nomenclature. I thought a Gtk::ToggleButton was a View (also a Controller). My "Model::some_method()" above is really called "Gui::some_method()", so maybe what I've been calling Model is really a (composite) View. o If not -- if Views are solely gtkmm widgets, not some class which contains them as member objects -- and: > >o Bigger question: Do you use libsigc++ signals for *all* your MVC > > communication (both Controller-to-Model and Model-to-View)? > > yes, for everything. o And: > I generally find that I have to connect to to button press/release > and keypress signals and so forth, but i rarely override them. o Then how do you change a togglebutton other than using Gtk::ToggleButton::set_active()? o From "ootips": > By contrast, the viewport knows > exactly what kind of model it observes. o How could a (stock, compiled-into-a-library, non-derived-from) Gtk::ToggleButton know anything about your Model? -- MARK [EMAIL PROTECTED] ___ gtk-list mailing list [EMAIL PROTECTED] http://mail.gnome.org/mailman/listinfo/gtk-list
Re: Update of GtkRadioMenuItems wihtout emitting any signal
>1) object->state() is an additional requirement on the Model > object's public interface. Conceptually, what business does a > View widget have knowing about the Model? It should just be > told what to display. well, it has to have access to whatever parts of the state are required to display the state. >2) Potential mismatch between Model object's internal state and > View widget's represention of same. Example: Model keeps > double values, GtkAdjustment uses gfloats. Or: Model keeps > HTML/RTF/internationalized text, GtkText uses GtkText(??), some > HTML widget uses HTML, so Model has to export multiple types of > state (or maybe multiple overloads of operator!=()). this can certainly become a problem. >> Controller::do_something_to_model (Model *model) >> { >>model->set_state (foo, this); >> } >> >> this causes "object" to emits its "StateChanged" signal. > >o Is "object" the Controller, or the Model? its the Model. >o Bigger question: Do you use libsigc++ signals for *all* your MVC > communication (both Controller-to-Model and Model-to-View)? yes, for everything. >o But for Model-to-View I just directly call the gtkmm methods: > >Model::some_method() >{ >_state1 = some_computation() ; >_togglebutton1.set_active(_state1) ; >} that breaks the anonymity principle. a Model should have *zero* knowledge of the View or Controllers. if you don't do this, you cannot have multiple Views, for example, and you can't reimplement the View without reimplementing the Model. having the Model drive the View directly is not really MVC, and in my experience, not very good OOP either. >o I don't write my own methods for Views and Controllers -- they're > just gtkmm widgets, used as-is. I don't derive from them and > extend/override (except for Gtk::DrawingArea). I generally find that I have to connect to to button press/release and keypress signals and so forth, but i rarely override them. the main hack i have to do is to call gtk_signal_emit_stop_by_name() because a button press on a widget drives a change of visual appearance in the widget that cannot happen until the Model state change actually takes place (and it may never take place for reasons that the Controller doesn't know about). --p ___ gtk-list mailing list [EMAIL PROTECTED] http://mail.gnome.org/mailman/listinfo/gtk-list
Re: Update of GtkRadioMenuItems wihtout emitting any signal
Paul Davis <[EMAIL PROTECTED]> writes: > try "MVC" in the body, since i usually use that acronym when > discussing this. o 84 hits. I'll read them. Thanks. > >handle_widget_state_change () { > >if (widget->representation_of_object_state() != object->state()) > >object->set_state (widget->state()); > >} > > yes, thats right. i wasn't being careful enough as i tuped that > in. sorry about that. o No problem. Glad I'm not (totally) crazy. o This is obviously one of the workable solutions. The two relatively minor things I don't like about it are: 1) object->state() is an additional requirement on the Model object's public interface. Conceptually, what business does a View widget have knowing about the Model? It should just be told what to display. 2) Potential mismatch between Model object's internal state and View widget's represention of same. Example: Model keeps double values, GtkAdjustment uses gfloats. Or: Model keeps HTML/RTF/internationalized text, GtkText uses GtkText(??), some HTML widget uses HTML, so Model has to export multiple types of state (or maybe multiple overloads of operator!=()). > >>handle_widget_state_change (void *src) { > >> if (src == this) { > >> /* ignore */ > >> return; > >> } > >> > >> } > >> > ... > >o Is the "this" in the above code fragment the object (Model) or the > > widget (View/Controller)? If object/Model, I don't understand > > because mine don't emit signals (widgets/Controllers emit signals; > > objects/Models do things like gtk_toggle_button_set_active()). If > > "this" is the widget/Controller, when "src==this" is exactly when > > the action should take place. > > sorry. i work in C++ and i use libsigc++ which offers me a superb > system for writing MVC programs. the "this" i used above refers to the > thing "on whose behalf" a member function is beind called. its an > "implicit" argument in all C++ member functions. o I also use gtk++(gtkmm) and libsigc++. I think some of the nomenclature confusion here is because we're all translating back and forth between C/GTK and C++/GTK--. o In C++ terms, my question was really "is the above handle_widget_state_change() a method of the object/Model class, or of the widget/View/Controller class"? o In any case, I'm going to switch to the nomenclature you're using below. > my objects all attempt > to remain anonymous and ignorant of who has registered an interest in > their state changes, which libsigc++ makes *phenomenally* easy to > do. so, suppose we have a true MVC system that includes: > > Controller::do_something_to_model (Model *model) > { >model->set_state (foo, this); > } > > this causes "object" to emits its "StateChanged" signal. o Is "object" the Controller, or the Model? o Bigger question: Do you use libsigc++ signals for *all* your MVC communication (both Controller-to-Model and Model-to-View)? o I don't. I use it for Controller-to-Model: Model::Model() : _state1(false) { _togglebutton1 .toggled .connect(bind(slot(*this, &Model::button1_toggled), &_togglebutton1)) ; } Model::button1_toggled( const Gtk::ToggleButton *togglebutton) { _state1 = togglebutton->get_active() ; } o But for Model-to-View I just directly call the gtkmm methods: Model::some_method() { _state1 = some_computation() ; _togglebutton1.set_active(_state1) ; } o I don't write my own methods for Views and Controllers -- they're just gtkmm widgets, used as-is. I don't derive from them and extend/override (except for Gtk::DrawingArea). o So my Model objects never emit signals (they just receive them) and my View/Controller objects never receive signals (just emit). If yours go "both ways" it would explain my confusion over your (otherwise clear) descriptions. o I'm going to table further questions pending an understanding of this, and a review of the list archives and the Gang Of Four book. -- MARK [EMAIL PROTECTED] ___ gtk-list mailing list [EMAIL PROTECTED] http://mail.gnome.org/mailman/listinfo/gtk-list
Re: Update of GtkRadioMenuItems wihtout emitting any signal
> searched the archives for this, but never found the right > keywords. Could you provide some "Subject:" lines? Searching for try "MVC" in the body, since i usually use that acronym when discussing this. > a little differently. If his "current_state" is your > "object->state()" (which makes more sense than my interpretation of > "widget->previous_state()"), and if "handle_widget_state_change()" > is a GTK signal-handler/callback, I would think it should be: > >handle_widget_state_change () { >if (widget->representation_of_object_state() != object->state()) >object->set_state (widget->state()); >} yes, thats right. i wasn't being careful enough as i tuped that in. sorry about that. >>handle_widget_state_change (void *src) { >> if (src == this) { >> /* ignore */ >> return; >> } >> >> } >> >> this lets a widget set the state of its underlying object (when acting >> as a controller), supplying "itself" as the src pointer, and thus >> ignore any notifications from the object when they are sent following >> the object's state change. > >o Is the "this" in the above code fragment the object (Model) or the > widget (View/Controller)? If object/Model, I don't understand > because mine don't emit signals (widgets/Controllers emit signals; > objects/Models do things like gtk_toggle_button_set_active()). If > "this" is the widget/Controller, when "src==this" is exactly when > the action should take place. sorry. i work in C++ and i use libsigc++ which offers me a superb system for writing MVC programs. the "this" i used above refers to the thing "on whose behalf" a member function is beind called. its an "implicit" argument in all C++ member functions.my objects all attempt to remain anonymous and ignorant of who has registered an interest in their state changes, which libsigc++ makes *phenomenally* easy to do. so, suppose we have a true MVC system that includes: Controller::do_something_to_model (Model *model) { model->set_state (foo, this); } this causes "object" to emits its "StateChanged" signal. Now, suppose that we have a view hooked up to the signal, with a handler: View::handle_model_state_change (void *src) { if (src == this) { /* we initiated the state change in the model, so presumably our visual appearance is up- to-date. relax. */ return; } ... something else changed the model's state ... ... make our appearance reflect the model's state ... } now, as you have noted, its common to use a single widget as both a "controller" and a "view". in that case, you'd have ControllerView::do_something_to_model (Model *model) { model->set_state (foo, this); ... change visual appearance if appropriate ... } this would presumably be called because of some GUI event (e.g. a button click). We will still have: ControllerView::handle_model_state_change (void *src) { } but this time, we will find out that the "src" of the change is ourselves. Presumably, our appearance is already correct (we responded to that in do_something_to_model(), so we can just return. Does this make this style any clearer? As I say, I've found that I've managed to avoid this by comparing model state to view state, but its still useful occasionally. There are other ways of tackling what ControllerView::do_something_to_model() does - its worth reading up on MVC programming and/or "Design Patterns" to get a handle on some of them. --p ___ gtk-list mailing list [EMAIL PROTECTED] http://mail.gnome.org/mailman/listinfo/gtk-list
Re: Update of GtkRadioMenuItems wihtout emitting any signal
one other comment. its worth being very careful to make sure that the Model does not emit "my state changed" signals just because "set_state()" was called upon it. i.e. actually check to make sure that the new state really is different from the old before emitting the changed signal. this may seem obvious to you - it wasn't to me. --p ___ gtk-list mailing list [EMAIL PROTECTED] http://mail.gnome.org/mailman/listinfo/gtk-list
Re: Update of GtkRadioMenuItems wihtout emitting any signal
Paul Davis <[EMAIL PROTECTED]> writes: > you're not the only ones; i've discussed this issue several times on > this list in the past. o Thanks for your analyses (below). As I said originally, I've searched the archives for this, but never found the right keywords. Could you provide some "Subject:" lines? Searching for your name doesn't help -- you post too much to the lists. (This is a compliment, not a complaint.) > however, if you're really doing > Model-View-Controller style programming, which is highly desirable and > it sounds as if you are, then Havoc's suggestion of: > >handle_widget_state_change () { > if (widget->representation_of_object_state() != object->state()) > widget->set_state (object->state()); > } > > is the *only* correct route to take here. o I (possibly mis-) read Havoc's: > if (current_state == gtk_toggle_button_get_active (toggle)) >return; a little differently. If his "current_state" is your "object->state()" (which makes more sense than my interpretation of "widget->previous_state()"), and if "handle_widget_state_change()" is a GTK signal-handler/callback, I would think it should be: handle_widget_state_change () { if (widget->representation_of_object_state() != object->state()) object->set_state (widget->state()); } in order to break the feedback loop that causes me problems: 1) object ("Model") state changes 2) object changes widget X ("View") state 3) widget X is also a "Controller", thus emits a signal which is caught by a signal handler which changes object's state 4) loop back to 1) > in my C++ code, i tend to use a void * (aka gpointer) as an extra arg > to all functions that change the state of my objects ("models"), an > arg i call "src". when the objects emit signals as a result of the > change, they include the "src" argument. as a result, widgets ("views" > and/or "controllers") can do things like: > >handle_widget_state_change (void *src) { > if (src == this) { > /* ignore */ > return; > } > > } > > this lets a widget set the state of its underlying object (when acting > as a controller), supplying "itself" as the src pointer, and thus > ignore any notifications from the object when they are sent following > the object's state change. o Is the "this" in the above code fragment the object (Model) or the widget (View/Controller)? If object/Model, I don't understand because mine don't emit signals (widgets/Controllers emit signals; objects/Models do things like gtk_toggle_button_set_active()). If "this" is the widget/Controller, when "src==this" is exactly when the action should take place. -- MARK [EMAIL PROTECTED] ___ gtk-list mailing list [EMAIL PROTECTED] http://mail.gnome.org/mailman/listinfo/gtk-list
Re: Update of GtkRadioMenuItems wihtout emitting any signal
>o I also have trouble believing that Ignacio Nodal and myself are the > only ones who've ever been bitten by this. Screen real estate is > always precious, and re-using a widget for input and output always > helps (and is easier on the user than "click this togglebutton to > change from "input values" to "display values" mode). you're not the only ones; i've discussed this issue several times on this list in the past. however, if you're really doing Model-View-Controller style programming, which is highly desirable and it sounds as if you are, then Havoc's suggestion of: handle_widget_state_change () { if (widget->representation_of_object_state() != object->state()) widget->set_state (object->state()); } is the *only* correct route to take here. in my C++ code, i tend to use a void * (aka gpointer) as an extra arg to all functions that change the state of my objects ("models"), an arg i call "src". when the objects emit signals as a result of the change, they include the "src" argument. as a result, widgets ("views" and/or "controllers") can do things like: handle_widget_state_change (void *src) { if (src == this) { /* ignore */ return; } } this lets a widget set the state of its underlying object (when acting as a controller), supplying "itself" as the src pointer, and thus ignore any notifications from the object when they are sent following the object's state change. however ... despite the fact that i found this to be a rather elegant solution, i think that there are hardly any places in my code where i make this check, and that number is going down all the time. the explicit comparison of widget state and object state now dominates my code, and it generally feels "right". your suggestion for "emit only on user input" will break proper MVC programming as soon as there are non-X-based methods of changing object or widget state. most of my programs accept MIDI input, for example, that can be used to change object states, and i expect my widgets to follow those changes. unless you provide a way to say "change this GtkAdjustment as if i were a user" and "change this GtkAdjustment as if i were not a user", which is deeply cumbersome, somewhere down the line, there has to be a call to "change this GtkAdjustment", and that *must* emit a signal that can be caught. anything less will, as Havoc intimated, and as i now emphasize, break a good MVC design in many subtle and not so subtle ways. --p ___ gtk-list mailing list [EMAIL PROTECTED] http://mail.gnome.org/mailman/listinfo/gtk-list
Re: Update of GtkRadioMenuItems wihtout emitting any signal
Havoc Pennington <[EMAIL PROTECTED]> writes: > It depends on the situation. Some approaches are: > > - gtk_signal_handler_block (g_signal_handlers_block, and by_func variants) > - don't do anything in the callback if the value hasn't changed: > if (current_state == gtk_toggle_button_get_active (toggle)) > return; > - fill in the default state of controls before you connect the >callbacks to them > > You can also use a global flag or a flag specific to a class/object, > but I don't like that approach much personally. o I don't like it much, either. (That's why I wrote "it's [still] pretty ugly".) o Thanks for weighing in on this. I didn't know about gtk_signal_handler_block(), etc., and will look into them. Unfortunately, a quick check seems to say they're not exposed in GTK-- (gtkmm), which is what I mostly use. o I need to test the performance of various solutions. Amongst: 1) Set a flag, change the widget, let the signal happen, test the flag. 2) Check current state in callback, do nothing if unchanged. (Requires maintaining a separate copy of the widget state -- isn't the XXX_get_YYY() or the adjustment value already changed by the time you're in the callback?) 3) gtk_signal_handler_block(), change the widget, gtk_signal_handler_unblock() 4) disconnect the signal, change the widget, re-connect the signal my guess is that #1 or #2 are still the most efficient. I do have cases where performance is important. Example: CAD program where user can set the current object's position by inputting x,y in spinbuttons, but can also drag the object around in its drawing area while the spinbuttons display x,y. > Most signals indicate that the state of an object has changed, not > that it has changed due to some specific cause (e.g. user input). > This is the right thing IMO for reasons of conceptual cleanliness; > there would be lots of subtle tricky bugs otherwise. In any case it's > too late to change this aspect of GTK. o I agree on conceptual cleanliness and that it's "too late" (would break huge number of programs). I do wonder what it would take to add a widget specific (and/or global-affect-all-widgets) command to optionally change the behavior to "emit signal only on user input". Default stays the way it is now; no programs break. Someday I'll look through the source and see. o I also have trouble believing that Ignacio Nodal and myself are the only ones who've ever been bitten by this. Screen real estate is always precious, and re-using a widget for input and output always helps (and is easier on the user than "click this togglebutton to change from "input values" to "display values" mode). -- MARK [EMAIL PROTECTED] ___ gtk-list mailing list [EMAIL PROTECTED] http://mail.gnome.org/mailman/listinfo/gtk-list
Re: Update of GtkRadioMenuItems wihtout emitting any signal
"Mark R. Rubin" <[EMAIL PROTECTED]> writes: > o Someone (Havoc??) must know the right solution to this problem. > It depends on the situation. Some approaches are: - gtk_signal_handler_block (g_signal_handlers_block, and by_func variants) - don't do anything in the callback if the value hasn't changed: if (current_state == gtk_toggle_button_get_active (toggle)) return; - fill in the default state of controls before you connect the callbacks to them You can also use a global flag or a flag specific to a class/object, but I don't like that approach much personally. Most signals indicate that the state of an object has changed, not that it has changed due to some specific cause (e.g. user input). This is the right thing IMO for reasons of conceptual cleanliness; there would be lots of subtle tricky bugs otherwise. In any case it's too late to change this aspect of GTK. Havoc ___ gtk-list mailing list [EMAIL PROTECTED] http://mail.gnome.org/mailman/listinfo/gtk-list
Re: Update of GtkRadioMenuItems wihtout emitting any signal
Ignacio Nodal <[EMAIL PROTECTED]> writes: > When I select a different CURRENT_GLOBJECT I want to update the selected > active GtkRadioMenuItem, but without emitting the "activate" signal, so > the menuitems callback isn't call. and: > How can I activate the widget returned by GtkMenuItemWidget() without > emitting the activate signal? > > may I use something like: > > gtk_menu_item_activate(GTK_MENU_ITEM(act_widget)); > gtk_signal_emit_stop_by_name(GTKOBJECT(act_widget), "activate"); o I have had the same question for over a year now. I've tried searching the list archives, but never found the right keyword to use. o The problem isn't limited to menus. It happens any time you use the same widget for both input (the user is supplying information to the program) and output (the program is displaying information to the user). o In the "input" case, I obviously want the signal to be emitted. For "output", I don't because the program already knows it's changing the widget's value. o At minimum, the unwanted signal causes unnecessary/redundant computation to take place. At worst, it can cause an infinite loop. Last year I wrote, but never posted, a simple example program to illustrate this. It's my own "hello world" test program for GUI toolkits: A fahrenheit-to-celcius temperature converter. It has two spinputtons, one for F and one for C. The user changes either one, and the other displays the correct matching temperature. For example, when the user inputs a C temperature, a signal is emitted, the program calculates F and displays it in the other spinbutton ... which then emits a signal causing a conversion back to F, and an update of the F spinputton. (In this case, because the conversion is invertible, the F value is the same as what the user inputted, so the F spinbutton doesn't emit a signal. No infinite loop, just redundant calculation.) o My workaround -- for real-world programs, not toy F-to-C converters -- is to set a flag when changing a widget. Then, in the signal handler: if (flag) { flag = FALSE ; return ; } else // really handle the signal o In C and Gtk this gets ugly very fast (global variables). I use C++ and Gtk--, so I wrap (for example) Gtk::Adjustment in my own class which handles the flag internally. It's still pretty ugly. o Someone (Havoc??) must know the right solution to this problem. -- MARK [EMAIL PROTECTED] ___ gtk-list mailing list [EMAIL PROTECTED] http://mail.gnome.org/mailman/listinfo/gtk-list
Update of GtkRadioMenuItems wihtout emitting any signal
Hi, I have a set of 3D Objects defined in my application, but I only show one of it. Let's call it the CURRENT_GLOBJECT. I can change the CURRENT_GLOBJECT by code or selecting it from a Menu of GtkRadioMenuItems, one GtkRadioMenuItem for each object. When I select a different CURRENT_GLOBJECT I want to update the selected active GtkRadioMenuItem, but without emitting the "activate" signal, so the menuitems callback isn't call. I use a function which returns me the widget I have to activate: GtkWidget *GetMenuItemWidget(GtkWidget* widget,gint num_object) (in my function, "widget" can be any of the GtkRadioMenuItems since they belong all to the same group) How can I activate the widget returned by GtkMenuItemWidget() without emitting the activate signal? may I use something like: gtk_menu_item_activate(GTK_MENU_ITEM(act_widget)); gtk_signal_emit_stop_by_name(GTKOBJECT(act_widget), "activate"); or which is the correct way? Thanks in advance, Ignacio Nodal ___ gtk-list mailing list [EMAIL PROTECTED] http://mail.gnome.org/mailman/listinfo/gtk-list