<?xml version="1.0"?>
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" 
  "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
  <!ENTITY date "February 2002">
]>

<article id="GUADEC" lang="en">
<!-- $Id: template.xml,v 1.1 2002/01/13 23:59:12 jaime Exp $ -->
  <artheader>
    <title>gtkmm2 - GNOME2 with C++</title>
    <author>
      <firstname>Murray</firstname>
      <surname>Cumming</surname>
      <affiliation>
	      <address><email>murrayc@usa.net</email></address>
      </affiliation>
    </author>
    <date>15th January 2002</date>
    <abstract>
      <para>There will be two parts.</para>
      <para>The first part will be an introduction to GTK+'s C++ bindings for newcomers. The advantages of gtkmmm will be demonstrated with simple examples. For instance, API-clarity, inheritance, encapsulation, type-safety, and use of the C++ standard library. There will be a brief comparison with QT.</para>
      <para>The second part will detail the most important differences between gtkmm 1.2 and the new gtkmm 2.0, for those who already use gtkmm. For instance, the new RefPtr for reference-counted resources, the new UTF8 string class, the signal accessors, properties, the new main window concept.</para>
    </abstract>
  </artheader>
  <para>TODO: This is an early draft - It needs some filling out, and maybe some thinning out.</para>
  <sect1 id="section-gtkmm-for-newcomers">
    <title>gtkmm for newcomers</title>

    <sect2>
      <title>Advantages of gtkmmm</title>
     <para> will be demonstrated with simple examples. For instance, API-clarity, inheritance, encapsulation, type-safety, and use of the C++ standard library.</para>
<orderedlist>
<listitem><para>gtkmm allows you to write code using normal C++ techniques such as encapsulation, derivation, and polymorphism. As a C++ programmer you probably already realise that this leads to clearer and better organised code.</para></listitem>
<listitem><para>gtkmm is more type-safe, so the compiler can detect errors that would only be detected at run time when using C. This use of specific types also makes the API clearer because you can see what types should be used just by looking at a method's declaration.</para></listitem>
<listitem><para>Inheritance can be used to derive new widgets. The derivation of new widgets in GTK+ C code is so complicated and error prone that almost no C coders do it. As a C++ developer you know that derivation is an essential Object Orientated technique.</para></listitem>
<listitem><para>Member instances can be used, simplifying memory management. All GTK+ C widgets are dealt with by use of pointers. As a C++ coder you know that pointers should be avoided where possible.</para></listitem>
<listitem><para>Less code. The GTK+ C object model uses prefixed function names and cast macros. For instance:</para>
<programlisting>gtk_button_set_text(GTK_BUTTON(button), "sometext");</programlisting>
<para>gtkmm C++ code is shorter and clearer. For instance:</para>
<programlisting>button.set_text("sometext");</programlisting></listitem>
<listitem><para>There's no need to worry about GTK+'s inconsistent reference-counting policy.</para></listitem>
</orderedlist>
    </sect2>
    
    <sect2>
      <title>Helloworld in gtkmm</title>
      <para>
<programlisting>
#include &lt;gtkmm/button.h&gt;
#include &lt;gtkmm/main.h&gt;
#include &lt;gtkmm/window.h&gt;
#include &lt;iostream&gt;

class HelloWorld : public Gtk::Window
{
public:
  HelloWorld();
  virtual ~HelloWorld();
  
protected:
  //Signal handlers:
  virtual void on_button_clicked();

  //Member widgets:
  Gtk::Button m_button;
};


HelloWorld::HelloWorld()
:  m_button("Hello World")   // creates a new button with the label "Hello World".
{
  // Sets the border width of the window.
  set_border_width(10);
          
  // When the button receives the "clicked" signal, it will call the
  // hello() method. The hello() method is defined below.
  m_button.signal_clicked().connect(SigC::slot(this, &amp;HelloWorld::on_button_clicked));

  // This packs the button into the Window (a container).
  add(m_button);

  // The final step is to display this newly created widget...
  m_button.show();
}

