Extended Layout



Hello GTK+ Hackers,
     Over the last week I've been working on the extended layout patches[0]
which are sitting in the 'native-layout' branch (the original plan is outlined
in Mathias Hasselmann's blog post[1]).

At this point I'd like to share my findings, plans and uncertainties with the
list so as to get the best understanding of the code I'm writing as possible and
basically to make sure the patch is going to be right for everyone.

Input and feedback sooner than later will be a great help for me to make the
best possible use of the very the limited time I have to focus
completely on GTK+.

So let me give you a quick run down of the current api, what it does and
how I understand it:

/* This one obsoletes gtk_widget_size_request() */
void  gtk_extended_layout_get_desired_size     (GtkExtendedLayout *layout,
                                                GtkRequisition    *minimum_size,
                                                GtkRequisition
*natural_size);

      Gets the initial minimum and natural size of a widget and caches
it on the instance.

      Basically children get allocated natural sizes inside a
container before any extra space is
      given to "expand" children.

      Constraints set by gtk_widget_set_size_request() as well as
sizegroup constraints
      are taken into account as well before returning to the caller.


/* desired Height-for-Width api */
void  gtk_extended_layout_get_width_for_height (GtkExtendedLayout *layout,
                                                gint               height,
                                                gint
*minimum_width,
                                                gint
*natural_width);
void  gtk_extended_layout_get_height_for_width (GtkExtendedLayout *layout,
                                                gint               width,
                                                gint
*minimum_height,
                                                gint
*natural_height);

      Gets the natural size in one dimension based on its allocation in
      the other dimension. These sizes can be greater or less than the
      original desired natural/minimum size, but probably not less
than the original
      minimum.

      When a widget is not allocated its full natural requisition in
one dimension,
      it may desire a custom allocation in the other dimension to compensate.

      Word wrapping text should for instance require more height when
not allocated
      the full natural width.

      There is a danger here of children requiring greater minimum
sizes than the
      overall allocation, probably this is just a matter of requesting
decent natural
      sizes at get_desired_size() time.


So this is my understanding: hboxes are going to query their children
for their desired
width when allocating for a said height and vice versa.

Then what brings it all together is that GtkBox has to implement the interface
itself in order to proxy the sum of the desired size in a said
dimension at allocate
time via the ->get_width_for_height()/->get_height_for_width() interfaces.

Then, if you have a layout with an hbox in a vbox, something like this:

vbox {
    hbox [ fill ] {
        label [wordwrap=yes expand=yes],
        button,
    },
    label [ expand, fill ]
}

The vbox, at size_allocate() time; will ask the hbox for its desired
height for width,
who will in turn query the label which will calculate how many lines
need to be wrapped
for its allocated width.

Then vbox will attempt to allocate the collective height of the hbox,
which should finally give the desired height-for-width effect in the overall
layout.

At least, this is the conclusion I've come to so far based on the material
I've seen; patches, blogs bug reports and ML threads.

Which brings me to the ambiguous case, ClutterActor has a "request-mode"[3]
property which says an actor may be either "height-for-width" or
"width-for-height".

I still have to investigate what the meaning of that property is, what
use cases it has in GTK+ etc, any insight there would also be appreciated.

Another note I have to make is that the api needs to be replicated for
cell renderers as they cannot operate under that same api (they cannot
be assumed to hold a pointer to the target rendering widget), so I paved
a separate (unfinished) interface to the same effect.



Ok all that said, the native-layout branch today does do a lot of what
Hippo Canvas was doing in Havoc's blog[2] back in 2006, as far as laying
out widgets with expand/fill/ellipsize properties in a horizontal box
everything seems to work as expected (content aware GtkBin widgets need a
little implementing), so far I have buttons working nicely and will finish up
combo box support shortly.

As far as integration with GTK+ and compatibility with third party derived
widgets and client code I think I have things covered, but please do double
check my work and follow up on my last comments on the bug[0] if you find
something there.

Well this is an exciting project so I'd like to get back to work, please
any comments, insights and attention to the branch will be greatly
appreciated.

Regards,
         -Tristan

[0] bug: https://bugzilla.gnome.org/show_bug.cgi?id=101968
[1] Mathias's post: http://live.gnome.org/MathiasHasselmann/NewLayoutManager
[2] Havoc's blog: http://log.ometer.com/2006-10.html
[3] http://clutter-project.org/docs/clutter/stable/ClutterActor.html#ClutterActor--request-mode


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]