Another way to create derived widgets from glade



Hi!

The libglademm way (get_widget_derived()) of creating derived widget
instances doesn't allow to use arbitrary constructors. The derived
widget's constructor has to look like that:

DerivedDialog::DerivedDialog(BaseObjectType* cobject, const
Glib::RefPtr<Gnome::Glade::Xml>& refGlade)
: Gtk::Dialog(cobject)
{ }

There was some discussion on the mailing list, but I could not find a
good working solution. So I looked at some code proposals (especially
this one: http://bugzilla.gnome.org/show_bug.cgi?id=134161) and tried to
improve it.

I managed to get a working solution and would love to hear some comments
or possible improvements. The code together with an example is attached.
(I don't know if attachments work on this mailing list, so I uploaded
the code here, too:
http://web-yard.de/user/public/gaul web-yard de/widgetloader.tar.bz2 ).

The code works for me and made my life easier (less code and more c++
feeling), but I don't know if it's correct and usable for someone else.

Thanks for responses!

Ciao,
André Gaul

Attachment: example.glade
Description: application/glade

/*
* Copyright (C) 2007 André Gaul <gaul web-yard de>
* 
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* 
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
* 
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*
*/

#include <gtkmm/main.h>
#include "example_mydialog.h"

using namespace Gnome::Glade;


int main(int argc, char **argv) {
	Gtk::Main gtk_main(argc, argv);
	Glib::RefPtr<Xml> refxml=Xml::create("example.glade");
	MyDialog mydialog(refxml, "don't forget to check your console output!");
	gtk_main.run(mydialog);
	return 0;
}
/*
* Copyright (C) 2007 André Gaul <gaul web-yard de>
* 
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* 
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
* 
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*
*/

#ifndef __example_mydialog_include__
#define __example_mydialog_include__

#include <gtkmm/dialog.h>
#include <gtkmm/button.h>
#include <gtkmm/entry.h>
#include <iostream>
#include "widgetloader.h"

using namespace Gnome::Glade;

/*
 * MyDialog - a dialog that prints content of a Gtk::Entry box
 * to console.
 */
class MyDialog : public WidgetLoader<Gtk::Dialog> {
public:
	MyDialog (const Glib::RefPtr<Xml>& refxml, const Glib::ustring& text) : 
		WidgetLoader<Gtk::Dialog> (refxml, "MyDialog"),
		button(refxml, "MyDialogButton"),
		entry(refxml, "MyDialogEntry")
	{
		button.signal_clicked().connect(sigc::mem_fun(*this,&MyDialog::button_clicked));
		entry.set_text(text);
	};
private:
	WidgetLoader<Gtk::Button> button;
	WidgetLoader<Gtk::Entry> entry;

	void button_clicked() {
		std::cout << entry.get_text() << std::endl;
	};
};

#endif
all: example

example: example_main.cc example_mydialog.h widgetloader.h
	g++ `pkg-config --cflags libglademm-2.4` `pkg-config --libs libglademm-2.4` example_main.cc -o example

clean: 
	rm -f example
/*
* Copyright (C) 2007 André Gaul <gaul web-yard de>
* 
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* 
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
* 
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*
*/

#ifndef __widgetloader_include__
#define __widgetloader_include__

#include <libglademm/xml.h>
#include <glade/glade-xml.h>

namespace Gnome {
namespace Glade {


/*
* WidgetLoader template class
*/
template <class T_WIDGET> class WidgetLoader : public T_WIDGET {
public:
	/*
	* constructor takes a RefPtr<Xml> to the glade data
	* and the glade name of the widget (of type T_WIDGET) 
	* to load.
	*/
	WidgetLoader(const Glib::RefPtr<Xml>& refxml, const Glib::ustring& widgetname) : 
		/*
		* with help of get_widget the underlying
		* T_WIDGET class is initialized 
		*/
		T_WIDGET( get_widget(refxml, widgetname))
	{};
private:
	typedef typename T_WIDGET::BaseObjectType widget_type;

	/*
	* static helper function
	* returns pointer to GtkWidget object
	* (if widgetname exists in glade xml)
	*/
	static widget_type *get_widget(const Glib::RefPtr<Xml>& _refxml, 
			const Glib::ustring& widgetname) 
	{
		//get pointer from glade 
		widget_type *base_widget = (widget_type *)glade_xml_get_widget(
				_refxml->gobj(), widgetname.c_str() );
		if (!base_widget) 
			throw XmlError("Base widget \"" + widgetname +
					"not found in glade file \"" +
					_refxml->get_filename() + "\".");
		//check reference count
		Glib::ObjectBase *object_base = Glib::ObjectBase::_get_current_wrapper( 
				(GObject*) base_widget );
		if (object_base) {
			throw XmlError("oject already exists.");
		} else {
			Glib::RefPtr<Xml> refThis(_refxml);
			//increase reference count
			refThis->reference(); 
		}
		return base_widget;
	};
};

}
}

#endif


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