Find file History
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.


Glade and MyPaint

NOTE: we do not actually build our UI using Glade or GtkBuilder as of
2011-10-02, version 0.9.1+git, but we might one day for a number of different
reasons. Using a UI designer makes application UI design more democratic; since
it forces custom widget coding to be more modular and independently testable,
it's better for code robustness; if we were to construct the entire UI using
GtkBuilder it could well grant speed gains; using GtkBuilder may assist the
effort to migrate MyPaint to GTK 3; and finally the effort to glade-ify a
widget is fairly minimal for quite a large reward.

Vague Goals

It would be nice to have the UI coded in one or more big XML files that could
be independently edited and just have MyPaint load that, but since we have
quite a few custom widgets with lots of funky interactions which must often be
constructed together in Glade/Builder-unfriendly monolithic chunks, it's not
going to happen overnight. So let's treat this as a vague goal and migrate
towards it gradually.

Project Directory Structure

The subdirectory glade/ contains the Glade catalog, glade-specific icons for
widgets, and a script for running glade in the right way. To run glade with the
MyPaint catalog for testing, invoke

    $ glade/
    $ glade/ gui/

Making widgets compatible with Glade and GtkBuilder

Prior to glade3, it was possible to run the widget code inside glade itself via
gladepython; now we have to fake it. It's still possible to set up properties
which can be edited by glade in the catalog file, but they must be listed out
explicitly and associated with a type. That's probably enough, in all honesty.

Widgets must be constructable on demand by the GObject system. For PyGI, this
means declaring a __gtype_name__ inside the class (we just use the class's
name), and ensuring it can be constructed with no arguments.

Try to make the widget's module not depend on too much other stuff too:
minimize its imports list, and make sure loading order doesn't matter.

Widgets need to behave sensibly outside a full MyPaint application. Quite often
they're constructed with the gui.application.Application as the first
constructor argument: this can't happen for GObject-constructed instances, but
for now it's probably acceptable to expose a set_app() method on the object and
do the right thing if it wasn't called.

Monkeypatching and possibly the pythonic _observers stuff we use everywhere
might be better done with declared __gsignals__ instead, since those too can be
hooked up via GtkBuilder.