HelloWorld::~HelloWorld
{
}

void HelloWorld::on_button_clicked()
{
  std::cout &lt;&lt; "Hello World" &lt;&lt; std::endl;
}
 
int main (int argc, char *argv[])
{
  Gtk::Main kit(argc, argv);

  HelloWorld helloworld;
  kit.run(helloworld); //Shows the window and returns when it is closed.

  return 0;
}
</programlisting>
</para>

    </sect2>

    <sect2>
      <title>Brief comparison with QT</title>
 <para>QT originates from a time when C++ was not standardised or well supported by compilers. Its design today is still based upon the choices available at that time, so it does not play well with more up-to-date code. Development of QT is still effectively closed - There is still no public development mailing list, and TrollTech have the normal corporate conservatism. As an open-source project, its design would have been improved through public debate, and it would have been possible to jettison the baggage.</para>
    <para>QT duplicates a lot of stuff that is now in the standard library, such as containers and type information. Most significantly, they modified the C++ language to provide signals, so that it's difficult to use QT classes with non-QT classes. gtkmm was able to use standard C++ to provide signals without changing the C++ language. And we use of Standard C++ Library containers such as std::string, std::list, std::vector and their iterators. We even provide STL-style interfaces to other things such as container children, allowing you to use iterators and push_back(), etc with these.</para>
    <para>With gtkmm normal C++ memory management can be used. QT demands that all widgets are dealt with as pointers, and that deletion of widgets is surrendered to parent widgets.</para>

<para>Here's a summary of those differences.
<table>
  <title>Comparison table</title>
  <tgroup cols="3">
  <thead>
    <row><entry></entry><entry>gtkmm</entry><entry>QT</entry></row>
  </thead>
  <tbody>
  <row><entry>signals</entry><entry>pure C++</entry><entry>moc extends C++ language</entry></row>
  <row><entry>containers</entry><entry>pure C++</entry><entry>QT-specific containers</entry></row>
  <row><entry>memory management</entry><entry>normal C++ choices</entry><entry>pointers only, and you can new, but you shouldn't delete</entry></row>
  <row><entry>GNOME classes</entry><entry>Yes</entry><entry>No</entry></row>
  <row><entry>Widget arrangement</entry><entry>Choice of containers</entry><entry>Containers and Layout classes are separate. Children must be added to both.</entry></row>
  </tbody>
  </tgroup>
</table>
We think that gtkmm makes your code clearer and more consistent. We think it gives you less to learn and less to worry about.</para>
    </sect2>

  </sect1>

  <sect1 id="section-gtkmm2">
    <title>What's new with gtkmm2</title>
     
    <sect2>
      <title>Glib::ustring</title>
      <para>glib::ustring has much the same interface as std::string, but contains UTF8 strings. Note that a normal ANSI string is also a UTF8 string, so, if you want to, you can use this class without every thinking about UTF8.</para>
      <para>Also, this class has conversions to and from std::string, so you can use a std::string instead of a glib::ustring - However, this will not work with multi-byte translations, just as normal C char* code wouldn't.</para>
      <para>In a perfect world the C++ Standard Library would contain a a UTF8 string, but it doesn't.</para> 
    </sect2>

    <sect2>
      <title>The main window concept</title>
      <para>In gtkmm 1.2 you had to worry about the Window's delete_event signal to make your application quit properly. If you didn't or if you got it wrong then your Window would self-destruct and cause a segfault. This was tedious and difficult, and nobody really understood it.</para>
      <para>We've made life simpler by preventing Window from self-destructing, and adding the Gtk::Main::run(window) override. It shows the window, starts the event loop, and stops the event loop when the window is closed. You can think of it as a way to say 'This is the main application window.' or 'The window and the application have the same lifetime.'</para>
    </sect2>

    <sect2>
      <title>Glib::RefPtr&lt;&gt;</title>
      <para>Most of the GDK objects are now based on GObject, so we now have auto-generated classes for them. However, GObject is a bit stricter than GtkObject about how we can manage its memory. We can only unref() a GObject, we can never destroy it. Therefore our C++ wrapper (which
is used by the C GObject) must remain alive as long as the C instance. But of course it should be deleted when glib tells us that the C instance has died.</para>
      <para>Of course you don't want to worry about all that, so we've created the RefPtr&lt;&gt; smartpointer which does all that for you. Objects such as Gdk::Bitmap can now only be instantiated with a create() function. For instance,
