After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 134161 - get_widget_derived() alternative
get_widget_derived() alternative
Status: RESOLVED FIXED
Product: gtkmm
Classification: Bindings
Component: general
2.91.x
Other All
: Normal enhancement
: 3
Assigned To: gtkmm-forge
gtkmm-forge
Depends on:
Blocks:
 
 
Reported: 2004-02-11 23:14 UTC by palm
Modified: 2016-01-28 10:07 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
derived.cpp - Source for Gnome::Glade::Derived class (2.48 KB, text/plain)
2004-02-11 23:16 UTC, palm
  Details
derived.h - Header file for Gnome::Glade::Derived class (3.05 KB, text/plain)
2004-02-11 23:17 UTC, palm
  Details
DerivedExample.cpp - Source for simple Gnome::Glade::Derived example (1.84 KB, patch)
2004-02-11 23:18 UTC, palm
none Details | Review
DerivedExample.glade - Glade file for simple Gnome::Glade::Derived example (2.28 KB, text/plain)
2004-02-11 23:19 UTC, palm
  Details
Patch (13.28 KB, patch)
2005-05-15 15:53 UTC, Marek Materzok
none Details | Review
Gtk::BuilderWidgetLoader, simpler derived instantiation for Gtk::Builder (2.47 KB, patch)
2009-01-27 18:01 UTC, Milosz Derezynski
none Details | Review
Gnome::Glade::WidgetLoader, same thing but for libglademm (2.25 KB, patch)
2009-01-27 18:03 UTC, Milosz Derezynski
none Details | Review
Gtk::BuilderWidgetLoader and an example program. (3.58 KB, application/x-compressed-tar)
2011-12-01 09:58 UTC, Kjell Ahlstedt
  Details
Arbitrary constructor parameters with variadic templates (3.50 KB, patch)
2015-06-02 01:52 UTC, Armin Burgmeier
none Details | Review
Example program for create_widget_derived (1.60 KB, text/x-c++src)
2015-06-02 01:53 UTC, Armin Burgmeier
  Details

Description palm 2004-02-11 23:14:13 UTC
Here's an alternate way to implement derived widgets in libglademm, as
discussed here:

http://mail.gnome.org/archives/gtkmm-list/2003-October/msg00070.html
Comment 1 palm 2004-02-11 23:16:21 UTC
Created attachment 24326 [details]
derived.cpp - Source for Gnome::Glade::Derived class
Comment 2 palm 2004-02-11 23:17:07 UTC
Created attachment 24328 [details]
derived.h - Header file for Gnome::Glade::Derived class
Comment 3 palm 2004-02-11 23:18:12 UTC
Created attachment 24329 [details] [review]
DerivedExample.cpp - Source for simple Gnome::Glade::Derived example
Comment 4 palm 2004-02-11 23:19:08 UTC
Created attachment 24330 [details]
DerivedExample.glade - Glade file for simple Gnome::Glade::Derived example
Comment 5 palm 2004-02-11 23:31:42 UTC
Unfortunately, setting up all the prereqs for building the latest CVS
libglademm turned out to be much harder than I first thought.

As I lack the time to do that now, I'm attaching my source files
instead of a patch. Merging it should be extremely straightforward
anyway as no existing code is modified.

All suggestions for improvement that I have received since posting the
initial code have been included.

Please feel free to modify as desired.
Comment 6 Murray Cumming 2004-03-28 12:47:31 UTC
> setting up all the prereqs for building the latest CVS
libglademm

In future, I recommend jhbuild.
Comment 7 Marek Materzok 2005-05-15 15:53:15 UTC
Created attachment 46453 [details] [review]
Patch
Comment 8 Murray Cumming 2005-12-19 09:25:38 UTC
I've finally had the chance to look at the patch. It looks pretty good, and seems to work.

In summary, it lets you do this:

class HelloDialog : public Gnome::Glade::Derived<Gtk::Dialog>
{
public
  HelloDialog()
  : Gnome::Glade::Derived<Gtk::Dialog>("derivedclass.glade", "exampleDialog")
  {}
};

or

class HelloButton : public Gnome::Glade::Derived<Gtk::Button>
{
public
  HelloDialog(const Glib::RefPtr<Gnome::Glade::Xml>& xml)
  : Gnome::Glade::Derived<Gtk::Dialog>(xml, "exampleButton")
  {}
};

However, in almost all cases you would want the constructor to take a Glade::Xml, so you can do this:

class HelloDialog : public Gnome::Glade::Derived<Gtk::Dialog>
{
public
  HelloDialog()
  : Gnome::Glade::Derived<Gtk::Dialog>("derivedclass.glade", "exampleDialog"),
    m_button(get_xml(), "button")
  {}
};

So the only advantage to this method that I see is that it requires less code, and can be used in the initializer list. That's good though.

However, 
1. it uses the SomeWidget(cobject) constructor directly, without checking whether there is an existing instance that it should return (See ObjectBase::_get_current_wrapper() in the existing get_widget_derived()), so this would cause problems if two widgets were instantiated for the same item in the glade file.
2. It doesn't check whether the instantiated C widget is of the expected type. But that should be easy to add.

Comment 9 Tim Mayberry 2006-01-08 23:53:47 UTC
I like the look of this patch from a brief inspection but I was wondering whether it would make sense for those constructors that don't take a reference to a Gnome::Glade::Xml to also take another string argument representing the domain for I18N? As I remember the create*() methods used to create a Gnome::Glade::Xml reference take a string representing the translation domain, but if this constructor is used DerivedBase(const std::string& filename, const std::string& widgetname) there seems to be no way to specify the translation domain.
Comment 10 Murray Cumming 2006-01-09 08:46:58 UTC
> whether it would make sense for those constructors that don't take a reference
> to a Gnome::Glade::Xml to also take another string argument representing the
> domain for I18N

