Discussion:
On_Button_Press_Event in Text_View
(too old to reply)
Gavin McCord
2024-08-13 11:37:09 UTC
Permalink
Using gtkada (gtk3), is it possible to use a custom handler to
deal with a button-press-event (or other events if necessary)
inside a widget such as a Text_View?

For example I create a Text_View with buffer. To process a
button-press within that view I have this code in my main
procedure:

The_View.On_Button_Press_Event (Press_CB'Access);
The_View.Set_Events (The_View.Get_Events or Button_Press_Mask);

The callback looks like this:

function Press_CB (Self : access Gtk_Widget_Record'Class;
Event : Gdk_Event_Button)
return Boolean is
begin
Put_Line ("Mouse click in text view");
return True;
end Press_CB;

So far, so good.

But I'd like to pass additional data to the callback,
without using global variables/records if it can be
avoided.

I have a custom handler used when I update the Text_Buffer:

Button_Callback.Connect
(Update_Button, "clicked", Update_Clicked'Access,
Buffer_To_Pass);

That works fine so I was imagining something similar might
be possible, but I've run through various permuations of
records and access types but not yet got a working callback.

Any help gratefully received (I can post the full code if
that's useful).

Kind regards,

Gavin McCord
Dmitry A. Kazakov
2024-08-13 20:29:59 UTC
Permalink
Post by Gavin McCord
Button_Callback.Connect
(Update_Button, "clicked", Update_Clicked'Access,
Buffer_To_Pass);
That works fine so I was imagining something similar might
be possible, but I've run through various permuations of
records and access types but not yet got a working callback.
Any help gratefully received (I can post the full code if
that's useful).
Something like this:

package Event_Handlers is
new Gtk.Handlers.User_Return_Callback
( GObject_Record,
Boolean,
User_Data_Type
);


function On_Button_Press
( Object : access GObject_Record'Class;
Event : Gdk_Event;
Data : User_Data_Type
) return Boolean;


View.Set_Events (View.Get_Events or Button_Press_Mask);
Event_Handlers.Connect
( View,
"button-press-event",
Event_Handlers.To_Marshaller (On_Button_Press'Access),
Data
);
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
Gavin McCord
2024-08-14 11:42:14 UTC
Permalink
Post by Dmitry A. Kazakov
Post by Gavin McCord
Button_Callback.Connect
(Update_Button, "clicked", Update_Clicked'Access,
Buffer_To_Pass);
That works fine so I was imagining something similar might be possible,
but I've run through various permuations of records and access types
but not yet got a working callback.
Any help gratefully received (I can post the full code if that's
useful).
package Event_Handlers is
new Gtk.Handlers.User_Return_Callback
( GObject_Record,
Boolean, User_Data_Type
);
function On_Button_Press
( Object : access GObject_Record'Class;
Event : Gdk_Event; Data : User_Data_Type
) return Boolean;
View.Set_Events (View.Get_Events or Button_Press_Mask);
Event_Handlers.Connect ( View,
"button-press-event",
Event_Handlers.To_Marshaller (On_Button_Press'Access),
Data
);
Thank you. That allows me to pass a record of the buffer.

There's only one other thing.

If I try to check the Event I get another error, such as

function On_Button_Press
[skipped lines]

if Event.The_Type = Gdk_2button_Press then
Put_Line ("double-click");
end if;

Attempting to compile that gives me

error: cannot reference discriminant of unchecked union


Gavin McCord
Dmitry A. Kazakov
2024-08-14 12:03:24 UTC
Permalink
Post by Gavin McCord
Post by Dmitry A. Kazakov
Post by Gavin McCord
Button_Callback.Connect
(Update_Button, "clicked", Update_Clicked'Access,
Buffer_To_Pass);
That works fine so I was imagining something similar might be possible,
but I've run through various permuations of records and access types
but not yet got a working callback.
Any help gratefully received (I can post the full code if that's
useful).
package Event_Handlers is
new Gtk.Handlers.User_Return_Callback
( GObject_Record,
Boolean, User_Data_Type
);
function On_Button_Press
( Object : access GObject_Record'Class;
Event : Gdk_Event; Data : User_Data_Type
) return Boolean;
View.Set_Events (View.Get_Events or Button_Press_Mask);
Event_Handlers.Connect ( View,
"button-press-event",
Event_Handlers.To_Marshaller (On_Button_Press'Access),
Data
);
Thank you. That allows me to pass a record of the buffer.
As a general advice. Usually you have a custom widget derived from
Gtk_Grid_Record servicing as the main window.

type Main_Window_Record is new Gtk_Grid_Record with record
Button : Gtk_Button;
Text_View : Gtk_Text_View;
Buffer : Gtk_Text_Buffer;
...
type Main_Window is access all Main_Window_Record'Class;

Main_Window you pass to all handlers, so that you always have a full
context in any of them.
Post by Gavin McCord
There's only one other thing.
If I try to check the Event I get another error, such as
function On_Button_Press
[skipped lines]
if Event.The_Type = Gdk_2button_Press then
Put_Line ("double-click");
end if;
Attempting to compile that gives me
error: cannot reference discriminant of unchecked union
case Get_Event_Type (Event) is
when Button_Press =>
...
when Gdk_2Button_Press | Gdk_3Button_Press =>
...
when Key_Press =>
case Get_Key_Val (Event) is
when GDK_Up | GDK_KP_Up =>
...
when GDK_Down | GDK_KP_Down =>
...
end case;
...
when others =>
...
end case;
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
Gavin McCord
2024-08-14 14:34:13 UTC
Permalink
Post by Dmitry A. Kazakov
Post by Gavin McCord
Post by Dmitry A. Kazakov
Post by Gavin McCord
Button_Callback.Connect
(Update_Button, "clicked", Update_Clicked'Access,
Buffer_To_Pass);
That works fine so I was imagining something similar might be possible,
but I've run through various permuations of records and access types
but not yet got a working callback.
Any help gratefully received (I can post the full code if that's
useful).
package Event_Handlers is
new Gtk.Handlers.User_Return_Callback
( GObject_Record,
Boolean, User_Data_Type
);
function On_Button_Press
( Object : access GObject_Record'Class;
Event : Gdk_Event; Data : User_Data_Type
) return Boolean;
View.Set_Events (View.Get_Events or Button_Press_Mask);
Event_Handlers.Connect ( View,
"button-press-event",
Event_Handlers.To_Marshaller (On_Button_Press'Access),
Data
);
Thank you. That allows me to pass a record of the buffer.
As a general advice. Usually you have a custom widget derived from
Gtk_Grid_Record servicing as the main window.
type Main_Window_Record is new Gtk_Grid_Record with record
Button : Gtk_Button;
Text_View : Gtk_Text_View;
Buffer : Gtk_Text_Buffer;
...
type Main_Window is access all Main_Window_Record'Class;
Main_Window you pass to all handlers, so that you always have a full
context in any of them.
Post by Gavin McCord
There's only one other thing.
If I try to check the Event I get another error, such as
function On_Button_Press [skipped lines]
if Event.The_Type = Gdk_2button_Press then
Put_Line ("double-click");
end if;
Attempting to compile that gives me
error: cannot reference discriminant of unchecked union
case Get_Event_Type (Event) is
when Button_Press =>
...
when Gdk_2Button_Press | Gdk_3Button_Press =>
...
when Key_Press =>
case Get_Key_Val (Event) is
when GDK_Up | GDK_KP_Up =>
...
when GDK_Down | GDK_KP_Down =>
...
end case;
...
when others =>
...
end case;
I've got it working now. Get_Event_Type (Event) is what I needed.

Thank you again for all your help.

Gavin

Loading...