<programlisting>
Glib::RefPtr&lt;Gdk::Bitmap&gt; bitmap = Gdk::Bitmap::create(window, data, width, height);
</programlisting>
</para>
      <para>You have no way of getting a bare Gdk::Bitmap. bitmap is then a smart pointer, so you can do this, much like a normal
pointer:
<programlisting>
if(bitmap)
{
  int depth = bitmap->get_depth().
}
</programlisting>
</para>
<para>
When bitmap goes out of scope an unref() will happen in the background and you
don't need to worry about it anymore.
</para>
       <para>This should mean that you *never* need to ref()/unref() a Gdk
object again. GTK+ is a little inconsistent about it's refcounting, though there
are a loose set of rules. All gtkmm methods do any extra referencing for you, so
you don't need to worry about that.</para>
    </sect2>

    <sect2>
      <title>Signals</title>
      <para>signals are now prefixed by signal_, and accessible via accessors. For instance,</para>
<para>
gtkmm 1.2:
<programlisting>button.clicked.connect(SigC::slot(this, &amp;Something::somemethod));</programlisting>
gtkmm 2:
<programlisting> button.signal_clicked().connect(SigC::slot(*this, &amp;Something::somemethod));</programlisting>
</para>
    </sect2>

    <sect2>
      <title>Properties</title>
      <para>GTK+ properties can be used like so:
<programlisting>
someobject.property_something().set_value(2);
int value = someobject.property_something().get_value();
</programlisting>
</para>
<para>Properties are rarely used, but they do seem to be necessary for Gtk::TextView.</para>
    </sect2>
    <sect2>
      <title>Miscellaneous</title>
      <itemizedlist>
        <listitem><para>Include "gtkmm/something.h" instead of "gtk--/something.h"</para></listitem>
        <listitem><para>Methods and classes that are now deprecated in GTK+ 2.0 are not wrapped in gtkmm 2.0</para></listitem>
        <listitem><para>The GDK wrappers are now auto-generated and are in the Gdk namespace.</para></listitem>
        <listitem><para>Default signal handlers were previously suffixed with _impl - for instance, Button::clicked_impl(). Now that they are prefixed with on_ - for instance, Button::on_clicked() - it's easier to see that they are signal handlers that are worth to overriding in derived classes.</para></listitem>
        <listitem><para>Signal handlers now use C++ types, just like other C++ methods.</para></listitem>
       <listitem><para>namespaced enums.</para></listitem>
      </itemizedlist>
    </sect2>

    <sect2>
      <title>Implementation Changes</title>
      <itemizedlist>
        <listitem><para>Much clearer, better documented, more maintainable code-generating code</para></listitem>
        <listitem><para>Use of GTK+'s .defs C interface-definition format, parsed by perl.</para></listitem>
        <listitem><para>Separate .hg/.ccg files parsed by perl.</para></listitem>
        <listitem><para>Wrappers for GObject, GtkObject, and Boxed Types.</para></listitem>
      </itemizedlist>
    </sect2>

  </sect1>

  <sect1 id="section-further-information">
    <title>Further Information</title>
    <para>More information is available at gtkmm.sourceforge.net, including an FAQ, a tutorial, and reference documentation. We are happy to answer your questions on gtkmm-main@lists.sourceforge.net.</para> 
  </sect1>


</article>