I guess we need to know when/if that is useful.
Comment 11 Tim Mayberry 2006-01-09 23:06:18 UTC
(In reply to comment #10)
> > whether it would make sense for those constructors that don't take a reference
> > to a Gnome::Glade::Xml to also take another string argument representing the
> > domain for I18N
> 
> I guess we need to know when/if that is useful.
> 

This might be able to sum it up better than I can http://developer.gnome.org/doc/API/libglade/libglade-i18n.html

So from my understanding it would be useful when you want to support I18N when the translation domain used to look up the translations is different from the default AND you want to use the version of the constructor that only takes a filename/widgetname(/domain) rather than the constructor that takes a Gnome::Glade::Xml reference.

As I've said above, it is still possible to specify the translation domain when creating the glade Xml reference and then using that in the Derived<T> constructor. I only brought it up because it seemed a little inconsistant, I don't see it as an issue.
 
Comment 12 Milosz Derezynski 2009-01-27 18:00:26 UTC
Ok so, Andre Gaul sent this patch to the list in 2007, which can be found here: http://mail.gnome.org/archives/gtkmm-list/2007-October/msg00074.html, which is way simpler than the one proposed here.

Hmm I just saw it does the same thing as the latest version here, but I guess that then doesn't make a difference. I've fixed the code up a little, and made a version for Gtk::Builder, see attached patches.

If someone could review the _get_current_wrapper() stuff please, that would be nice.
Comment 13 Milosz Derezynski 2009-01-27 18:01:47 UTC
Created attachment 127341 [details] [review]
Gtk::BuilderWidgetLoader, simpler derived instantiation for Gtk::Builder
Comment 14 Milosz Derezynski 2009-01-27 18:03:45 UTC
Created attachment 127342 [details] [review]
Gnome::Glade::WidgetLoader, same thing but for libglademm
Comment 15 Murray Cumming 2009-02-05 17:40:21 UTC
Could you show how this would be used in application code, please? Let's stick to libglademm for now, because that is what we are most familiar with.
Comment 16 Murray Cumming 2009-02-21 13:13:21 UTC
Please?
Comment 17 Murray Cumming 2009-03-04 22:39:23 UTC
Time is running out. There's a slim chance that this could be considered before the API freeze if you could reply.
Comment 18 Murray Cumming 2010-11-10 20:24:58 UTC
If you replied to comment #15 then maybe we could consider this for Gtk::Builder.
Comment 19 Kjell Ahlstedt 2011-12-01 09:58:57 UTC
Created attachment 202504 [details]
Gtk::BuilderWidgetLoader and an example program.

This is a rewritten version of Gtk::BuilderWidgetLoader from comment 13,
and a version of the example program gtkmm-documentation/examples/book/builder/
derived that uses Gtk::BuilderWidgetLoader instead of
Gtk::Builder::get_widget_derived().

If it's considered worth implementing, I can make two patches (one for gtkmm,
one for gtkmm-documentation). Then I will also have to add some text in the
Gtkmm tutorial, chapter Glade and Gtk::Builder, section Using derived widgets.
Comment 20 Kjell Ahlstedt 2011-12-01 14:31:37 UTC
The libglademm bug 303044 contains another idea that makes it possible to use
derived widgets with arbitrary constructors. I don't know if it's better or
worse than this one, or just different. That bug contains no example how to
use the new get_widget_derived() overload, suggested there.
Comment 21 Armin Burgmeier 2015-06-02 01:52:18 UTC
Created attachment 304399 [details] [review]
Arbitrary constructor parameters with variadic templates

Here is another way to add support for (mostly) arbitrary constructors, using C++11 variadic templates and std::forward. I called the function create_widget_derived since its semantics are slightly different compared to get_widget_derived in case a C++ wrapper exists already for the C instance. The new function always fails, while get_widget_derived returns the existing C++ instance if it is compatible.

I know there have been some discussions about using C++11 features in gtkmm. I don't know what the current status is, but I put this here in any case as an idea.
Comment 22 Armin Burgmeier 2015-06-02 01:53:13 UTC
Created attachment 304400 [details]
Example program for create_widget_derived

An example program that shows how create_widget_derived could be used.
Comment 23 Kjell Ahlstedt 2015-08-04 17:26:21 UTC
I vote for Armin's proposal with a variadic template. Gtkmm 3.18 will use C++11
features.

Some details need discussion:

- create_widget_derived() or get_widget_derived()? It's a mixture of getting and
  creating. It gets the underlying C widget from the GtkBuilder and creates a
  C++ wrapper for it. I have no clear preference for one name over the other.

- g_critical() or throw? In my code in comment 19, I use throw to report
  errors. A problem with throw is that there are no suitable error codes in
  Gtk::BuilderError. I use std::runtime_error, and that's not ideal. But code in
  glibmm can throw std::out_of_range, std::overflow_error and std::bad_cast, so
  I guess it's acceptible.
Comment 24 Kjell Ahlstedt 2016-01-28 10:06:50 UTC
With C++11 it's easy to make get_widget_derived() accept constructors with extra
parameters: Just make it a variadic template. No need for a separate
create_widget_derived(). get_widget_derived() can handle constructors both
with and without extra parameters. Since it was a template also before this
modification, it has not been part of the ABI.

Fixed with this commit:
https://git.gnome.org/browse/gtkmm/commit/?id=6e98903fc458c96fbf87b2080c9a06a0f221ead3