Container secrets: size allocation, part 3

 Expanding children

The next stop in our quest for featureful size allocation is the ::expand property. There are actually two of them,  ::hexpand and ::vexpand, and they have a somewhat interesting behavior of propagating upwards in the widget hierarchy. But that is not what we are going to discuss today, we simply want to give the children of our center box widget all the available space if they have the ::hexpand flag set.

Once again, the measure() implementation can stay as it is. And once again, we need to make a decision about who to expand first, if more than one child has an expand flag set. GtkBox tries to treat all its children the same, and evenly distributes the available extra space among all expanding children. We, on the other hand, prefer the center child, since it is the most important one.

But how do we go about this ? After some experimentation, I figured that if we already have to push the center child to the left or right because it does not fit, there is not point in making it even larger. Therefore we only respect the expand flag if that is not the case:

center_expand = gtk_widget_get_hexpand (center);

if (left_size > center_x)
  center_x = left_size;
else if (width - right_size < center_pos + center_size)
  center_x = width - center_width - right_size;
else if (center_expand) {
  center_width = width - 2 * MAX (left_size, right_size);
  center_x = (width / 2) - (center_width / 2);
}

After doing this, there may still be some space left that we can give to the outer children, if they are expanding:

if (left_expand)
  left_size = center_pos - left_pos;
if (right_expand)
  right_size = pos + width - (center_pos + center_width);
No expanding children
Center child expanding
End child expanding
Center and end children expanding

References

  1. Container secrets: size allocation
  2. Container secrets: size allocation, part 2
  3. The code with these changes