Search code examples
gtkgtk#

How to create a wrapping table in GTK#


I'm trying to make a table of square buttons in GTK# with the following properties:

  1. Buttons will be added and removed one at a time.
  2. Buttons should be laid out like text on a page - left to right until no more can fit on a row, then wrapping onto the next row.
  3. If there are more buttons than will fit in the window, there should be a vertical scroll-bar.
  4. The table should be resizable. Resizing should reflow the buttons as necessary.
  5. Buttons should be of fixed size.

I started off trying to use a Table with Homogenous==true. I added a handler for SizeAllocated and in it I check if the width of the table has changed enough to add or remove a column. If it has, I removed all the buttons, updated NColumns and re-attached the buttons in the correct places. This seemed to work, but the buttons were not fixed size - they would expand to fill the horizontal space.

Next I tried turning off Homogenous and setting preferred dimensions for the buttons. A minor problem is that ideally I want to put a known-size bitmap on each button, and I would like to get the layout correct regardless of how many pixels the button adds around the bitmap, but I'm not sure how to find out the total size of the buttons to do my calculations. A more serious problem is that my application now redraws inconsistently - sometimes the button labels are off-centre or not drawn at all. I am wondering if this is because I am changing the layout in response to the wrong signal.

How should I do this instead? Is Table the right container for the job? Is there something that will do what I want out of the box? (Perhaps something more akin to "icon" or "thumbnail" view in a file browser?) What is the correct way to manipulate the layout of the window in response to changes in size?


Solution

  • To do something like this you need a custom layout container. A wrap box is difficult (requires scary hacks) if done without the new height-for-width stuff in GTK+ 3.0, but it's been done.

    Here are some links to past efforts that you may find useful:

    GIMP also has or used to have a wrap box widget in it, which may be the same as one of the above, I'm not sure.