(proposal for) source code generator

View: New views
6 Messages — Rating Filter:   Alert me  

(proposal for) source code generator

by Amadeus W.M. :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I'm using gtkmm again after a break of about 1 1/2 years and I see some
things have changed. For one, I was building the gui with glade
(glade-2 to be precise), and then I would use glade-- to generate the
source code. I know, libglademm was the preferred method, but I preferred
glade-- because the code generated by glade-- already contained the
appropriate signal_connect() instructions. With libglademm I had to write
them myself. Anyway...

Now glade-- seems defunct, and despite my efforts to resuscitate it, I
can't repair it. So I have to byte the bullet and migrate to libglademm. I
tried some basic examples and it's not too bad, but it just crossed my
mind that one could write a code generator that uses libglademm.

To exemplify, suppose I have a trivial application with a top level window
with just a button in it that outputs "OK" to stdout when clicked. That's
the whole application. The gui part of the code for this would be as
follows:


class MainWindowGUI : public sigc::trackable
{

protected:

    Glib::RefPtr<Gnome::Glade::Xml> refXml;
    Gtk::Window * mainWindow;
    Gtk::Button * okButton;


    virtual bool on_mainWindow_key_press_event(GdkEventKey *ev) = 0;
    virtual void on_okButton_clicked() = 0;



public:

