GTK+ Learns height-for-width geometry

Over the past weeks I’ve been concentrating my full energies on an Openismus funded expedition to finalize the extended layout patches that teach height-for-width geometry management to GTK+.

Its time to show off a little what came out of this effort:

The test/extendedlayoutexample program screenshot cropped by gimp running against the native-layout branch.

No ! not the crazy allocation assertions from hell ! I’m just kidding; I’m not sure if those assertions come from running the Gimp against git master or from running against the native-layout branch. The point of this shot is only to say the stuff is pretty damn stable. I’ve been creating the demos (in this post and my last blog post) using Glade running directly against a modified height-for-width GTK+ core. The above screenshot was taken with the Gimp running against the modified GTK+ and it displayed and behaved fine during the exercise.

So that was my first priority: turn the work into something that we can all use right now, there are some really minor API breaks (also discussed in the announcement) but from what I’ve seen so far you’re favorite application will run just fine against the new GTK+ code (that includes sticky places where the application tries to hack its own height-for-width labels by way of handling “size-request” signals and such).

One of the really difficult parts of getting this working was to make container widgets report sensible width-for-height/height-for-width collectively for their children:

Two wrapping labels in a horizontal box (top left)

The trick is the horizontal box has to compute a collective minimum and natural height for its overall allocated width:

When stretched, the horizontal box reliquishes height by collectively calculating height-for-width of its children.

Trickier still, was to figure out how a height-for-width widget and a width-for-height widget could live together  in the same hierarchy and at least always require enough space in both dimensions (so that we can set reasonable window constraints based on the interface’s minimum size and labels don’t wrap ever out of view unexpectedly).

After a lot of thought and valuable insights shared on irc (Owen, Matthias…), a good nights sleep and then another day hacking we were able to dish out a GTK+ that will also do width-for-height:

An interface that uses width-for-height

And the two possible extremities of the window pane:

Lowest position for the window pane

And:

Highest position of the window pane

All of this is available in the ‘native-layout’. A trimmed down branch has been created for review of the base feature set called ‘native-layout-incubator’ where you can find the above demo ‘extendedlayoutexample’.

Thanks Murray and Openismus for the great experience, and for the great new features for GTK+ !

4 thoughts on “GTK+ Learns height-for-width geometry”

  1. ethana2:
    Yes QT also does this (except from what I understand QT
    does height-for-width but not width-for-height; although
    height-for-width is much more important in most interfaces).

    Cocoa; I’ve not encountered anything like this in its API while
    using it (at least on iPhone api) or after a quick search of their
    documentation.

    Cocoa has a much different API that seems heavily coordinates
    based (the few container objects available do very specific things,
    like the tab bar or navigation bar widgets for instance).
    Like when writing an action script application: usually you would define
    the positions and sizes of each object in the designer tool – and your
    positions will be floating point values. Then your application may be
    shown at different sizes on the target host (depending on screen
    resolution and user settings, also kindof like flash).

    Of course they must provide solutions for scrollable wrapping text in
    some way (which is also a height-for-width kind of size request),
    GTK+ addresses this by way of its scrolled window semantics.

Leave a Reply

Your email address will not be published. Required fields are marked *