comp.lang.ada
 help / color / mirror / Atom feed
From: "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de>
Subject: GtkAda signal handlers interface proposal
Date: Wed, 27 Apr 2016 21:47:17 +0200
Date: 2016-04-27T21:47:17+02:00	[thread overview]
Message-ID: <nfr50b$mje$1@gioia.aioe.org> (raw)

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

                 reply	other threads:[~2016-04-27 19:47 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox