GtkSpringLayout is a GTK+ implementation of ideas found in springs-and-struts layout managers in various toolkits. It is a layout container that arranges its children according to constraints which are specified in the form of "springs", which can be attached to the edges of the children or the container itself. The GtkSpringLayout allows to attach a single constraint for the left, right, top and bottom edge of each child (as well as the container itself). It is also possible to constrain the width or height of widget, but only two out of the three possible constraints for each dimension can be set, e.g. if the left edge and the width are constrained, GtkSpringLayout enforces that right = left + width. Similarly, it enforces that bottom = top + height. Another restriction of the way in which GtkSpringLayout resolves the constraints is that cycles in the graph formed by the springs are not allowed. Springs which introduce cycles are ignored. Springs have a minimum, preferred and maximum size. The actual value of a spring might be different from its preferred value, but it is restricted to lie between the minimum and maximum. Mathematically, springs can be modeled as pointed intervals (which we'll write as [min,preferred,max]) and some common operations can be defined on them: [a1,b1,c1] + [a2,b2,c2] := [a1+a2,b1+b2,c1+c2] [a1,b1,c1] - [a2,b2,c2] := [a1-a2,b1-b2,c1-c2] MAX([a1,b1,c1], [a2,b2,c2]) := [MAX(a1,a2), MAX(b1,b2), MAX(c1,c2)] - [a,b,c] := [-c,-b,-a] f * [a,b,c] := [f*a,f*b,f*c] if f >= 0 := [f*c,f*b,f*a] if f < 0 These operations are reflected by the functions gtk_spring_sum(), gtk_spring_difference(), gtk_spring_max(), gtk_spring_minus() and gtk_spring_scale(), which construct new springs which depend on other springs and calculate their minimum, preferred and maximum values according to the formulas above. Another important aspect of such compound springs is that when their value is set, they propagate the value back to the springs they depend upon in a way which makes sure that the formulas hold. For sum springs, this is done in such a way that the strain of the dependent springs is the same as the strain of the compound spring. Apart from compound springs, there are simple springs which just have fixed values for minimum, preferred and maximum. These can be constructed using gtk_spring_simple() (or the convenience method gtk_spring_constant(), which makes minimum == preferred == maximum to construct inflexible springs, also known as struts). There are special springs which represent the width or height of a child widget or the container. These can be constructed using gtk_spring_width() and gtk_spring_height(). These springs can be made flexible by setting the child properties extra-width, max-extra-width, extra-height or max-extra-height to nonzero values. A width spring can be described as the interval [req.width, req.width + extra-width, req.width + max-extra-width] where req is the requisition of the widget. Similarly for height springs. Another kind of special springs, proxy springs are used to describe the constraint that determines the location of an edge of a child. Springs of this kind are constructed with gtk_proxy_spring(). The advantage of using proxy springs instead of just obtaining the constraint with gtk_spring_layout_get_constraint() is that it allows to attach constraints to edges without paying attention to the order in which they are attached. Finally, it is possible to implement custom types of springs by deriving from the abstract GtkSpring class. All custom springs must implement get_minimum_value, get_preferred_value, get_maximum_value, get_value and set_value. If a custom spring depends on other springs, its set_value implementation should propagate the new value to its dependent springs in a way which ensures that a following get_value call will yield the new value. Compound custom springs should also implement the is_cyclic and reset_cyclic methods which are used for detecting cycles in the spring graph. The is_cyclic method must call gtk_spring_is_cyclic() on all dependent springs and return the disjunction of the results and the reset_cyclic method must call gtk_spring_reset_cyclic() on all dependent springs. GtkPadSpring is an example of a custom spring that behaves similar to a spring that adds three springs together, but when propagating a value back, it tries to keep the middle spring at its preferred size as long as possible. testsprings.c contains a few examples.