Understanding GTK options to for widget sizes

A new day, a new question.

I am currently working on a “preview grid” for media send in a Tweet, in a similiar style to what Twitter itself uses:

Mockup of intended layout

So I have a sub-class of Gtk.Grid for the overview, with a custom Gtk.Widget using Gtk.ConstrainLayout for each item, with the intention to use constraints to clip the images when needed.

Now, while the basic widget structure is implemented, I still have to implement some resizing functionality, as I want:

  1. The grid to use a certain multiplier of the width as the height.
  2. To use the size of one item to calculate how to clip the image in it.

As far as I understand now, after reading the Docs, I would need to implement Gtk.Widget.measure (along with Gtk.Widget.get_request_mode) for the first case, and something related to Gtk.Widget.allocate for the second.
However, as of now I do not fully understand how these functions are called and processed by GTK, so I am asking here for some advice.

You shouldn’t need to use both Gtk.Grid and Gtk.ConstraintLayout, just one of them will probably do the job. I don’t think either of them can crop child contents, so you will have to come up with something else. You may be able to implement a custom widget that does set_overflow(GTK_OVERFLOW_HIDDEN), or possibly you can use a GtkViewport.

I think your assessment is correct, but here is more of a run down as far as I understand it. Most of the details of this is in the function gtk_widget_allocate which is called by containers on each of their children.

get_request_mode is used internally by gtk_widget_allocate to decide which orientation to use first when invoking measure, since that function needs to be called twice for each widget. The width-for-height and height-for-width modes are only used by widgets that support reflow like when you resize a wrapped text paragraph. If your widget doesn’t do that then you can use a constant size.

measure is then for the widget to declare its minimum size to the parent container so the container knows how to lay itself out. It’s called in the gtk_widget_measure function which is used by the parent container during its own size_allocate implementation. In your widget implementation, the gtk_widget_queue_resize method should be called when the return value from this function changes, i.e. if you have changed some internal state that alters its computation.

Finally size_allocate is called when the widget receives a new size from the parent container. This is usually invoked by calling gtk_widget_size_allocate or gtk_widget_allocate inside the parent container’s size_allocate implementation.

There are some more things to know if you’re implementing a custom container but for a simple widget with no children, you likely won’t need more than these three.

Well, in my use-case I want to display a variable number of items on this grid, with these items might having some additional UI-elements so I came to this setup. And you can use GtkConstraintLayout to clip child widgets, for example by [child.start ( super.start - offset )], which I wanted to use that. But thanks for the hints to overflow and the viewport, will look into that as well.

Also thanks for the explanations!

Hmm, I see what you mean, that will actually work if you set the overflow to hidden. That’s interesting!

I have now a (aside of a few bugs) working implementation of my wanted feature.
I had to use custom measure and size_allocate functions, but it works quite well!

One thing I noticed though is the following:
Using SizeRequestMode = HEIGHT_FOR_WIDTH, I could implement the “keep the same ratio of width to height while resizing”, as measure is called for resizes as well. However, it does not apply when maximizing a window, where measure is not called, resulting in no recalculation of the height, despite the width change.
Is this wanted behaviour in GTK? Did I miss something or is this a bug?

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.