In my courageous attempt at fixing bugs I came across this snippet where the variable setProgramatically eludes me:
void RegisteredCheckButton::setActive (bool b) { setProgrammatically = true; set_active (b); //The slave button is greyed out if the master button is unchecked for (std::listGtk::Widget*::const_iterator i = _slavewidgets.begin(); i != _slavewidgets.end(); ++i) { (*i)->set_sensitive(b); } setProgrammatically = false; }
Please help. Found in file <registered-widget.cpp>
On Sep 23, 2012, at 11:28 AM, Arshdeep Singh wrote:
In my courageous attempt at fixing bugs I came across this snippet where the variable setProgramatically eludes me:
void RegisteredCheckButton::setActive (bool b) { setProgrammatically = true; set_active (b); //The slave button is greyed out if the master button is unchecked for (std::listGtk::Widget*::const_iterator i = _slavewidgets.begin(); i != _slavewidgets.end(); ++i) { (*i)->set_sensitive(b); } setProgrammatically = false; }
Please help. Found in file <registered-widget.cpp>
Well... I've not chased down this specific instance, but I can give an overview of some of the patterns in play here.
First of all, "setProgrammatically" is a global variable or a member variable. Doing a quick find/grep to search source, I spotted it in registered-widget.h. It urns out to be a member, thus is on a per-widget basis.
The comment in the .h file helps a bit:
bool setProgrammatically; // true if the value was set by setActive, not changed by the user; // if a callback checks it, it must reset it back to false
The main reason for such toggles is to stop cyclic or runaway loops of recursive calls. It also helps distinguish between events triggered by the end user and those caused by side effects of changes in the middle.
There are a few different things to be done that we can clean up more properly, but for the short term being away of the two main reasons (tell if a user click was the source and prevent infinite loops of events and handlers).
Okay, I've figured that out. Thanks.
Now I face a problem in editing the ' RegisteredCheckButton:<GtkWidget>CheckButton' class ' I added a function 'void setGray(RegisteredChekcButton* ,bool b) to the class definition, obviously the declaration in the <registered-widget.h> and the definition in <registered-widget.cpp>
void setGray (RegisteredCheckButton* A , bool b) { gtk_toggle_set_active ( (GtkToggleButton*) A , !b); }
The object hierarchy shows that GtkCheckButton derives from GtkToggleButton, so this should work. This showed the error that you cannot convert RegisteredCheckButton* to GtkToggleButton* . So I switched
void setGray (RegisteredCheckButton* A , bool b) { gtk_widget_set_sensitive ( (GtkWidget*) A , !b); }
This compiled fine but nothing seems to happen now. This code should 'gray-out' the RegisteredCheckButton.
-------------- --------------- ------------------
Also, I want to make sure if the function
DocumentProperties : update() in the document-properties.cpp
is responsible for making changes in the GUI of the Document Properties Dialog Box and reflecting those changes in the main Inkscape application.
Thanks demicoder
On Mon, Sep 24, 2012 at 2:53 AM, Jon Cruz <jon@...18...> wrote:
On Sep 23, 2012, at 11:28 AM, Arshdeep Singh wrote:
In my courageous attempt at fixing bugs I came across this snippet where the variable setProgramatically eludes me:
void RegisteredCheckButton::setActive (bool b) { setProgrammatically = true; set_active (b); //The slave button is greyed out if the master button is unchecked for (std::listGtk::Widget*::const_iterator i = _slavewidgets.begin(); i != _slavewidgets.end(); ++i) { (*i)->set_sensitive(b); } setProgrammatically = false; }
Please help. Found in file <registered-widget.cpp>
Well... I've not chased down this specific instance, but I can give an overview of some of the patterns in play here.
First of all, "setProgrammatically" is a global variable or a member variable. Doing a quick find/grep to search source, I spotted it in registered-widget.h. It urns out to be a member, thus is on a per-widget basis.
The comment in the .h file helps a bit:
bool setProgrammatically; // true if the value was set by setActive, not changed by the user; // if a callback checks it, it must reset it back to false
The main reason for such toggles is to stop cyclic or runaway loops of recursive calls. It also helps distinguish between events triggered by the end user and those caused by side effects of changes in the middle.
There are a few different things to be done that we can clean up more properly, but for the short term being away of the two main reasons (tell if a user click was the source and prevent infinite loops of events and handlers).
On 24-9-2012 13:16, Arshdeep Singh wrote:
Now I face a problem in editing the ' RegisteredCheckButton:<GtkWidget>CheckButton' class '
please be extra careful in typing class names in e-mails! This above does not make much sense actually :-)
I added a function 'void setGray(RegisteredChekcButton* ,bool b) to the class definition, obviously the declaration in the <registered-widget.h> and the definition in <registered-widget.cpp>
void setGray (RegisteredCheckButton* A , bool b) { gtk_toggle_set_active ( (GtkToggleButton*) A , !b); }
The object hierarchy shows that GtkCheckButton derives from GtkToggleButton, so this should work. This showed the error that you cannot convert RegisteredCheckButton* to GtkToggleButton* .
It's because RegisteredCheckButton is not derived from GtkCheckButton. It is derived from Gtk::CheckButton (subtle difference!).
But, the RegisteredCheckButton already has a method to gray-out the box: void RegisteredCheckButton::setActive (bool b) Does that not do want you want?
Regards, Johan
On 24-9-2012 23:59, Johan Engelen wrote:
On 24-9-2012 13:16, Arshdeep Singh wrote:
Now I face a problem in editing the ' RegisteredCheckButton:<GtkWidget>CheckButton' class '
please be extra careful in typing class names in e-mails! This above does not make much sense actually :-)
I added a function 'void setGray(RegisteredChekcButton* ,bool b) to the class definition, obviously the declaration in the <registered-widget.h> and the definition in <registered-widget.cpp>
void setGray (RegisteredCheckButton* A , bool b) { gtk_toggle_set_active ( (GtkToggleButton*) A , !b); }
The object hierarchy shows that GtkCheckButton derives from GtkToggleButton, so this should work. This showed the error that you cannot convert RegisteredCheckButton* to GtkToggleButton* .
It's because RegisteredCheckButton is not derived from GtkCheckButton. It is derived from Gtk::CheckButton (subtle difference!).
But, the RegisteredCheckButton already has a method to gray-out the box: void RegisteredCheckButton::setActive (bool b) Does that not do want you want?
Err, sorry for the mistake. The setActive method makes the checkbox checked (or not), perhaps we should rename that.
To implement what you want, have a look at RegisteredCheckButton::setActive, because it shows how to forward the setting to its slave buttons. (You will have to write some if-statements: If the checkbutton is grayed-out, its slaves should be gray-out too. If the checkbutton is not grayed-out, its slaves should be grayed-out only if the checkbutton is not active, etc.) As setActive does with set_active(bool), you can simply call set_sensitive(bool) without any casts from within a method of RegisteredCheckButton to gray out the checkbutton.
Cheers, Johan
On Sep 24, 2012, at 4:16 AM, Arshdeep Singh wrote:
I think there are a few "big-picture" things that can help you in getting things in.
First and foremost is that you should stay aware that our code started as C and has slowly been migrating to C++. Also there is quite a lot of code that needs a few rounds of refactoring and cleanup. So don't be worried about questioning code you see in there, since there are good chances there is a lot that needs improving and shouldn't be just copied without at least some review.
Now I face a problem in editing the ' RegisteredCheckButton:<GtkWidget>CheckButton' class ' I added a function 'void setGray(RegisteredChekcButton* ,bool b) to the class definition, obviously the declaration in the <registered-widget.h> and the definition in <registered-widget.cpp>
void setGray (RegisteredCheckButton* A , bool b) { gtk_toggle_set_active ( (GtkToggleButton*) A , !b); }
We probably want to avoid function names using "gray", since that is a physical appearance of things. Instead we want to stay with more logical states.
One first reference we can use is the C-based GTK+ documentation. Looking at the hierarchy
http://developer.gnome.org/gtk/stable/GtkCheckButton.html#GtkCheckButton.obj...
you can see that it inherits from GtkTogleButton which in turn inherits from GtkButton, etc. Often working your way back up the hierarchy will reveal methods you might want to use.
(Keep in mind that we are using the C++ wrapper that would give Gtk::ToggleButton and Gtk::Button... but the C implementation is the main GTK+ library)
GtkToggleButton has functions to get and set "active". Gtk::ToggleButton has get_active() and set_active() methods. http://developer.gnome.org/gtk/stable/GtkToggleButton.html http://developer.gnome.org/gtkmm/stable/classGtk_1_1ToggleButton.html
Working our way all the way up to "Widget", we see settors and gettors for
"sensitive"
Looking at detail on that http://developer.gnome.org/gtk/stable/GtkWidget.html#gtk-widget-set-sensitiv...
Sets the sensitivity of a widget. A widget is sensitive if the user can interact with it. Insensitive widgets are "grayed out" and the user can't interact with them. Insensitive widgets are known as "inactive", "disabled", or "ghosted" in some other toolkits.
So for any widget we want to use "sensitive" instead of "gray". Additionally for toggle buttons such as check buttons or radio buttons we want to use "active" instead of "checked" or "pushed". Sticking with the logical meaning, not the physical presentation.
The object hierarchy shows that GtkCheckButton derives from GtkToggleButton, so this should work. This showed the error that you cannot convert RegisteredCheckButton* to GtkToggleButton* . So I switched
void setGray (RegisteredCheckButton* A , bool b) { gtk_widget_set_sensitive ( (GtkWidget*) A , !b); }
This compiled fine but nothing seems to happen now. This code should 'gray-out' the RegisteredCheckButton.
The next big-picture item is to try to avoid C-style casts. The bit of code that is "(GtkWidget*)" is actually fairly dangerous. In C++ first we have inheritance of classes that usually works with no casting at all. If you have a pointer to some class instance, you can pass it to a call of that takes a pointer to some parent class with no casting at all.
One dangerous aspect is that such casting can even corrupt your code. For example, the compiler will happily change a pointer to a constant string (such as char *ptr = "foo";) and pass it in as a GtkWidget class instance pointer. Avoiding those is good. The GTK+ library itself has an overall approach of providing macros that do the casting conversion while validating the pointers supplied. For example, this one could be
gtk_widget_set_sensitive( GTK_WIDGET(A) );
However keep in mind that this is more for C coding and we want to stick with C++ as much as we can (normally in our code we can just remove casts and the C++ compiler will do the right thing).
And as a final note, we try to avoid parameter names that are capitalized. (Also I personally dislike single-letter names and prefer ones that are a little more descriptive). http://inkscape.org/doc/coding_style.php
participants (3)
-
Arshdeep Singh
-
Johan Engelen
-
Jon Cruz