    MainWindowGUI(Glib::RefPtr<Gnome::Glade::Xml> refXml)
        : mainWindow(0), okButton(0) {
       
        // Get the main window.
        refXml->get_widget("mainWindow", mainWindow);
        if (!mainWindow)
            throw std::runtime_error("Couldn't find okButton in
ok2.glade");

        // Get the button.
        refXml->get_widget("okButton", okButton);
        if (!okButton)
            throw std::runtime_error("Couldn't find okButton in
ok2.glade");

        // Connect to signals.
        mainWindow->signal_key_press_event().connect(sigc::mem_fun(*this,
&MainWindowGUI::on_mainWindow_key_press_event),false);
        okButton->signal_clicked().connect(sigc::mem_fun(*this,
&MainWindowGUI::on_okButton_clicked));

    }
   

    Gtk::Window & getWindow() { return *mainWindow; }


};


In general, the MainWindowGUI class would contain a pointer to each widget
found in the .glade file and also pure virtual callbacks, again as
specified in the .glade file. The constructor would contain the
appropriate signal_connect() calls.

I don't know enough xml/xslt but I suspect this could be done by creating
an intelligent xslt file, say application.xsl, then generate the code with
an off-the-shelf xslt processor like so:

xsltproc application.xsl application.glade > MainWindowGUI.hh

Thus, one would not have to write massive amounts of code to parse the
xml .glade file and generate the C++ code from it. All that would need to
be written (not by me though) would be a one-time xslt file (transform).


Would this be feasible? Any xml experts willing to try this?

_______________________________________________
gtkmm-list mailing list
gtkmm-list@...
http://mail.gnome.org/mailman/listinfo/gtkmm-list

Re: (proposal for) source code generator

by Grischa Jacobs :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Amadeus W.M. wrote:
<...>
> To exemplify, suppose I have a trivial application with a top level window
> with just a button in it that outputs "OK" to stdout when clicked. That's
> the whole application. The gui part of the code for this would be as
> follows:
>
>
> class MainWindowGUI : public sigc::trackable
> {
<...>
> I don't know enough xml/xslt but I suspect this could be done by creating
> an intelligent xslt file, say application.xsl, then generate the code with
> an off-the-shelf xslt processor like so:
>
> xsltproc application.xsl application.glade > MainWindowGUI.hh
>
> Thus, one would not have to write massive amounts of code to parse the
> xml .glade file and generate the C++ code from it. All that would need to
> be written (not by me though) would be a one-time xslt file (transform).

We're too using glade--, despite the claim that a majority of the
developer would prefer libglade. Nice to see that I'm not the last of
its kind. Just two questions.

I was wondering whether Gtk::Builder would be worth to look at. Its the
proclaimed successor of libglade and seems to provide a similar
functionality.

And, while looking at the code, why would you derive MainWindowGUI from
sigc::trackable instead of Gtk::Window? While this could be easily
changed in the xsl file to fit everyones personal preference, I was just
wondering whether there is a specific reason.

> Would this be feasible? Any xml experts willing to try this?

_______________________________________________
gtkmm-list mailing list
gtkmm-list@...
http://mail.gnome.org/mailman/listinfo/gtkmm-list

Re: (proposal for) source code generator

by Amadeus W.M. :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Sat, 28 Jun 2008 14:32:02 +0200, Grischa Jacobs wrote:

> Amadeus W.M. wrote:
> <...>
>> To exemplify, suppose I have a trivial application with a top level
>> window with just a button in it that outputs "OK" to stdout when
>> clicked. That's the whole application. The gui part of the code for
>> this would be as follows:
>>
>>
>> class MainWindowGUI : public sigc::trackable {
> <...>
>> I don't know enough xml/xslt but I suspect this could be done by
>> creating an intelligent xslt file, say application.xsl, then generate
>> the code with an off-the-shelf xslt processor like so:
>>
>> xsltproc application.xsl application.glade > MainWindowGUI.hh
>>
>> Thus, one would not have to write massive amounts of code to parse the
>> xml .glade file and generate the C++ code from it. All that would need
>> to be written (not by me though) would be a one-time xslt file
>> (transform).
>
> We're too using glade--, despite the claim that a majority of the
> developer would prefer libglade. Nice to see that I'm not the last of
> its kind. Just two questions.
>
> I was wondering whether Gtk::Builder would be worth to look at. Its the
> proclaimed successor of libglade and seems to provide a similar
> functionality.
>
> And, while looking at the code, why would you derive MainWindowGUI from
> sigc::trackable instead of Gtk::Window? While this could be easily
> changed in the xsl file to fit everyones personal preference, I was just
> wondering whether there is a specific reason.
>
>> Would this be feasible? Any xml experts willing to try this?


Because the real main window comes out of refXml as a Gtk::Window *. That
(and not MainWindowGUI) is the window that contains all the widgets and
with all the properties you defined in glade. You don't have to pack the
child widgets, nor to set properties of the window in your code (like
glade-- does). I guess libglademm does that behind the scene when parsing
the .glade file. Someone correct me if I'm wrong. At least the code I
posted shows you don't have to pack the child widgets.

Of course, you can derive MainWindowGUI from Gtk::Window, but it's not
going to be the main window. To use the main window you still need to get
it via refXml.


_______________________________________________
gtkmm-list mailing list
gtkmm-list@...
http://mail.gnome.org/mailman/listinfo/gtkmm-list

Re: (proposal for) source code generator

by Grischa Jacobs :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Amadeus W.M. wrote:
<...>

>>> Would this be feasible? Any xml experts willing to try this?
>
>
> Because the real main window comes out of refXml as a Gtk::Window *. That
> (and not MainWindowGUI) is the window that contains all the widgets and
> with all the properties you defined in glade. You don't have to pack the
> child widgets, nor to set properties of the window in your code (like
> glade-- does). I guess libglademm does that behind the scene when parsing
> the .glade file. Someone correct me if I'm wrong. At least the code I
> posted shows you don't have to pack the child widgets.
>
> Of course, you can derive MainWindowGUI from Gtk::Window, but it's not
> going to be the main window. To use the main window you still need to get
> it via refXml.
Just a proof of concept - test.xslt can be used together with a
glade-file to generate the skeleton code. Might even compile...

> gtkmm-list mailing list
> gtkmm-list@...
> http://mail.gnome.org/mailman/listinfo/gtkmm-list


#include "simple.h"

#include <libglademm/xml.h>

#include <gtkmm/main.h>
#include <gtkmm/window.h>

#include <cstdlib>


int main(int argc, char * argv[])
{
#if defined(ENABLE_NLS)
        bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
        bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
        textdomain (GETTEXT_PACKAGE);
#endif //ENABLE_NLS

        Gtk::Main m(argc, argv);

        Glib::RefPtr<Gnome::Glade::Xml> interface = Gnome::Glade::Xml::create("simple.glade");

        MainWindow * window;

        interface->get_widget_derived("MainWindow", window);

        if( window )
        {
                m.run(*window);
        }

        return EXIT_SUCCESS;
}




#ifndef __XSLT_GLADE_CODE_H__
#define __XSLT_GLADE_CODE_H__

#include <libglademm/xml.h>

#include <gtkmm/box.h>
#include <gtkmm/button.h>
#include <gtkmm/fixed.h>
#include <gtkmm/menu.h>
#include <gtkmm/menubar.h>
#include <gtkmm/statusbar.h>
#include <gtkmm/window.h>



class MainWindow : public Gtk::Window
{
public:
        /// Constructor
        MainWindow(BaseObjectType * cobject, const Glib::RefPtr <Gnome::Glade::Xml> & ref_glade) : Gtk::Window(cobject)
        {
                m_vbox1 = dynamic_cast<Gtk::VBox*>(ref_glade->get_widget("vbox1"));
                m_menubar1 = dynamic_cast<Gtk::MenuBar*>(ref_glade->get_widget("menubar1"));
                m_menuitem1 = dynamic_cast<Gtk::MenuItem*>(ref_glade->get_widget("menuitem1"));
                m_menu1 = dynamic_cast<Gtk::Menu*>(ref_glade->get_widget("menu1"));
                m_imagemenuitem1 = dynamic_cast<Gtk::ImageMenuItem*>(ref_glade->get_widget("imagemenuitem1"));
                m_imagemenuitem2 = dynamic_cast<Gtk::ImageMenuItem*>(ref_glade->get_widget("imagemenuitem2"));
                m_imagemenuitem3 = dynamic_cast<Gtk::ImageMenuItem*>(ref_glade->get_widget("imagemenuitem3"));
                m_imagemenuitem4 = dynamic_cast<Gtk::ImageMenuItem*>(ref_glade->get_widget("imagemenuitem4"));
                m_separatormenuitem1 = dynamic_cast<Gtk::SeparatorMenuItem*>(ref_glade->get_widget("separatormenuitem1"));
                m_imagemenuitem5 = dynamic_cast<Gtk::ImageMenuItem*>(ref_glade->get_widget("imagemenuitem5"));
                m_menuitem2 = dynamic_cast<Gtk::MenuItem*>(ref_glade->get_widget("menuitem2"));
                m_menu2 = dynamic_cast<Gtk::Menu*>(ref_glade->get_widget("menu2"));
                m_imagemenuitem6 = dynamic_cast<Gtk::ImageMenuItem*>(ref_glade->get_widget("imagemenuitem6"));
                m_imagemenuitem7 = dynamic_cast<Gtk::ImageMenuItem*>(ref_glade->get_widget("imagemenuitem7"));
                m_imagemenuitem8 = dynamic_cast<Gtk::ImageMenuItem*>(ref_glade->get_widget("imagemenuitem8"));
                m_imagemenuitem9 = dynamic_cast<Gtk::ImageMenuItem*>(ref_glade->get_widget("imagemenuitem9"));
                m_menuitem3 = dynamic_cast<Gtk::MenuItem*>(ref_glade->get_widget("menuitem3"));
                m_menuitem4 = dynamic_cast<Gtk::MenuItem*>(ref_glade->get_widget("menuitem4"));
                m_menu3 = dynamic_cast<Gtk::Menu*>(ref_glade->get_widget("menu3"));
                m_imagemenuitem10 = dynamic_cast<Gtk::ImageMenuItem*>(ref_glade->get_widget("imagemenuitem10"));
                m_fixed1 = dynamic_cast<Gtk::Fixed*>(ref_glade->get_widget("fixed1"));
                m_TestButton = dynamic_cast<Gtk::Button*>(ref_glade->get_widget("TestButton"));
                m_statusbar1 = dynamic_cast<Gtk::Statusbar*>(ref_glade->get_widget("statusbar1"));
        }

protected:
        Gtk::VBox * m_vbox1;
        Gtk::MenuBar * m_menubar1;
        Gtk::MenuItem * m_menuitem1;
        Gtk::Menu * m_menu1;
        Gtk::ImageMenuItem * m_imagemenuitem1;
        Gtk::ImageMenuItem * m_imagemenuitem2;
        Gtk::ImageMenuItem * m_imagemenuitem3;
        Gtk::ImageMenuItem * m_imagemenuitem4;
        Gtk::SeparatorMenuItem * m_separatormenuitem1;
        Gtk::ImageMenuItem * m_imagemenuitem5;
        Gtk::MenuItem * m_menuitem2;
        Gtk::Menu * m_menu2;
        Gtk::ImageMenuItem * m_imagemenuitem6;
        Gtk::ImageMenuItem * m_imagemenuitem7;
        Gtk::ImageMenuItem * m_imagemenuitem8;
        Gtk::ImageMenuItem * m_imagemenuitem9;
        Gtk::MenuItem * m_menuitem3;
        Gtk::MenuItem * m_menuitem4;
        Gtk::Menu * m_menu3;
        Gtk::ImageMenuItem * m_imagemenuitem10;
        Gtk::Fixed * m_fixed1;
        Gtk::Button * m_TestButton;
        Gtk::Statusbar * m_statusbar1;
       
};



#endif // __XSLT_GLADE_CODE_H__


_______________________________________________
gtkmm-list mailing list
gtkmm-list@...
http://mail.gnome.org/mailman/listinfo/gtkmm-list

simple.glade (11K) Download Attachment
test.xslt (3K) Download Attachment

Re: (proposal for) source code generator

by Amadeus W.M. :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I didn't get the attachment because I'm reading this mailing list via
gmane. Could you please email the xslt file to me personally? Thanks!
We can then work on it. This might actually come alive!

Thanks!


> Just a proof of concept - test.xslt can be used together with a
> glade-file to generate the skeleton code. Might even compile...
>
>> gtkmm-list mailing list
>> gtkmm-list@...
>> http://mail.gnome.org/mailman/listinfo/gtkmm-list
>
> #include "simple.h"
>
> #include <libglademm/xml.h>
>
> #include <gtkmm/main.h>
> #include <gtkmm/window.h>
>
> #include <cstdlib>
>
>
> int main(int argc, char * argv[])
> {
> #if defined(ENABLE_NLS)
> bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
> bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8"); textdomain
> (GETTEXT_PACKAGE);
> #endif //ENABLE_NLS
>
> Gtk::Main m(argc, argv);
>
> Glib::RefPtr<Gnome::Glade::Xml> interface =
> Gnome::Glade::Xml::create("simple.glade");
>
> MainWindow * window;
>
> interface->get_widget_derived("MainWindow", window);
>
> if( window )
> {
> m.run(*window);
> }
>
> return EXIT_SUCCESS;
> }
>
>
> #ifndef __XSLT_GLADE_CODE_H__
> #define __XSLT_GLADE_CODE_H__
>
> #include <libglademm/xml.h>
>
> #include <gtkmm/box.h>
> #include <gtkmm/button.h>
> #include <gtkmm/fixed.h>
> #include <gtkmm/menu.h>
> #include <gtkmm/menubar.h>
> #include <gtkmm/statusbar.h>
> #include <gtkmm/window.h>
>
>
>
> class MainWindow : public Gtk::Window {
> public:
> /// Constructor
> MainWindow(BaseObjectType * cobject, const Glib::RefPtr
> <Gnome::Glade::Xml> & ref_glade) : Gtk::Window(cobject) {
> m_vbox1 = dynamic_cast<Gtk::VBox*>(ref_glade->get_widget
("vbox1"));
> m_menubar1 =
> dynamic_cast<Gtk::MenuBar*>(ref_glade->get_widget
("menubar1"));
> m_menuitem1 =
> dynamic_cast<Gtk::MenuItem*>(ref_glade->get_widget
("menuitem1"));
> m_menu1 = dynamic_cast<Gtk::Menu*>(ref_glade->get_widget
("menu1"));
> m_imagemenuitem1 =
> dynamic_cast<Gtk::ImageMenuItem*>(ref_glade->get_widget
("imagemenuitem1"));
> m_imagemenuitem2 =
> dynamic_cast<Gtk::ImageMenuItem*>(ref_glade->get_widget
("imagemenuitem2"));
> m_imagemenuitem3 =
> dynamic_cast<Gtk::ImageMenuItem*>(ref_glade->get_widget
("imagemenuitem3"));
> m_imagemenuitem4 =
> dynamic_cast<Gtk::ImageMenuItem*>(ref_glade->get_widget
("imagemenuitem4"));
> m_separatormenuitem1 =
> dynamic_cast<Gtk::SeparatorMenuItem*>(ref_glade->get_widget
("separatormenuitem1"));
> m_imagemenuitem5 =
> dynamic_cast<Gtk::ImageMenuItem*>(ref_glade->get_widget
("imagemenuitem5"));
> m_menuitem2 =
> dynamic_cast<Gtk::MenuItem*>(ref_glade->get_widget
("menuitem2"));
> m_menu2 = dynamic_cast<Gtk::Menu*>(ref_glade->get_widget
("menu2"));
> m_imagemenuitem6 =
> dynamic_cast<Gtk::ImageMenuItem*>(ref_glade->get_widget
("imagemenuitem6"));
> m_imagemenuitem7 =
> dynamic_cast<Gtk::ImageMenuItem*>(ref_glade->get_widget
("imagemenuitem7"));
> m_imagemenuitem8 =
> dynamic_cast<Gtk::ImageMenuItem*>(ref_glade->get_widget
("imagemenuitem8"));
> m_imagemenuitem9 =
> dynamic_cast<Gtk::ImageMenuItem*>(ref_glade->get_widget
("imagemenuitem9"));
> m_menuitem3 =
> dynamic_cast<Gtk::MenuItem*>(ref_glade->get_widget
("menuitem3"));
> m_menuitem4 =
> dynamic_cast<Gtk::MenuItem*>(ref_glade->get_widget
("menuitem4"));
> m_menu3 = dynamic_cast<Gtk::Menu*>(ref_glade->get_widget
("menu3"));
> m_imagemenuitem10 =
> dynamic_cast<Gtk::ImageMenuItem*>(ref_glade->get_widget
("imagemenuitem10"));
> m_fixed1 = dynamic_cast<Gtk::Fixed*>(ref_glade->get_widget
("fixed1"));
> m_TestButton =
> dynamic_cast<Gtk::Button*>(ref_glade->get_widget
("TestButton"));
> m_statusbar1 =
> dynamic_cast<Gtk::Statusbar*>(ref_glade->get_widget
("statusbar1"));

> }
>
> protected:
> Gtk::VBox * m_vbox1;
> Gtk::MenuBar * m_menubar1;
> Gtk::MenuItem * m_menuitem1;
> Gtk::Menu * m_menu1;
> Gtk::ImageMenuItem * m_imagemenuitem1; Gtk::ImageMenuItem *
> m_imagemenuitem2; Gtk::ImageMenuItem * m_imagemenuitem3;
> Gtk::ImageMenuItem * m_imagemenuitem4; Gtk::SeparatorMenuItem *
> m_separatormenuitem1; Gtk::ImageMenuItem * m_imagemenuitem5;
> Gtk::MenuItem * m_menuitem2;
> Gtk::Menu * m_menu2;
> Gtk::ImageMenuItem * m_imagemenuitem6; Gtk::ImageMenuItem *
> m_imagemenuitem7; Gtk::ImageMenuItem * m_imagemenuitem8;
> Gtk::ImageMenuItem * m_imagemenuitem9; Gtk::MenuItem * m_menuitem3;
> Gtk::MenuItem * m_menuitem4;
> Gtk::Menu * m_menu3;
> Gtk::ImageMenuItem * m_imagemenuitem10; Gtk::Fixed * m_fixed1;
> Gtk::Button * m_TestButton;
> Gtk::Statusbar * m_statusbar1;
>
> };
>
>
>
> #endif // __XSLT_GLADE_CODE_H__
> _______________________________________________ gtkmm-list mailing list
> gtkmm-list@...
> http://mail.gnome.org/mailman/listinfo/gtkmm-list

_______________________________________________
gtkmm-list mailing list
gtkmm-list@...
http://mail.gnome.org/mailman/listinfo/gtkmm-list

Re: (proposal for) source code generator

by Grischa Jacobs :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Amadeus W.M. wrote:
> I didn't get the attachment because I'm reading this mailing list via
> gmane. Could you please email the xslt file to me personally? Thanks!
> We can then work on it. This might actually come alive!

That's how signals might work. Can't tell though how much effort it
takes to add all the non-default (void/void) handlers.

> Thanks!

Grischa Jacobs


_______________________________________________
gtkmm-list mailing list
gtkmm-list@...
http://mail.gnome.org/mailman/listinfo/gtkmm-list

simple.xslt (4K) Download Attachment