Container secrets: size allocation, part 5

Orientation

Many widgets in GTK+ can be oriented either horizontally or vertically. Anything from a separator to a toolbar is implementing the GtkOrientable interface to allow this to be changed at runtime, by setting the ::orientation property. So, obviously, GtkCenterBox should follow this pattern too.

I’m not explaining in detail how to add the interface and implement the property. The interesting part for us is how we are going to use the orientation property during size allocation.

Thankfully, much of our machinery is already written in terms of a single dimension, and can be applied to a height just as well as a width. What remains to be done is going through all the functions, and making sure that we take the orientation into account whenever we do something that depends on it. For example, we introduce a little helper to query the proper expand property.

static gboolean
get_expand (GtkWidget *widget,
            GtkOrientation orientation)
{
  if (orientation == GTK_ORIENTATION_HORIZONTAL)
    return gtk_widget_get_hexpand (widget);
  else
    return gtk_widget_get_vexpand (widget);
}

One thing to keep in mind is that some of the features we implement here only apply in horizontal orientation, such as right-to-left flipping, or baselines.

The measure() function changes to avoid hardcoding horizontal orientation:

if (orientation == self->orientation)
  gtk_center_box_measure_orientation (widget, orientation, for_size,
                                      minimum, natural,
                                      min_baseline, nat_baseline);
else
  gtk_center_box_measure_opposite (widget, orientation, for_size,
                                   minimum, natural,
                                   min_baseline, nat_baseline);

The size_allocate() function calls distribute() to distribute either the width or the height, depending on orientation:

if (self->orientation == GTK_ORIENTATION_HORIZONTAL) {
  size = width;
  for_size = height;
} else {
  size = height;
  for_size = width;
}
distribute (self, for_size, size, sizes);

After these straightforward, but tedious changes, we can orient a center box vertically:

References

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

One thought on “Container secrets: size allocation, part 5”

  1. Just wanted to drop a quick thanks for taking the time to write these. There is a good bit of info out there for getting started with Gtk. What seems to lacking or hard to track down is info on doing more complex things with it.

Comments are closed.