Good morning, I've managed to get the base feature set of the native-layout branch working and in a usable state.
By usable I mean: I've been running Glade on the extended layout branch for the past week and all of the regressions I've spotted so far have been fixed, I can also run the Gimp and gedit with no visible regressions yet (and ofcourse, the gtk-demo and testgtk as well). It should also of course essentially solve the height-for-width bug[0] and at least provide the right framework to adress the GtkExpander ellipsize bug[1] and probably a few more. I also spent some time today documenting the API which makes alot more sense now (at least to me) I've salvaged everything that is clean and usable thus far into a new 'native-layout-incubator' branch. This branch was created for the review process and potential inclusion of the whole height-for-width geometry management system and modest feature set to leverage it. Anyone interested should try compiling the incubator branch (or the native-layout branch even) and run the example in the tests directory: ./tests/extendedlayoutexample (note in the native-layout branch its still called testextendedlayout2). So, here's a global picture of what's in the incubator branch and what didnt make it: In: - The GtkExtendedLayout ofcourse (this is the basic API for requesting height-for-width size requests (this is all the new code that manages what sizes a widget will request in either dimension, doing deals with size groups and explicit size requests, caching the whole expensive operation and all that noise). - GtkLabel features: o The label now does height-for-width and also width-for-height when the text is rotated to 90 or 270 degrees. o The label now requests a full natural size to fit ellipsizing text unless capped by "max-width-chars". (this includes rotated text in any angle). o "max-width-chars" / "width-chars" act as guides to hint at good minimum widths and max natural widths when wrapping text. - GtkBox will allocate children according to their natural sizes (the key container right now producing the overall effect of height-for-width geometry) - Mathias Hasselmann's testellipsize test which demos rotating ellipsizing label allocations. - A new test 'extendedlayoutexample' showing various interfaces using the natural layout features. Out: - GtkExtendedCell: this is the cell renderer specific api, the cell renderers already do natural sizes for ellipsize but don't yet do width-for-height or height-for-width (they also just need some basic attention I didnt have time for). - Mathias Hasselmann's testextendedlayout test which is really a great and thorough test, it needs work to bring up to speed on what to expect in terms of behaviors of GtkLabel, it also expects other stuff to pass that's just not ready yet (cell renderers etc). - GtkComboBox support depends on the cell renderer stuff so its still not ready. - GtkPlug/GtkSocket support: this is just a matter of changing the api from a natural requisition of width/height pair to a dual pass requisition of ->get_height_for_width(). Would be really simple to finish these off as it just needs to be set straight to forward along the new height-for-width api. The idea here is of course that we keep native-layout branch up to date and that will be a great place to continue work on GtkTable, finish up cell renderers and incrementally introduce these new features to GTK+. About compatibility, afaics only these side effects are introduced: - Direct access to ->requisition is invalid and needs to be gtk_extended_layout_get_desired_size (or at least gtk_widget_get_child_requisition). - GtkBin classes that define a custom padding must implement get_desired_width()/get_desired_height() to report them correctly along with the child values (otherwise only the base values from a "size-request" is used). - GtkLabel heuristics have change a bit with regards to "max-width-chars" and "width-chars", although I doubt the impacts are going to be visibly negative. Some regrets: - I think in the end I would have preferred an enum return type for gtk_extended_layout_is_height_for_width(); it really makes no difference in practice but would make for better readable documentation. - While it was besides the point; it would be nice to take a few days; maybe include ->size_allocate() in the new API and come up with a completely floating point api for GTK+ 3.0. (this was one among the countless bugzilla comments I read). And ofcourse, the whole thing is going to consume more memory to cache the multiple requisitions; and the requests are going to be slower no matter what. While there is undoubtedly room for optimization in GtkLabel, over all we are moving from a one size requisition and one size allocation; to a dual pass requisition phase, followed by a recursive allocation that fires recursive contextual requisitions along the way. But all that being said the caching works well and interfaces resize nicely from what I've seen so far, a little extra resources I guess is the price you pay for a more modern geometry management system. Ok time to sleep for now; try it test it review it enjoy it ! Cheers, -Tristan PS: New API with documentation attached [0] https://bugzilla.gnome.org/show_bug.cgi?id=101968 [1] https://bugzilla.gnome.org/show_bug.cgi?id=406528
/** * SECTION:gtkextendedlayout * @Short_Description: Height for Width Geometry management * @Title: GtkExtendedLayout * * The extended layout is GTK+'s height for width geometry management * system. * * <refsect2> * <title>Implementing GtkExtendedLayout</title> * <para> * Some important things to keep in mind when implementing * or using the extended layout. * * The Extended Layout system will query a logical heirarchy in * only one orientation at a time. When widgets are initially queried * for their minimum sizes it is generally done in a dual pass * in the direction chosen by the toplevel. * * For instance when queried in the normal height-for-width mode: * First the default minimum and natural width for each widget * in the interface will computed and collectively returned to * the toplevel by way of gtk_extended_layout_get_desired_width(). * Next; the toplevel will use the minimum width to query for the * minimum height contextual to that width using gtk_extended_layout_get_height_for_width() * which will also be a highly recursive operation. This minimum * for minimum size can be used to set the minimum size constraint * on the toplevel. * * When allocating; each container can use the minimum and natural * sizes reported by thier children to allocate natural sizes and * expose as much content as possible with the given allocation. * * That means that the request operation at allocation time will * usually fire again in contexts of different allocated sizes than * the ones originally queried for. * * A Widget that does not actually do height-for-width * or width-for-height size negotiations only has to implement * get_desired_width() and get_desired_height() * * If a widget does move content around to smartly use up the * allocated size, then it must support the request properly in * both orientations; even if the request only makes sense in * one orientation. * * For instance; a GtkLabel that does height-for-width word wrapping * will not expect to have get_desired_height() called because that * call is specific to a width-for-height request, in this case the * label must return the heights contextual to its minimum possible * width. By following this rule any widget that handles height-for-width * or width-for-height requests will always be allocated at least * enough space to fit its own content. * </para> * </refsect2> */ /** * gtk_extended_layout_is_height_for_width: * @layout: a #GtkExtendedLayout instance * * Gets whether the widget prefers a height-for-width layout * or a width-for-height layout * * Returns: %TRUE if the widget prefers height-for-width, %FALSE if * the widget should be treated with a width-for-height preference. * * <note><para>#GtkBin widgets generally propagate the preference of thier child, * container widgets need to request something either in context of their * children or in context of their allocation capabilities.</para></note> * * Since: 3.0 */ gboolean gtk_extended_layout_is_height_for_width (GtkExtendedLayout *layout); /** * gtk_extended_layout_get_desired_width: * @layout: a #GtkExtendedLayout instance * @minimum_width: location to store the minimum size, or %NULL * @natural_width: location to store the natural size, or %NULL * * Retreives a widget's initial minimum and natural width. * * <note><para>This call is specific to height for width requests.</para></note> * * Since: 3.0 */ void gtk_extended_layout_get_desired_width (GtkExtendedLayout *layout, gint *minimum_width, gint *natural_width); /** * gtk_extended_layout_get_desired_height: * @layout: a #GtkExtendedLayout instance * @minimum_width: location to store the minimum size, or %NULL * @natural_width: location to store the natural size, or %NULL * * Retreives a widget's minimum and natural size in a single dimension. * * <note><para>This call is specific to width for height requests.</para></note> * * Since: 3.0 */ void gtk_extended_layout_get_desired_height (GtkExtendedLayout *layout, gint *minimum_height, gint *natural_height); /** * gtk_extended_layout_get_width_for_height: * @layout: a #GtkExtendedLayout instance * @height: the size which is available for allocation * @minimum_size: location for storing the minimum size, or %NULL * @natural_size: location for storing the natural size, or %NULL * * Retreives a widget's desired width if it would be given * the specified @height. * * Since: 3.0 */ void gtk_extended_layout_get_width_for_height (GtkExtendedLayout *layout, gint height, gint *minimum_width, gint *natural_width); /** * gtk_extended_layout_get_height_for_width: * @layout: a #GtkExtendedLayout instance * @width: the size which is available for allocation * @minimum_size: location for storing the minimum size, or %NULL * @natural_size: location for storing the natural size, or %NULL * * Retreives a widget's desired height if it would be given * the specified @width. * * Since: 3.0 */ void gtk_extended_layout_get_height_for_width (GtkExtendedLayout *layout, gint width, gint *minimum_height, gint *natural_height); /** * gtk_extended_layout_get_desired_size: * @layout: a #GtkExtendedLayout instance * @width: the size which is available for allocation * @request_natural: Whether to base the contextual request off of the * base natural or the base minimum * @minimum_size: location for storing the minimum size, or %NULL * @natural_size: location for storing the natural size, or %NULL * * Retreives the minimum and natural size of a widget taking * into account the widget's preference for height-for-width management. * * If request_natural is specified, the non-contextual natural value will * be used to make the contextual request; otherwise the minimum will be used. * * This is used to retreive a suitable size by container widgets whom dont * impose any restrictions on the child placement. * * Since: 3.0 */ void gtk_extended_layout_get_desired_size (GtkExtendedLayout *layout, gboolean request_natural, GtkRequisition *minimum_size, GtkRequisition *natural_size);
_______________________________________________ gtk-devel-list mailing list gtk-devel-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-devel-list