Reputation: 5960
With GtkAda, I want to identify which radio button was toggled.
The best I have come up with is this not very pretty code, which iterates over all of the buttons to find which ones toggled:
procedure On_Pgm_Btn_Click
(Button : access Gtk.Widget.Gtk_Widget_Record'Class) is
Button_Array : array (Positive range <>) of Gtk_Radio_Button := (Pgm_Bit, Pgm_1, Pgm_2, Pgm_3, Pgm_4);
begin
for Index In Button_Array'range loop
if Button_Array(Index).Get_Active then
Selected_Program_Button := Button_Array(Index);
exit;
end if;
end loop;
end On_Pgm_Btn_Click;
This is called with this handler connection code:
Gtkada.Handlers.Widget_Callback.Connect (Pgm_Bit, "toggled", On_Pgm_Btn_Click'Unrestricted_Access);
Gtkada.Handlers.Widget_Callback.Connect (Pgm_1, "toggled", On_Pgm_Btn_Click'Unrestricted_Access);
Gtkada.Handlers.Widget_Callback.Connect (Pgm_2, "toggled", On_Pgm_Btn_Click'Unrestricted_Access);
Gtkada.Handlers.Widget_Callback.Connect (Pgm_3, "toggled", On_Pgm_Btn_Click'Unrestricted_Access);
Gtkada.Handlers.Widget_Callback.Connect (Pgm_4, "toggled", On_Pgm_Btn_Click'Unrestricted_Access);
I can see in the debugger that the value of the parameter Button has the same address as the button that generated the event, but I don't know the conventional way that this parameter is used. It's type is Gtk.Widget.Gtk_Widget_Record'Class, which suggests to me that I might be hacking the code if I did an unchecked conversion to a radio button;
How to I get the Radio Button from the parameter Button?
(Also, if there is a better way to get the state of a radio button group, I would like to know. I haven't been able to find any good examples.)
UPDATE with Solution
From the accepted answer below, I understand that a view conversion is implemented simply like a function call, as shown in the examples of ARM 4.6. The handler became this:
procedure On_Pgm_Btn_Click
(Button : access Gtk.Widget.Gtk_Widget_Record'Class) is
This_Button : Gtk_Radio_Button;
begin
This_Button := Gtk_Radio_Button(Button);
if This_Button.Get_Active then
Selected_Program_Button := This_Button;
end if;
end On_Pgm_Btn_Click;
The types involved are already defined in gtk-radio-button.ads as:
type Gtk_Radio_Button_Record is new Gtk_Check_Button_Record with null record;
type Gtk_Radio_Button is access all Gtk_Radio_Button_Record'Class;
and in gtk_widget.ads as:
type Gtk_Widget_Record is new GObject_Record with null record;
type Gtk_Widget is access all Gtk_Widget_Record'Class;
so there was no reason to redefine them or use the packages and sample code provided in the accepted answer.
The important line in the modified code is:
This_Button := Gtk_Radio_Button(Button);
which performs the view conversion.
Upvotes: 0
Views: 157
Reputation: 25491
This should be handled by a view conversion (ARM 4.6(5)), not an unchecked conversion.
I don’t have Gtk installed, so I wrote this (after some research at AdaCore’s documentation), which is I believe a self-contained equivalent, and which compiled successfully with GCC 5.1.0.
package View_Conversions is
type Widget_Record is tagged null record;
-- Represents Gtk.Widget.Gtk_Widget_Record
type Button_Record is new Widget_Record with null record;
type Button is access all Button_Record'Class;
-- Represents Gtk.Radio_Button.Gtk_Radio_Button
procedure On_Click (Widget : access Widget_Record'Class);
end View_Conversions;
with body
package body View_Conversions is
Selected : Button;
-- Records the selected button
procedure On_Click (Widget : access Widget_Record'Class) is
begin
Selected := Button (Widget);
-- If the Widget is a Button, save it; if not, raise CE
end On_Click;
end View_Conversions;
The advantage over unchecked conversion is that this is a checked conversion, and if the passed Widget
isn’t in fact a Button
you’ll get a Constraint_Error
at the point of the conversion.
Upvotes: 1