Search code examples
cgtk

Align two buttons side by side in GTK Grid


So, I am writing a simple calculator in GTK, and I am using a Grid to put all the number buttons. I want my equal button to be as tall as two normal buttons, but I want to align it's bottom to it's sibling's bottom. How can I accomplish this? Should I use another type of widget instead of using a grid?

static void
activate (GtkApplication *app,
          gpointer        user_data)
{
  
  //declaration of each widget (in this case, buttons)
  GtkWidget *window;
  GtkWidget *grid_numbers;
  GtkWidget *zero;
  GtkWidget *one;
  GtkWidget *comma;
  GtkWidget *mod;
  GtkWidget *plus;
  GtkWidget *equal;
  GtkWidget *squared;
  GtkWidget *minus;
  GtkWidget *mult;
  GtkWidget *sqrt;
  GtkWidget *divide;
  GtkWidget *two;
  GtkWidget *three;
  GtkWidget *four;
  GtkWidget *five;
  GtkWidget *six;
  GtkWidget *seven;
  GtkWidget *eight;
  GtkWidget *nine;

  window = gtk_application_window_new (app);
  gtk_window_set_title (GTK_WINDOW (window), "The C Calculator");
  gtk_window_set_default_size (GTK_WINDOW (window), 300, 490);

  grid_numbers = gtk_grid_new();
  gtk_widget_set_halign(grid_numbers, GTK_ALIGN_CENTER);
  gtk_widget_set_valign(grid_numbers, GTK_ALIGN_END);
  gtk_grid_set_row_homogeneous(GTK_GRID(grid_numbers), true);
  gtk_grid_set_column_homogeneous(GTK_GRID(grid_numbers), true);
  //gtk_grid_set_column_spacing(GTK_GRID(grid_numbers), 100);
  //gtk_grid_set_row_spacing(GTK_GRID(grid_numbers), 100);

  gtk_window_set_child(GTK_WINDOW(window), grid_numbers);

  zero = gtk_button_new_with_label("0");
  //implement logic
  gtk_grid_attach(GTK_GRID(grid_numbers), zero, 0, 0, 10, 10);
  g_signal_connect(zero, "clicked", G_CALLBACK(zeroFun), NULL);

  comma = gtk_button_new_with_label(",");
  gtk_grid_attach_next_to(GTK_GRID(grid_numbers), comma, zero, GTK_POS_RIGHT,10, 10);
  
  mod = gtk_button_new_with_label("%");
  gtk_grid_attach_next_to(GTK_GRID(grid_numbers), mod, comma, GTK_POS_RIGHT, 10, 10);

  plus = gtk_button_new_with_label("+");
  gtk_grid_attach_next_to(GTK_GRID(grid_numbers), plus, mod, GTK_POS_RIGHT, 10, 10);
  
  equal = gtk_button_new_with_label("=");
  gtk_grid_attach_next_to(GTK_GRID(grid_numbers), equal, plus, GTK_POS_RIGHT, 10, 20);

  one = gtk_button_new_with_label("1");
  gtk_grid_attach_next_to(GTK_GRID(grid_numbers), one, zero, GTK_POS_TOP, 10, 10);


  gtk_window_present (GTK_WINDOW (window));
}

enter image description here


Solution

  • First of all, there's one remark about an assumption you seem to be making: the final 2 arguments width and height of gtk_grid_attach() are not the width and height in pixels or something like that. They represent the number of columns (or rows) the child widget should be taking. In other words, you probably want to replace 10 by 1 and 20 by 2 in the values of your example.

    Now, you have 2 options to achieve what you want here:

    1. Using gtk_grid_attach() directly

    gtk_grid_attach() allows you to specify exactly which row and column an element should be put in

      equal = gtk_button_new_with_label("=");
      gtk_grid_attach_next_to(GTK_GRID(grid_numbers), equal, 3, 1, 1, 2);
    
    1. Using gtk_grid_attach_next_to()

    gtk_grid_attach_next_to() with GTK_POS_RIGHT will internally call gtk_grid_attach() with the same row number as the referenced element indeed. In your example, if you really want to use this method, you'll probably use it on the button that is above the "+" button (I assume the "-" button)