0

As the title says, I want to create a grid of uniform, square buttons in gtk4, with no (or very little) spacing in between the cells. It seems like this should be quite simple but I've been really struggling to achieve this in gtk.

Here's a picture of an example of what I'm trying to replicate: range chart.

This is meant to be for a poker-related application. Such charts are extremely common in poker software. The user should be able to select any subset of cells, which each represent a dealt hand. This subset (or "range", as its called) can then be processed by the program in various ways.

My (failed) attempts so far include:

  1. Using a GtkGrid with each child containing a GtkAspectFrame which contains a GtkToggleButton. image

This sort of worked but I was left with hideous gaps between the cells, which I could not figure out how to get rid of. Also, when I ran the program, GTK would spit out a bunch of error messages that looked like this:

(window:29202): Gtk-CRITICAL **: 11:07:39.057: Allocation width too small. Tried to allocate 34x34, but GtkToggleButton 0x564febf98c10 needs at least 36x34.

  1. Using a GtkListStore with 13 G_TYPE_STRING columns (one for each card). Then I manually added each of the 13 rows to the list store and display it as a GtkTreeView using GtkCellRendererText. image

I was able to display the text but that's about it. The GtkTreeView seems to be more row/column-oriented than cell-oriented. It doesn't even seem like there's a way to select individual cells, and there doesn't seem to be a way to add buttons by default. Perhaps I could implement a custom GtkCellRenderer with a bunch of custom events/signals? This seems like quite the rabbit hole to go down so I wanted to see if I could get some guidance first.

Beyond the most basic implementation, I will eventually want each cell to be able to have associated data that is not necessarily displayed at all times. I believe this would suggest that a GtkTreeView is the right way to go, if there's a way to get it to work properly.

As you can probably tell, I am very new to Gtk. I've only been playing with it for a few days, trying to understand the docs and get this to work. What is the right approach here? Any tips to point me in the right direction would be greatly appreciated.


As a bonus: Often times a well-designed poker application will allow you to mouse over the cells with the mouse button held down to select your range. Any cell under the cursor while the mouse button is held down will be added to the selection. This is often more convenient than clicking each individual cell. How would one go about achieving this behavior in gtk4?

cherba
  • 1
  • I'm not familiar with GTK4 per se, but I think for what you want to achieve, you'll have to go down the rabbit hole of creating your own control. I'd probably implement this with a drawing area or canvas, where you can control all details of the grid you draw. You'll have to listen to mouse and perhaps keyboard events, but in your example, hit tests should be easy. With standard controls, I guess you will hit limitations pretty fast. Besides, conceptually, your grid items aren't buttons that you press or cells that you can edit, so using those feels a bit off. – M Oehm Jun 11 '21 at 04:41

1 Answers1

0

You can use GtkGrid and set the row-homogeneous and column-homogeneous properties. It will make all cells have the same height/width as the biggest child respectively.

GtkWidget *grid = gtk_grid_new();
gtk_grid_set_row_homogeneous (GTK_GRID (grid), TRUE);
gtk_grid_set_column_homogeneous (GTK_GRID (grid), TRUE);

// Then just attach your button using the usual APIs:
// gtk_grid_attach (GTK_GRID (grid), button, 0, 0, 1, 1);

or in GtkBuilder XML

<object class="GtkGrid" id="grid">
    <property name="row-homogeneous">1</property>
    <property name="column-homogeneous">1</property>
    <child>
        <object class="GtkToggleButton">
            <!-- initialize your toggle button -->
        </object>
        <layout> 
            <property name="column">0</property>
            <property name="row">0</property>
        </layout>
    </child>
    <!-- And so on ... -->
</object>
nielsdg
  • 2,318
  • 1
  • 13
  • 22
  • I tried this in glade. As far as I can tell, this ensures that all cells have equal height and equal width, but does not guarantee that height = width. – cherba Jun 10 '21 at 13:13