[gtkada] GtkAda signal handlers interface proposal
Dmitry A. Kazakov
mailbox at dmitry-kazakov.de
Wed Apr 27 21:48:35 CEST 2016
The use case is a widget (or GObject) handling signals from other
widgets, usually its children. Presently this requires instantiation of
a Gtk.Handlers.* package because it requires passing the widget as a
signal parameter. This quite difficult to get right, especially the
Connect call.
The proposal is to have a method similar to already provided
parameterless handlers. As an example let's take Gkt.Button. It has
On_Clicked declared as a primitive operation.
procedure On_Clicked
(Self : not null access Gtk_Button_Record;
Call : Cb_Gtk_Button_Void;
After : Boolean := False);
Here the handler procedure is Cb_Gtk_Button_Void:
type Cb_Gtk_Button_Void is not null access
procedure (Self : access Gtk_Button_Record'Class);
Now the package Gtk.Button will also have an interface declaration:
type Clicked_Handler is interface;
procedure On_Clicked
( Emitter : not null access Gtk_Button_Record'Class;
-- Additional signal-specific parameters go here
Handler : not null access Clicked_Handler
) is abstract;
The Gtk_Button_Record type will get yet another primitive operation
procedure Handle_Clicked
( Self : not null access Gtk_Button_Record;
Handler : not null access Clicked_Handler'Class;
After : Boolean := False
);
Since GtkAda is generated, it should be relatively easy to do. The
implementation of Handle_Clicked is straightforward. Gtk.Button will
have an instance Gtk.Handlers.User_Callback with
type Clicked_Handler_Ptr is access all Clicked_Handler'Class;
From the procedure called on signal it will dispatch to On_Clicked.
The client code will look like this:
type My_Widget_Record is new Gtk.Grid.Gtk_Grid_Record
and Clicked_Handler with
record
Button1 : Gtk_Button;
Button2 : Gtk_Button;
...
end record;
overriding
procedure On_Clicked
( Emitter : not null access Gtk_Button_Record'Class;
Widget : not null access My_Widget_Record
);
Connecting signals in Initialize:
procedure Initialize
( Widget : not null access My_Widget_Record'Class
) is
begin
...
Widget.Button1.Handle_Clicked (Widget);
Widget.Button2.Handle_Clicked (Widget);
end Initialize;
The handler:
procedure On_Clicked
( Emitter : not null access Gtk_Button_Record'Class;
Widget : not null access My_Widget_Record
) is
begin
if Emitter = Widget.Button1 then
... -- This is from Button1
elsif Emitter = Widget.Button2 then
... -- This is from Button2
end if;
end On_Clicked;
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
-------------- next part --------------
An HTML attachment was scrubbed...
URL: </pipermail/gtkada/attachments/20160427/ce852c08/attachment.html>
More information about the gtkada
mailing list