You can just add widgets to cells. As is already stated in the comment, the Top
and Left
parameters of Attach
represent the cell indices (row/column), not pixels. See the annotated example below.
If you want to position a widget using coordinates, then you can use a GTK Fixed container. Be aware, however, that this container is almost never a good solution for positioning widgets; widgets should, in principle, always be positioned using layout containers HBox, VBox, Table, Grid and Layout. This is to ensure proper widget composition regardless of the screen resolution and screen size of the user. This is emphasized in the description of the Fixed widget:
For most applications, you should not use this container! It keeps you from having to learn about the other GTK+ containers, but it results in broken applications.
I've added an example that shows the usage of both container widgets, Grid and Fixed. In these example, I've moved the GTK code into a separate package in order to add a Destroy_Event_Callback
which in turn will call Gtk.Main.Main_Quit
to stop the GTK event loop and properly exit the program when you close the window.
app.adb (using GTK Fixed, see manual and GtkAda source)
with Gtk.Main; use Gtk.Main;
with Gtk.Window; use Gtk.Window;
with Gtk.Button; use Gtk.Button;
with Gtk.Widget; use Gtk.Widget;
with Gtk.Fixed; use Gtk.Fixed;
package body App is
procedure Destroy_Event_Callback
(Widget : access Gtk.Widget.Gtk_Widget_Record'Class);
---------
-- Run --
---------
procedure Run is
Win : Gtk_Window;
Button_1 : Gtk_Button;
Button_2 : Gtk_Button;
Button_3 : Gtk_Button;
Fixed : Gtk_Fixed;
begin
Gtk.Main.Init;
Gtk_New (Win);
Win.Set_Default_Size (Width => 380, Height => 502);
Win.On_Destroy (Call => Destroy_Event_Callback'Access);
Gtk_New (Button_1, "Button 1");
Gtk_New (Button_2, "Button 2");
Gtk_New (Button_3, "Button 3");
Gtk_New (Fixed);
-- Add the buttons to the container with their
-- top-left corner at the specified coordinate.
Fixed.Put (Button_1, X => 0, Y => 0);
Fixed.Put (Button_2, X => 50, Y => 100);
Fixed.Put (Button_3, X => 200, Y => 100);
Win.Add (Fixed);
Win.Show_All;
Gtk.Main.Main;
end Run;
----------------------------
-- Destroy_Event_Callback --
----------------------------
procedure Destroy_Event_Callback
(Widget : access Gtk.Widget.Gtk_Widget_Record'Class)
is
begin
Gtk.Main.Main_Quit;
end Destroy_Event_Callback;
end App;
app.adb (using GTK Grid, see manual and GtkAda source)
with Gtk.Main; use Gtk.Main;
with Gtk.Window; use Gtk.Window;
with Gtk.Button; use Gtk.Button;
with Gtk.Widget; use Gtk.Widget;
with Gtk.Grid; use Gtk.Grid;
package body App is
procedure Destroy_Event_Callback
(Widget : access Gtk.Widget.Gtk_Widget_Record'Class);
---------
-- Run --
---------
procedure Run is
Win : Gtk_Window;
Button_1 : Gtk_Button;
Button_2 : Gtk_Button;
Button_3 : Gtk_Button;
Grid : Gtk_Grid;
begin
Gtk.Main.Init;
Gtk_New (Win);
Win.Set_Default_Size (Width => 380, Height => 502);
Win.On_Destroy (Call => Destroy_Event_Callback'Access);
Gtk_New (Button_1, "Button 1");
Gtk_New (Button_2, "Button 2");
Gtk_New (Button_3, "Button 3");
Gtk_New (Grid);
-- Stretch the grid to the size of the window.
Grid.Set_Hexpand (True);
Grid.Set_Vexpand (True);
-- Make all cells have the same width/height.
Grid.Set_Column_Homogeneous (True);
Grid.Set_Row_Homogeneous (True);
-- Insert the buttons into the grid.
--
-- Left: 0 1 2
-- Top: +------+------+------+
-- 0 | Btn1 | | |
-- +------+------+------+
-- 1 | | Btn3 | Btn2 |
-- +------+------+------+
--
Grid.Attach (Button_1, Left => 0, Top => 0);
Grid.Attach (Button_2, Left => 2, Top => 1);
Grid.Attach (Button_3, Left => 1, Top => 1);
Win.Add (Grid);
Win.Show_All;
Gtk.Main.Main;
end Run;
----------------------------
-- Destroy_Event_Callback --
----------------------------
procedure Destroy_Event_Callback
(Widget : access Gtk.Widget.Gtk_Widget_Record'Class)
is
begin
Gtk.Main.Main_Quit;
end Destroy_Event_Callback;
end App;
app.ads
package App is
procedure Run;
end App;
main.adb
with App;
procedure Main is
begin
App.Run;
end Main;