GTK+ learns height for width episode II

These last weeks I’ve been working on finishing the remaining bits of the height-for-width layout system for GTK+.

The GtkExtendedLayout interface, which has recently been renamed to GtkSizeRequest has been merged into GTK+ recently with only some basic features leveraging the new code (the new GtkSizeRequest interface allows widgets to trade height for width when negotiating their geometry, read this informative post for more details on how this works).

I’m going to be putting a branch together to be reviewed but here’s a sneak preview of what’s been added in height-for-width land.

Wrapping expander labels:

Shows the expander fully unwrapped, note that the focus shows the label is allocated no more than its full natural width

When the expander is allocated something smaller:

Note the extra vertical space is not evenly shared. The expander label is allocated a sufficient height and the remaining space is given to the child.

At it’s smallest size:

All height-for-width widgets will always ensure enough height to fit the minimum width.

Ok ok I know expanders are not that exciting… I’m only posting them cause the screenshots have pretty colours in them…

Naturally sizing Tree Views

Ok this is the juice, as you might guess working anything new into the treeview code is … some kind of nightmare… so first the easy part… here are some ellipsizing cell renderers packed into some columns in a view to show how it naturally sizes:

Note how the width of renderers in the right column is shared according to natural widths

And when you shrink it:

Note that when not all renderers get their natural width, at least smaller widths are prioritized automatically.

Wrapping Cell Renderers in Tree Views

Ok heres the wild stuff, first of all I have to say I’m not very proud of all the cute kittens I had to slay to get this done… that is to say that there is an interesting new problem for scrolled windows that parent height for width widgets that may result in deadly feedback loops that lockup your desktop… thankfully I found a trick to avoid it. It’s not that pretty and in the long term the hack should be replaced… with… well with something generally more kind to your kittens.

All that said… it does work and calculate row-height for width asynchronously in the background and only when columns are set to resize etc etc… hopefully this wont be much of a performance hit for views that handle large datasets.

Except that the columns/renderers are automatically allocated natural widths, nothing is special about this treeview.

The above shows the treeview at its full width; it’s packed in a scrolled window with automatic scrollbars.

When you shrink the view the row heights will be recalculated and redisplayed, the horizontal scrollbar of the scrolled window will only appear if the child view is allocated less than its minimum possible width.

This can be useful where its more important to see the full content of each visible row than it is to see a lot of rows at a time.

This particular view can be resized very slim, just because the minimum width-chars of the renderers are not set and so they are all permitted to get pretty small:

This view's rules permit it to become very skinny - one renderer is set to ellipsize and not wrap.

While I’m happy to have got as far as wrapping text in treeview’s; that was only the hardest challenge of the GtkCellRenderer brand – after this there is still more to be done for GtkIconView, GtkCellView and consequently, GtkComboBox.

And of course, all of this fancy cell renderer stuff is going to have to pass review and all… but we’re getting there !

And I’m proud to say that all these recent developments have been brought to you by Openismus GmbH.

Enjoy !

9 Responses to “GTK+ learns height for width episode II”

  1. Marco Diego Aurélio Mesquita says:

    Thanks!

  2. pt says:

    wow this would be so useful Baobab disk usage anayzer.

    Currently when a folder with a long name appears on the list the size column falls out of view. And you have to manually resize the columns

  3. oll says:

    Is it possible to have a looka t the code? Do you have a git branch to look at?

  4. Jussi Kukkonen says:

    Awesome.

    I feel for the kittens, I really do, but their sacrifice is for the greater good.

  5. Jaroslav Smid says:

    Well, you seem excited, but I’m not. I would rather have ellipsized text on expander (and full text shown as on-mouse-over hint) then to give it 5 lines which could be used by child widget.
    The same apply for treeview – current treeview implementation is so-so, it doesn’t support hits for ellipsized text (and if it does, it is hacky implemented and doesn’t show where it should – over the text as it does for example in WinAPI, moreover when it is under mouse cursor, widget under it looses mouse-over state and when clicked, the click is not propagated to treeview). And with wrapped text, treeview gets confusing and slow (because the items are not of the same height).

  6. tvb says:

    I just prepared a branch for review:
    http://git.gnome.org/browse/gtk+/log/?h=native-layout-incubator-2

    The whole branch (containing unfinished work) is ‘native-layout’.

  7. tvb says:

    Jaroslav: I’m not sure I understand, are you claiming that I did not give you ellipsizing expander labels just because you also get to have wrapping ones ?

    Do you suspect that the treeview’s fixed-height-mode will break with my patch ?

    It’s possible with all the features of treeview I made a couple of mistakes, we have a review process for that.

  8. Jaroslav Smid says:

    tvb: No, I’m just claiming, that what you did with expander is maybe unusable (at least for me). If this is available for gtk message dialogs, which in current state show like 5 words on each line, it will be great, but for expander, I am not sure.

    And I didn’t say you broke treeview, it just look so inconsistent when there is suddenly one extra thick row. Of course no one forces me to use that renderer. I’m just saying, that I don’t like it on these widgets, seems unusable for me.

  9. Good tips thanks for the share. I will keep them in mind for life