Monet – A Widget Drawing API

I’ve been quietly working in my spare time on a new project, called Monet. The aim is to provide a cross-toolkit widget drawing API and theming architecture. This would allow different toolkits to use the same code to draw their widgets, thus producing a more consistent look and feel across applications. The other motivator is to improve the theming abilities provided by existing toolkits and applications. The main target is to improve GTK+ theming opportunities, but I am also considering extending this beyond traditional widget theming, especially as GTK+ may have client side window decoration support soon.

Following on from the discussions at the theme hackfest last year, with extra input from Benjamin Berg (current maintainer of the gtk-engines package) and other Gnome artists and designers, we’ve created a new widget drawing API, drawing on ideas used in existing toolkits such as GTK+, Qt and Windows.

The main concepts behind the design are fairly simple. Each widget is represented by an object that encapsulates all the information necessary to draw it. This can include geometry, context, state, colours, and other properties such as text. For example, the Button class includes text, background and border colours, as well as certain flags such as whether the button is focused. This information is passed to the theme drawing API (the “theme engine”) with a cairo context, onto which the button will be drawn. More complex widgets are split into sub-elements and passed to the theme engine as a group. More exotic widgets such as window frames could also be added as part of this API. The advantages of using objects to define each widget’s drawing parameters is that they can be sub-classed and provide well documented properties.

Since the drawing API is defined as an abstract class, it is still possible to write new themes in code, just as they are done now in GTK+. However, I would like to include a theme engine that allows artists and theme authors to write new themes without requiring a compiler and even provide GUI tools for creating themes. There are several possible solutions to this:

Using an existing specification such as CSS seems attractive, but on closer inspection it is clear that CSS is not suitable for widget drawing without using images or custom extensions. As author of the Moblin toolkit, which uses CSS exclusively for styling, I have experienced first hand its short comings when it is applied to a widget scene graph, rather than an HTML document. There are several unapparent problems that arise, such as the lack of class hierarchy matching*.

SVG might be an alternative solution, but again there are problems that can only be solved with custom attributes and renderers. These would need to include the ability to keep constant stroke widths and corner radii when scaling. This would necessitate both custom editors and renderers.

Another possibility would be to use a custom scripting language such as Lua or even Javascript. The drawing API could be exposed to appropriate objects in these languages and cairo used directly. However, I would expect concerns about performance and efficiency, not to mention that writing a wysiwyg editor would be near impossible.

Finally, a custom XML format was suggested as a possibility (in fact, by a designer, no less). Personally, I don’t think anyone should have to write XML to create a theme, but luckily it would be trivial to write a custom editor for this type of theme. It also would have the advantage that it is not bound to any existing but ever-so-slightly different use case. It would also be trivial to expose the cairo API in such a format. Metacity also has a drawing API defined in XML and this could be used as a starting point (although, a much simpler schema could be achieved since less geometry needs to be specified).

I would be interested to hear any further thoughts on alternative theme formats.

I have started prototyping these ideas in a git repository on git.gnome.org, under the Monet project. Since the API includes an object for each widget type, I have experimented with implementing this to some success using Vala. The abstract base classes are available, as are classes for simple widgets. There is also an implementation of a GTK+ engine in Vala, which would form the basis of a translational mechanism. A very simple (and limited) test engine is implemented, along with a test case to drive it. Certainly none of it is interesting to users yet.

My hope for the future would be that toolkits gradually begin to start using the new API natively, but to help during the transition period, wrappers can be added to the existing infrastructure. For example, the project will include a traditional GTK+ engine as a proxy to allow GTK+ users to start using the new architecture immediately.

There are certainly problems that the API does not yet solve, such as transition effects. Other considerations might whether to add support for “native” styles on other platforms, such as Windows and Mac OS X, or whether these are best left to each toolkit to implement themselves. I would be interested to hear any suggestions around these areas.

* Qt “solve” this in quite an interesting way, but it changes the semantics of class selectors in CSS.

15 thoughts on “Monet – A Widget Drawing API”

    1. @Florian, @David: The purpose of Monet is to be a cross toolkit widget drawing library. Both Edge and QML mix UI definition and drawing, where as Monet focuses only on drawing, and they only work with one toolkit.

  1. Does or could Monet allow to have separate prelight styles for toggle buttons in both on and off states?

    Does it or could it adress the sub-widget issue with spin-buttons and/or better notebook tab focus indication as described on
    http://thorwil.wordpress.com/2009/07/29/gtk-issues/ ?

    Regarding the format, how about a customized version of CSS? Maybe just the same Qt does? But even with XML, at least some terminology could be taken from CSS.

    Quite a lot could be done with just having a means to define multiple outlines and layered fills with multiple stops and transparency. But for things like spinner buttons and expanders, using SVG would be very valuable. In any case, instant preview would be gold.

    1. @Thorsten, I hope the new API would address many of the problems and shortcomings in GTK+ theming, including the ones you mention. However, they would still need to be fixed in GTK+ to be dealt with properly.

  2. Hi Thomas, at a first glance, seems like a nice idea to solve this pesky issue which is cross-toolkit widget theming and drawing.

    I do have one question though. What if one has widgets that are inexistent in other toolkits or ones that behave dramatically different? In example, relying on widgets that morph themselves depending on state and context and which depend highly on the GPU not only for transition effects but for rather non-trivial effects in-widget.

    Have you looked at JSON?

  3. This is all too similar to the evolution of Adobe’s Flex framework. The progressive incarnation of Flex theming: Programmatic skinning -> CSS styling -> Custom XML (FXG + MXML).

    As you can relate: programming left the majority of designers out, CSS gave the designer something but far too limiting for their creative expression, and now XML is being tried.

    http://www.adobe.com/devnet/flex/articles/flex4_skinning.html

  4. Hi, Thomas

    (I’m dilomo form IRC if you remember)

    I was willing to start a project that will ease designers in their work on themes. It uses a svg “single canvas” workflow to let the artists draw all the widgets and then exports it to a pixmap theme (on my New Wave’s base that has been tested and is working well).See mockup here:
    http://gnome-look.org/content/preview.php?preview=1&id=118925&file1=118925-1.png&file2=&file3=&name=Gnome+Theme+Creator

    So I would like to ask you some questions and get a general idea if my program is worth developing right now:

    1. Is this going to included in Gnome 3.0 or is just an effort from your side?
    2. What happens to the gtk pixbuf engine and could it be used to some extent?
    3. How could a theme for pixmap be converted to the new format?
    4. When do you think is the date you will make a usable engine+infrastructure so that it could be tested?

  5. Changing the semantics of class selectors should hardly be an issue unless you want to render in a browser, which won’t work well anyway.

    I encourage you to look into things like edje as well. People outside the GNOME world have already worked on this problem.

  6. Personally I really like the idea of using Lua (or another scripting language, but I like Lua) as a backing for a styling system. Lua is really fast and I don’t think you’d have much problem speed wise, especially when you compare to the pain and anguish you’d experience with XML, complex parser, converting types from strings, etc. No language has seamless support for anything like XML.

    Lua has a lot of declarative features also, for example I’ve been playing around a bit with the idea of a Lua based declarative build system.

    http://github.com/blankthemuffin/TestProject/blob/master/library/library.lua

    Not to mention the ease of use you get from being able to use proper programming constructs inside your theme. Even just being able to set variables and include styles from each other is a win imo.

    I also don’t see how using a proper scripting language would have any bearing on the ability to write a wysiwyg editor at all. It’s just a different format you’d have to write to, and not a particularly difficult one at that I believe.

    Anyway that’s my two cents.

  7. Please consider the needs of browsers rendering HTML form widgets in your design.

    For example, a browser generally cannot provide “the text in the button” to your API. There might be text in the button with arbitrary styles on it, or images, or a table, or anything at all. We can ask you for the default font and color to use for text in a button, but that’s about it.

  8. “More complex widgets are split into sub-elements and passed to the theme engine as a group.”

    I’d like to hear more about how this would work, as I think it’s a very complex problem to mention in only one sentence. How much flexibility can be given to the theme engine when rendering, for example, a combobox?

    The current GTK code for this is horrifying. There are two different modes for comboboxes, a win32 style “list-mode” and a more X11 style option menu. Currently these are implemented in the GTK core, and a completely different set of sub-elements is generated depending on the mode. Somehow complex cases like this need to be handled as part of the theme engine, and the widget needs a way to say “render me however you want” and “where does my child widget go?” rather than being responsible for any details of its structure or appearance.

Comments are closed.